vue3 简单上手

China☆狼群 提交于 2020-02-27 15:08:33

使用 vue-next-webpack-preview 项目作为测试环境

 

生命周期

setup函数的执行时机和composition-api 的变现并不一致, vue3中是最先执行的

下图为composition-api 效果

 

组件传参以及事件处理

子组件, 接受父组件传递的参数 使用该值作为初始值, 进行+1操作, 并将该事件抛出

<template>
  <div>
    <span>{{count}}</span>
    <button @click="add">add</button>
  </div>
</template>

<script>
  import {ref} from 'vue'
  export default {
    name: "Calc",
    setup(prop, ctx) {
      let count = ref(prop.initValue)
      const add = () => {
        count.value++
        ctx.emit('on-add', count.value)
      }
      return {
        add, count
      }
    }
  }
</script>

父组件

每次点击时, 就生成随机数, 并传入子组件, 接受子组件add事件, 打印参数

<template>
  <div>
    <Calc
      v-for="(i,index) in list"
      :key="index"
      :initValue="i"
      @on-add="onAdd"
    >
    </Calc>
    <button @click="push">push</button>
  </div>
</template>
<script>
  import {ref, reactive, computed, effect} from 'vue'
  import Calc from './Calc'
  ref(0)
  export default {
    components: {
      Calc
    },
    setup() {
      let list = ref([])
      const push = () => {
        let r = Math.random() * 100 | 0
        list.value.push(r)
      }
      const onAdd = val => {
        console.log('on-add', val)
      }
      return {
        push, list,onAdd
      }
    }
  }
</script>

 

用reactive改写子组件, ref更适合用于基础数据类型, reactive适合使用对象的时候, 并且reactive只能传入对象, 传入0这种基础类型的数据会有警告, 返回值也是基础类型无响应式功能, ref可以传入对象和基础数据类型, 只是在需要使用value访问, 在模板中vue会自动拆箱, 所以可以省略

<template>
  <div>
    <!--    <span>{{count}}</span>-->
    <span>{{state.count}}</span>
    <button @click="add">add</button>
  </div>
</template>
<script>
  import {ref, reactive} from 'vue'

  export default {
    name: "Calc",
    setup(prop, ctx) {
      // let count = ref(prop.initValue)
      let state = reactive({count: prop.initValue})
      const add = () => {
        // count.value++
        state.count++
        // ctx.emit('on-add', count.value)
        ctx.emit('on-add', state.count)
      }
      return {
        // 不能使用展开符, 会失去响应式
        // add, ...state
        add, state
      }
    }
  }
</script>

或者使用toRefs 展开,直接展开会失去响应式, 需要配合toRefs

<span>{{count}}</span>
     

return {
        // 不能使用展开符, 会失去响应式
        // add, ...state
        add, ...toRefs(state)
      }

 

ref和reactive

直接展开reactive对象会失去响应式, 可以使用toRefs之后再展开, 访问时注意使用value

let {ref, toRefs, reactive, isRef, isReactive} = require('vue')

let count = ref(0)
console.log(count.value) // 0
console.log(count, count.value) // { _isRef: true, value: [Getter/Setter] } 0

let state = reactive(
  {count}
)
// true false false true
console.log(isRef(count), isRef(state), isReactive(count), isReactive(state))

let count2 = ref(10)
state.count = count2
state.count++

// 11 0 11
console.log(state.count, count.value, count2.value)


// 转化为普通对象, 但是每个属性都是一个ref
let stateRef = {...toRefs(state)}
let stateSimple = {...state}
// 11 11 11
console.log(state.count, stateRef.count.value, stateSimple.count)
state.count = 111
// 111 111 11, 直接展开会失去响应式
console.log(state.count, stateRef.count.value, stateSimple.count)

computed

可以创建只读或者可读可写的计算属性

let {ref, computed} = require('vue')
let count = ref(0)

let double = computed(() => count.value * 2)

let triple = computed({
  get() {
    return count.value * 3
  },
  set(val) {
    count.value = (val / 3) | 0
  }
})
// 0 0 0
console.log(count.value, double.value, triple.value)
count.value += 10

// 10 20 30
console.log(count.value, double.value, triple.value)

triple.value = 13
// 4 8 12
console.log(count.value, double.value, triple.value)

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!