系列文章目錄
創作不易 拒絕白嫖 點個贊呗
關注我,帶你走進前端的世界!!!
是什麼
- 将引用類型資料–>響應式資料 ==> 把值類型的資料包裝程式設計響應式的引用類型的資料
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}
}
// 這個例子在上面出現過