其他分享
首页 > 其他分享> > Vue3 -- ref & reactive & toRefs & toRef响应式引用

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

作者:互联网

文章目录

前言

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

响应式引用原理

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

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

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

 		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

		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

reactive

toRefs

toRef

readonly

结语

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

如有问题欢迎各位指正

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