系列文章目录
创作不易 拒绝白嫖 点个赞呗
关注我,带你走进前端的世界!!!
是什么
- 将引用类型数据–>响应式数据 ==> 把值类型的数据包装编程响应式的引用类型的数据
object array map set weakmap weakset
- 函数
- reactive参数必须是对象(json/arr)
默认情况下修改对象, 界面不会自动更
如果想更新, 可以通过重新赋值的方式
- 本质: 将传入的数据包装成一个Proxy对象
用法
创建变量
案例1
import {reactive} from 'vue'; let state = reactive([1, 2, 3]); console.log(state) // Proxy {0: 1, 1: 3, 2: 5}
注意!!!
<p>{{state}}</p> <button @click="myFn">按钮</button> let obj = [1, 2, 3]; let state = reactive(obj) console.log(obj); // (3) [1, 2, 3] console.log(state); // Proxy {0: 1, 1: 2, 2: 3} // 页面显示是[1, 2, 3] function myFn() { state[3] = "zs"; console.log(obj); //(4) [1, 2, 3, "zs"] console.log(state); //Proxy {0: 1, 1: 2, 2: 3, 3: "zs"} // 点击按钮后 // 页面显示是[1, 2, 3, "zs"] // 由此-》根据下标修改数据可以触发页面的更新 // 且 state的修改对原数据的修改有影响 } function myFn() { obj[3] = "ls"; console.log(obj); //(4) [1, 2, 3, "ls"] console.log(state); //Proxy {0: 1, 1: 2, 2: 3, 3: "ls"} // 点击按钮后 // 页面显示是[1, 2, 3] // 且 原数据的修改对state的修改有影响 // 但是页面不会触发更新 } function myFn() { state = [4,5,6]; console.log(obj); //(3) [1, 2, 3] console.log(state); //(3) [4, 5, 6] // 点击按钮后 // 页面显示是[1, 2, 3] // 直接对state进行修改不会触发页面的更新,但是上面对下标进行修改可以触发页面更新 // 同时这里直接进行复制,导致state不再是proxy // 这里你可以使用 // Object.assign(state,[4,5,6]) // 这样也可以 触发页面的更新, // 这个方法在ajax请求之后进行赋值,很好用 }
案例2
import {reactive} from 'vue'; let state = reactive( { name: "zs", age: 19 }); // 这里不再赘述,效果和上面的Array一致
ref和reactive的区别
ref是把值类型添加一层包装,使其变成响应式的引用类型的值。
reactive 则是引用类型的值变成响应式的值。
所以两者的区别只是在于是否需要添加一层引用包装
本质上
ref(0) --> reactive( { value:0 })
相关API
isReactive
作用
检查对象是否是 reactive
创建的响应式 proxy。
其实内部是判断数据对象上是否包含
__v_isRef
属性并且其值为true
。
用法
let state = reactive( { name: "zs", age: 19 }); console.log(isReactive(state)) // true
readonly
作用
声明一个只读的proxy
与const的区别
const: 赋值保护, 不能给变量重新赋值
readonly: 属性保护, 不能给属性重新赋值
用法
<p>{{state.name}}</p> <p>{{state.attr.age}}</p> <button @click="myFn">按钮</button> let state = readonly({name:'syl', attr:{age:18}}); function myFn() { state.name = 'zs'; state.attr.age = 19; console.log(state); // proxy{name:'syl', attr:{age:18}} console.log(isReadonly(state)); // true // 变量无法更改 // 点击按钮后页面没有变化 }
isReadonly
作用
检查对象是否是由readonly创建的只读代理
shallowReactive
作用
创建一个响应式代理,该代理跟踪其自身 property 的响应性,但不执行嵌套对象的深度响应式转换 (暴露原始值)。
官网例子
当从合成函数返回响应式对象时,toRefs
非常有用,这样消费组件就可以在不丢失响应性的情况下对返回的对象进行分解/扩散:
<p>{{ state.a }}</p> <p>{{ state.attr.b }}</p> <p>{{ state.attr.c.d }}</p> <button @click="myFn">按钮</button> let state = shallowReactive({ a: "a", attr: { b: "b", c: { d: "d", }, }, }); function myFn() { state.attr.c.d='5' console.log(state.attr.c.d); //5 // 点击按钮后页面没有变化 } function myFn() { state.a='5' console.log(state.a); //5 // 点击按钮后页面变化 }
shallowReadonly
作用
用于创建一个只读的数据, 但是不是递归只读的
<p>{{state.name}}</p> <p>{{state.attr.age}}</p> <button @click="myFn">按钮</button> let state = shallowReadonly({name:'syl', attr:{age:18}}); function myFn() { state.attr.age = 19; console.log(state.attr.age) // 19 // 点击按钮页面没有变化 } function myFn() { state.name = 'ls'; console.log(state.name) // syl // 数据无法更改 // 点击按钮页面没有变化 }
toRaw
做用
从reactive 得到原始数据
用法
let obj = {name:'syl', age:18}; /* ref/reactive数据每次修改都会被追踪, 都会更新界面 但是当你不需要更新UI界面, 可以通过toRaw方法拿到它的原始数据, 对原始数据进行修改 这样就不会被追踪不会更新界面, */ let state = reactive(obj); let obj2 = toRaw(state); console.log(obj === obj2); // true function myFn() { obj2.name = 'zs'; console.log(obj2); // {name: "zs", age: 18} console.log(state); // {name: "zs", age: 18} } // 这个例子在上面出现过