美文网首页web前端高级-vueVue
【vue3】一文读懂ref与reactive

【vue3】一文读懂ref与reactive

作者: 老鼠AI大米_Java全栈 | 来源:发表于2021-03-24 16:36 被阅读0次

    开发中如何选择使用ref和reactive呢?有时真不知道怎么选择

    Ref

    ref数据响应式监听。ref 函数传入一个值作为参数,一般传入基本数据类型,返回一个基于该值的响应式Ref对象,该对象中的值一旦被改变和访问,都会被跟踪到,就像我们改写后的示例代码一样,通过修改 count.value 的值,可以触发模板的重新渲染,显示最新的值

    <template>
      
      <h1>{{name}}</h1>
      <h1>{{age}}</h1>
      <button @click="sayName">测试</button>
    </template>
    
    <script lang="ts">
    import {ref,computed} from 'vue' 
    
    export default {
      name: 'App',
      setup(){
        const name = ref('daxiong')
        const birthYear = ref(2000)
        const now = ref(2020)
        const age = computed(()=>{
          return now.value - birthYear.value
        })
        const sayName = () =>{
          name.value = 'I am ' + name.value
        }
        return {
          name,
          sayName,
          age
        }
      }
    }
    </script>
    

    ref 的作用就是将一个原始数据类型(primitive data type)转换成一个带有响应式特性

    的数据类型,原始数据类型共有7个,分别是:

    • String
    • Number
    • BigInt
    • Boolean
    • Symbol
    • Null
    • Undefined

    reactive

    reactive是用来定义更加复杂的数据类型,但是定义后里面的变量取出来就不在是响应式Ref对象数据了
    所以需要用toRefs函数转化为响应式数据对象

    <template>
      <div>
        <h1>{{ name }}</h1>
        <h1>{{ age }}</h1>
        <button @click="sayName">测试</button>
      </div>
    </template>
    
    <script lang="ts">
    import { computed, reactive,toRefs } from "vue";
    
    interface DataProps {
      name: string;
      now: number;
      birthYear: number;
      age: number;
      sayName: () => void;
    }
    
    export default {
      name: "App",
      setup() {
        const data: DataProps = reactive({
          name: "daxiong",
          birthYear: 2000,
          now: 2020,
          sayName: () => {
            console.log(data.name);
            
            data.name = "I am " + data.name;
            console.log(data.name);
          },
          age: computed(() => {
            return data.now - data.birthYear;
          }),
        });
    
        return {
          ...refData,
        };
      },
    };
    </script>
    

    Bug

    不出意外,你会发现这个简化后的代码竟然无效,不管怎么点按钮,页面并没有发生变化!事实上,这样写没有效果的原因就在于一个响应型对象(reactive object) 一旦被销毁或展开(如上面代码那样),其响应式特性(reactivity)就会丢失。

    toRefs的作用

    为了解决上述问题,Vue3又提供了一个新的API:toRefs,它可以将一个响应型对象(reactive object) 转化为普通对象(plain object),同时又把该对象中的每一个属性转化成对应的响应式属性(ref)。说白了就是放弃该对象(Object)本身的响应式特性(reactivity),转而给对象里的属性赋予响应式特性(reactivity)。故而我们可以将代`码修复成下面这样:

    <template>
      <div>
        <h1>{{ name }}</h1>
        <h1>{{ age }}</h1>
        <button @click="sayName">测试</button>
      </div>
    </template>
    
    <script lang="ts">
    import { computed, reactive,toRefs } from "vue";
    
    interface DataProps {
      name: string;
      now: number;
      birthYear: number;
      age: number;
      sayName: () => void;
    }
    
    export default {
      name: "App",
      setup() {
        const data: DataProps = reactive({
          name: "daxiong",
          birthYear: 2000,
          now: 2020,
          sayName: () => {
            console.log(data.name);
            
            data.name = "I am " + data.name;
            console.log(data.name);
          },
          age: computed(() => {
            return data.now - data.birthYear;
          }),
        });
    
        const refData = toRefs(data)
        return {
          ...refData,
        };
      },
    };
    </script>
    

    总结

    refreactive 一个针对原始数据类型,而另一个用于对象,这两个API都是为了给JavaScript普通的数据类型赋予响应式特性(reactivity)。根据Vue3官方文档,这两者的主要区别在于每个人写JavaScript时的风格不同,有人喜欢用原始数据类型(primitives),把变量单独拎出来写;而有人喜欢用对象(Object),把变量当作对象里的属性,都写在一个对象里头,比如:

    // style 1: separate variables
    let x = 0
    let y = 0
    
    function updatePosition(e) {
      x = e.pageX
      y = e.pageY
    }
    
    // --- compared to ---
    
    // style 2: single object
    const pos = {
      x: 0,
      y: 0
    }
    
    function updatePosition(e) {
      pos.x = e.pageX
      pos.y = e.pageY
    }
    

    学习交流群:211042548

    相关文章

      网友评论

        本文标题:【vue3】一文读懂ref与reactive

        本文链接:https://www.haomeiwen.com/subject/mfehhltx.html