vue3 setup 使用 和 ref,reactive 响应式引用的用法和原理
https://v3.cn.vuejs.org/guide/composition-api-setup.html#setup
setup在created实例初始化之前。 所以呢 在里面不能用 this啊,他肯定找不到的。
直接返回的数据,全局也是拿的到的。
使用 setup
函数时,它将接收两个参数:
props
context
让我们更深入地研究如何使用每个参数.
ref,reactive 响应式引用的用法和原理
如果在setup 返回的数据改变后,是不会响应式的,所以用到ref:
响应式原理:通过 proxy 对数据进行封装,当数据变化时,触发模版等内容的更新
那么 ref 处理基础类型的数据,记住啊 是基础类型,什么什么对象、数组不是用ref,使用ref的值的话,是用ref.value, 但是如果在html代码中使用,不用带.value,因为VUE 自动识别。

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>study</title> <script src="https://unpkg.com/vue@next"></script> </head> <body> <div id="root"></div> </body> <script> const app = Vue.createApp({ template: ` <div>{{name}}</div> `, setup(props, context) { // 引入ref const { ref } = Vue; //proxy, 标识咸瑜 为响应式数据, '咸瑜'变成 proxy({value: '咸瑜'}) 这样的一个响应式引用 let name = ref('咸瑜'); setTimeout(() => { // 注意这里使用是用了 name.value ,因为使用了 ref name.value = '大咸鱼(已改变)' }, 2000) return { name } } }); const vm = app.mount('#root'); </script> </html>
自己看列子,例子中2S后 “咸鱼” 变为 “大咸鱼” ,其中用到了ref,如果不用 ,那么你就别想响应式。 原理就是 proxy ,底层自己会操作。
reactive :
和ref的一样,使用详细看下面代码怎么用的即可: 下面数组和对象都定义了。

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>study</title> <script src="https://unpkg.com/vue@next"></script> </head> <body> <div id="root"></div> </body> <script> // reactive 处理非基础类型的数据 const app = Vue.createApp({ template: ` <div>{{nameObj.name}}</div> `, setup(props, context) { // 引入 reactive const { reactive, } = Vue; // 定义nameObj 是个对象。 const nameObj = reactive({ name: '咸瑜' }); // 2S 后改变对象的值。 setTimeout(() => { nameObj.name = '菜鸟小咸瑜' }, 2000) return{ nameObj } } }); const vm = app.mount('#root'); </script> </html>

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>study</title> <script src="https://unpkg.com/vue@next"></script> </head> <body> <div id="root"></div> </body> <script> // reactive 处理非基础类型的数据 const app = Vue.createApp({ template: ` <div>{{numArr[0]}}</div> `, setup(props, context) { // 引入 reactive const { reactive, } = Vue; // 定义numArr 是个数组。 数组也是一样的。 const numArr = reactive([123]); // 2S 后改变数组元素[0] 为 456 setTimeout(() => { numArr[0] = 456 }, 2000) return{ numArr } } }); const vm = app.mount('#root'); </script> </html>
新的玩意,心得开始(开死)....
除了上面2个,如果你想让 对象或数组是只读的话,那么vue 还有个玩意叫 readonly :

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>study</title> <script src="https://unpkg.com/vue@next"></script> </head> <body> <div id="root"></div> </body> <script> // readonly 标识为只读的, const app = Vue.createApp({ template: ` <div>{{copyArr[0]}}</div> `, setup(props, context) { // 引入 const { reactive, readonly } = Vue; const numArr = reactive([123]); // 把它标识为只读的,他会返回一份不可以被修改的numArr【copyArr】 const copyArr = readonly(numArr) setTimeout(() => { // 修改之前的是完全没问题的。。。 numArr[0] = 456 // 修改copyArr的第一个元素为456 【会报警】 copyArr[0] = 456 }, 2000) // 返回 return { copyArr } } }); const vm = app.mount('#root'); </script> </html>
这个就是修改copyArr[0] = 456 时候的警告了。
如果你有这样的需求:解构然后返回,但你解构后的变量肯定也不是响应式的,那你就可以用 toRefs了:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>study</title> <script src="https://unpkg.com/vue@next"></script> </head> <body> <div id="root"></div> </body> <script> // 注意看 这里直接调用name const app = Vue.createApp({ template: ` <div>{{name}}</div> `, setup(props, context) { // 引入 const { reactive, readonly, toRefs } = Vue; const personObj = reactive({ name:"咸鱼", age:18 }) const {name} = toRefs(personObj); // 返回 return { name } } }); const vm = app.mount('#root'); </script> </html>
其实他的原理就是:
把 personOBJ 转变成:(name : proxy({ value : "咸鱼" }))
所以呢,这里直接返回name,也是可以直接渲染【响应式】。
本文来自博客园,作者:咸瑜,转载请注明原文链接:https://www.cnblogs.com/bi-hu/p/16098634.html