vue3.0 组合式API

setup函数是组合API的入口函数

ref函数

  • ref和reactive一样,用来实现响应式数据的方法

  • 由于reactive必须传递一个对象,所以提供了ref方法,实现对简单值的监听

  • 本质还是reactive,系统会自动将值转换 ref(xx) -> reactive({value:xx})

  • 在Vue中使用ref的值不需要通过value获取 在js中使用ref的值必须通过value获取

<template>
  <p>{{count}}</p>
  <button @click="myFn">按钮</button>
</template>
​
<script>
  import {ref} from 'vue'
  export default {
    name: "vue3.0",
    //setup函数是组合API的入口函数
    setup() {
      //ref函数只能处理简单类型的变化,不能监听复杂类型的变化(对象/数组)
      let count = ref(0);
      //在组合API中,如果想定义方法,不用定义到methods中,直接定义即可
      function myFn() {
        alert(123)
        count.value += 1
      }
      //在组合API中定义的变量/方法,要想外界使用,必须通过return{xx, xx}暴露出去
      return {count, myFn}
    }
  }
</script>

reactive函数

  • reactive是Vue3中提供的实现响应式数据的方法 Vue2中是通过defineProperty实现 Vue3中是通过ES6的Proxy实现

  • 参数必须是对象(json/arr)

  • 如果传递其他对象 默认情况下修改对象,界面不会自动更新,可通过重新赋值的方式更新

<template>
  <div>
    <form>
      <input type="text" v-model="state2.stu.id">
      <input type="text" v-model="state2.stu.name">
      <input type="text" v-model="state2.stu.age">
      <input type="button" @click="addStu">
    </form>
    <ul>
      <li v-for="(stu, index) in state.stus"
          :key="stu.id"
          @click="remStu(index)">
        {{stu.name}} - {{stu.age}}
      </li>
    </ul>
  </div>
</template>
​
<script>
  import {reactive} from "vue";
  export default {
    name: "app1",
    setup() {
      let {state, remStu} = userRemoveStudent();
      let {state2, addStu} = userAddStudent(state);
      return {state, remStu, state2, addStu}
    }
  }
  function userRemoveStudent() {
    let state = reactive({
      stus: [
        {id:1, name:'zs', age:10},
        {id:2, name:'ls', age:20},
        {id:3, name:'ww', age:30},
      ]
    });
    function remStu(index) {
      state.stus = state.stus.filter((stu, idx) => idx !== index)
    }
    return {state, remStu}
  }
​
  function userAddStudent(state) {
    let state2 = reactive({
      stu: {
        id:'',
        name:'',
        age:''
      }
    })
    function addStu(e) {
      e.preventDefault()
      const stu = Object.assign({}, state2.stu);
      state.stus.push(stu)
      state2.stu.id = ''
      state2.stu.name = ''
      state2.stu.age = ''
    }
    return {state2, addStu}
  }
</script>
  • 可将函数封装到js文件,通过import引用

  • Composition API 可和 Option API混合使用()

  • setup执行时机,beforecreate钩子之前完成的 还未执行Created生命周期方法,在setup中无法使用data和methods

  • setup中this指向undefined

  • setup函数只能是同步的

判断当前数据是否是ref类型

通过当前数据的__v_ref来判断,如果有这个私有属性,并取值为true,那么就代表是一个ref类型数据

递归监听

  1. 默认情况下,无论通过ref还是reactive都是递归监听

  2. 如果数据量比较大,非常消耗性能

非递归监听

一般情况下使用ref和reactive即可,只有在需要监听的数据量比较大时,才使用shallowReactive/shallowRef

  • shallowReactive 此方法Vue监听的是第一层的变化

  • shallowRef 此方法Vue监听的是.value的变化,因为底层调用shallowReactive,value才是第一层

  • triggerRef主动触发界面更新 Vue3只提供了triggerRef,没有提供triggerReactive

toRaw

<script>
  import {reactive, toRaw, ref} from 'vue'
  export default {
    name: "app2",
    setup() {
      /*
      ref/reactive数据
      每次修改都会被追踪,都会更新UI界面,但是这样是非常消耗性能
      所以如果有一些操作不需要追踪,不需要更新UI界面,就可以通过toRaw方法拿到它的原始数据
      对原始数据进行修改,这样就不会被追踪,不会更新UI界面,性能就好了
      * */
      let obj = {name: 'zs', age:18}
      let state = reactive(obj)
      // let state = ref(obj)
      //如果想通过toRaw拿到ref类型的原始数据
      //那么就必须明确告诉toRaw方法,要获取的是.value的值
      let obj2 = toRaw(state)
      // let obj2 = toRaw(state.value)
​
​
      //state和obj的关系
      //引用关系,state的本质是Proxy对象中引用了obj
​
      function myFn() {
        //如果直接修改obj,无法触发界面更新
        //只有通过包装之后的对象来修改,才会触发界面更新
        obj.name = 'ls';
        console.log(obj);//{name: "ls", age: 18}
        console.log(obj2);//{name: "ls", age: 18}
        console.log(state);//{name: "ls", age: 18}
      }
    }
  }
</script>

markRaw

让数据永远不被追踪,不变响应数据

let obj = {name: 'zs', age:18}
obj = markRaw(obj)

toRef

  • 如果利用ref将某一个对象中的属性变成响应式数据,我们修改响应式的数据是不会影响到原始数据的

  • 如果利用toRef将某一个对象中的属性变成响应式数据,我们修改响应式的数据会影响到原始数据的 但是如果响应式的数据是通过toRef创建的,那么修改了数据并不会触发UI界面的更新

toRefs

利用toRefs将某一个对象中的多个属性变成响应式数据,我们修改响应式的数据会影响到原始数据的 但是如果响应式的数据是通过toRefs创建的,那么修改了数据并不会触发UI界面的更新

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值