ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Vue3 -- ref & reactive & toRefs & toRef响应式引用

2021-07-11 22:32:58  阅读:872  来源: 互联网

标签:张三 obj name -- toRefs toRef reactive proxy const


文章目录

前言

上一节我们知道了setup函数的数据不具备响应式,这一节我们来解决这一问题。

响应式引用原理

通过 proxy 对数据进行封装,当数据变化时,触发模板内容更新。

ref

  • 作用:接受一个内部值并返回响应式对象;
  • 处理:一般用于处理基础数据类型;
  • 引用:ref需要从Vue中引入才能使用;
  • 使用:通过value属性获取,使用数据时不需要使用value;
 			// 模板中使用时,vue底层自动调用 .value
            template:`<div>{{name}}</div>`,
            setup(){
                //引入ref
                const { ref } = Vue;
                // 响应式引用,proxy 将 '张三' 变成 proxy({ value: '张三'})
                let name = ref('张三');
                // 两秒后修改 name
                setTimeout(() => {
                    // 修改 name 使用 name.value
                    name.value = '李四';
                }, 2000);
                return{ name }
            }

页面渲染成功渲染出 张三

两秒后更新数据,重新渲染出 李四

reactive

  • 作用:接受一个内部值并返回响应式对象;
  • 引用:从Vue中引入才能使用;
  • 处理:一般用于处理非基础数据类型;
  • 解构:数据解构之后的数据不具备响应式;

数据未解构时

			template:`<div>{{obj.name}}</div>`,
            setup(){
                //引入reactive
                const { reactive } = Vue;
                // 响应式引用,proxy 将 {name: '张三'} 变成 proxy({name: '张三'})
                let obj = reactive({name: '张三'});
                // 两秒后修改 obj.name
                setTimeout(() => {
                    obj.name = '李四';
                }, 2000);
                return{ obj }
            }

页面渲染成功渲染出 张三

两秒后更新数据,重新渲染出 李四

尝试对数据进行解构

		template:`<div>{{name}}</div>`,
            setup(){
                //引入reactive
                const { reactive } = Vue;
                // 响应式引用,proxy 将 {name: '张三'} 变成 proxy({name: '张三'})
                let obj = reactive({name: '张三'});
                // 两秒后修改 obj.name
                setTimeout(() => {
                    obj.name = '李四';
                }, 2000);
                const { name } = obj;
                return{ name }
            }

页面渲染成功渲染出 张三

两秒后更新数据,页面没有变化

toRefs

  • 作用:使解构后的数据重新获得响应式;
  • 引用:从Vue中引入才能使用;
  • 封装:封装数据中本身不存在某个数据时,会返回不具备响应式的undefined;

toRefs响应式引用

   		template:`<div>{{name}}</div>`,
            setup(){
                //引入reactive
                const { reactive, toRefs } = Vue;
                // 响应式引用,proxy 将 {name: '张三'} 变成 proxy({name: '张三'})
                let obj = reactive({name: '张三'});
                // 两秒后修改 obj.name
                setTimeout(() => {
                    obj.name = '李四';
                }, 2000);
                // 通过toRefs包装后会变为proxy({name:proxy({value:'name'})})
                const { name } = toRefs(obj);
                return{ name }
            }

页面渲染成功渲染出 张三

两秒后更新数据,重新渲染出 李四

toRefs封装不存在数据

 		template:`<div>{{age}}</div>`,
            setup(){
                //引入reactive
                const { reactive, toRefs } = Vue;
                // 响应式引用,proxy 将 {name: '张三'} 变成 proxy({name: '张三'})
                let obj = reactive({name: '张三'});
                // 通过toRefs包装后会变为proxy({name:proxy({value:'name'})})
                const { age } = toRefs(obj);
                // 两秒后修改 age.value
                setTimeout(() => {
                    age.value = '18';
                }, 2000);
                return{ age }
            }

控制台报错
在这里插入图片描述

toRef

  • 作用:封装数据中不存在数据时,不会报错,会返回具备响应式的值;
  • 使用:toRef方法不需要解构;
  • 参数:两个参数,一个总数据,一个获取的数据。
 		template:`<div>{{age}}</div>`,
            setup(){
                //引入reactive
                const { reactive, toRef } = Vue;
                // 响应式引用,proxy 将 {name: '张三'} 变成 proxy({name: '张三'})
                let obj = reactive({name: '张三'});

                const  age  = toRef(obj, 'age');
                // 两秒后修改 age.value
                setTimeout(() => {
                    age.value = '18';
                }, 2000);
                return{ age }
            }

页面两秒后渲染出:18
在这里插入图片描述

readonly

  • 作用:取得一个对象或ref并返回一个只读代理;
  • 引用:从Vue中引入才能使用;
		template:`
            <div>{{obj.name}}</div>
            <div>{{copyObj.name}}</div>
            `,
            setup(){
                //引入reactive
                const { reactive, readonly } = Vue;
                // 响应式引用,proxy 将 {name: '张三'} 变成 proxy({name: '张三'})
                let obj = reactive({name: '张三'});
                let copyObj = readonly({name: '张三'});
                // 两秒后修改 obj.name
                setTimeout(() => {
                    obj.name = '李四';
                    copyObj.name = '李四';
                }, 2000);
                return{ obj, copyObj }
            }

页面效果
在这里插入图片描述
两秒后页面效果,同时控制台给出警告。
在这里插入图片描述
在这里插入图片描述

完整代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue3 -- 响应式引用</title>
    <!-- 使用CDN引入Vue -->
    <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
    <div id="root"></div>
    <script>
        const app = Vue.createApp({

            // ref
            // 模板中使用时,vue底层自动调用 .value
            // template:`<div>{{name}}</div>`,
            // setup(){
            //     //引入ref
            //     const { ref } = Vue;
            //     // 响应式引用,proxy 将 '张三' 变成 proxy({ value: '张三'})
            //     let name = ref('张三');
            //     // 两秒后修改 name
            //     setTimeout(() => {
            //         // 修改 name 使用 name.value
            //         name.value = '李四';
            //     }, 2000);
            //     return{ name }
            // }

            // reactive
            // 未解构
            // template:`<div>{{obj.name}}</div>`,
            // setup(){
            //     //引入reactive
            //     const { reactive } = Vue;
            //     // 响应式引用,proxy 将 {name: '张三'} 变成 proxy({name: '张三'})
            //     let obj = reactive({name: '张三'});
            //     // 两秒后修改 obj.name
            //     setTimeout(() => {
            //         obj.name = '李四';
            //     }, 2000);
            //     return{ obj }
            // }

            // 解构后
            // template:`<div>{{name}}</div>`,
            // setup(){
            //     //引入reactive
            //     const { reactive } = Vue;
            //     // 响应式引用,proxy 将 {name: '张三'} 变成 proxy({name: '张三'})
            //     let obj = reactive({name: '张三'});
            //     // 两秒后修改 obj.name
            //     setTimeout(() => {
            //         obj.name = '李四';
            //     }, 2000);
            //     const { name } = obj;
            //     return{ name }
            // }

            // // toRefs
            // template:`<div>{{name}}</div>`,
            // setup(){
            //     //引入reactive
            //     const { reactive, toRefs } = Vue;
            //     // 响应式引用,proxy 将 {name: '张三'} 变成 proxy({name: '张三'})
            //     let obj = reactive({name: '张三'});
            //     // 两秒后修改 obj.name
            //     setTimeout(() => {
            //         obj.name = '李四';
            //     }, 2000);
            //     // 通过toRefs包装后会变为proxy({name:proxy({value:'name'})})
            //     const { name } = toRefs(obj);
            //     return{ name }
            // }

            //toRefs封装不存在数据
            // template:`<div>{{age}}</div>`,
            // setup(){
            //     //引入reactive
            //     const { reactive, toRefs } = Vue;
            //     // 响应式引用,proxy 将 {name: '张三'} 变成 proxy({name: '张三'})
            //     let obj = reactive({name: '张三'});

            //     const  { age } = toRefs(obj);
            //     // 两秒后修改 age.value
            //     setTimeout(() => {
            //         age.value = '18';
            //     }, 2000);
            //     return{ age }
            // }

            // //toRef
            // template:`<div>{{age}}</div>`,
            // setup(){
            //     //引入reactive
            //     const { reactive, toRef } = Vue;
            //     // 响应式引用,proxy 将 {name: '张三'} 变成 proxy({name: '张三'})
            //     let obj = reactive({name: '张三'});

            //     const  age  = toRef(obj, 'age');
            //     // 两秒后修改 age.value
            //     setTimeout(() => {
            //         age.value = '18';
            //     }, 2000);
            //     return{ age }
            // }

            // readonly
            template:`
            <div>{{obj.name}}</div>
            <div>{{copyObj.name}}</div>
            `,
            setup(){
                //引入reactive
                const { reactive, readonly } = Vue;
                // 响应式引用,proxy 将 {name: '张三'} 变成 proxy({name: '张三'})
                let obj = reactive({name: '张三'});
                let copyObj = readonly({name: '张三'});
                // 两秒后修改 obj.name
                setTimeout(() => {
                    obj.name = '李四';
                    copyObj.name = '李四';
                }, 2000);
                return{ obj, copyObj }
            }
        });        
        const vm = app.mount('#root');
    </script>
</body>
</html>

总结

ref

  • 作用:接受一个基础数据类型值并返回响应式对象
  • 引用:ref需要从Vue中引入才能使用;
  • 使用:通过value属性获取,使用数据时不需要使用value

reactive

  • 作用:接受一个非基础数据类型值并返回响应式对象
  • 引用:从Vue中引入才能使用;
  • 解构:数据解构之后的数据不具备响应式

toRefs

  • 作用:使reactive解构后的数据重新获得响应式
  • 引用:从Vue中引入才能使用;
  • 封装:封装数据中本身不存在某个数据时,会返回不具备响应式的undefined;

toRef

  • 作用:封装数据中不存在数据时,不会报错,会返回具备响应式的值
  • 使用:toRef方法不需要解构
  • 参数:两个参数,一个总数据,一个获取的数据。

readonly

  • 作用:取得一个对象或ref并返回一个只读代理;
  • 引用:从Vue中引入才能使用;

结语

本小节到此结束,谢谢大家的观看!

如有问题欢迎各位指正

标签:张三,obj,name,--,toRefs,toRef,reactive,proxy,const
来源: https://blog.csdn.net/m0_47901007/article/details/118656860

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有