reactive類型數據代碼
<template>
<div>
<p>{{state}}</p>
<button @click="myFn">按鈕</button>
</div>
</template>
<script>
import {reactive} from 'vue';
export default {
name: 'App',
setup() {
let obj = {name:'lnj', age:18};
let state = reactive(obj);
// console.log(obj === state); // false // state和obj的關系:
// 引用關系, state的本質是一個Proxy對象, 在這個Proxy對象中引用了obj(同一個內存地址)
function myFn() {
// 如果直接修改obj, 那么是無法觸發界面更新的 // 只有通過包裝之后的對象來修改state, 才會觸發界面的更新
obj.name='zs'
console.log(obj) // {name: "zs", age: 18}
state.name = 'zs';
console.log(state); // {name: "zs", age: 18}
}
return {state, myFn}
}
}
</script>
<style>
</style>
我們點擊按鈕后,發現obj修改name的屬性的數據成功了,但是頁面視圖並沒有更新,不是響應式的。通過封裝了state的對象,修改name屬性,會更改頁面視圖更新
一句話,如果我們對 reactive 的源數據進行改變的時候,是不會引起界面的改變,也就不會產生有關的計算了。
如果我們有修改 obj的內容,又不想觸發界面改變的時候,我們就可以修改 obj
可問題是,如果我沒創建 obj 呢?又或者 obj 在另一個文件里創建了,怎么辦。
toRaw
reactive的toRaw
<template>
<div>
<p>{{state}}</p>
<button @click="myFn">按鈕</button>
</div>
</template>
<script>
/*
1.toRaw
從Reactive 或 Ref中得到原始數據
2.toRaw作用
做一些不想被監聽的事情(提升性能)
* */
import {reactive, toRaw} from 'vue';
export default {
name: 'App',
setup() {
/*
ref/reactive數據類型的特點:
每次修改都會被追蹤, 都會更新UI界面, 但是這樣其實是非常消耗性能的
所以如果我們有一些操作不需要追蹤, 不需要更新UI界面, 那么這個時候,
我們就可以通過toRaw方法拿到它的原始數據, 對原始數據進行修改 這樣就不會被追蹤, 這樣就不會更新UI界面, 這樣性能就好了
* */
let state = reactive(
{name:'lnj', age:18}
);
// 獲取state的源數據
let obj2 = toRaw(state); // console.log({name:'lnj', age:18} === obj2); // true
// console.log({name:'lnj', age:18} === state); // false
function myFn() {
// 獲取的源數據更改,不會觸發頁面更新
obj2.name = 'zs';
console.log(obj2); // {name: "zs", age: 18}
// state.name = 'zs';
// console.log(state);// {name: "zs", age: 18}
}
return {state, myFn}
}
}
</script>
<style>
</style>
ref的toRow
<template>
<div>
<p>{{state}}</p>
<button @click="myFn">按鈕</button>
</div>
</template>
<script>
import { toRaw, ref} from 'vue';
export default {
name: 'App',
setup() {
/*
1.ref本質: reactive
ref(obj) -> reactive({value: obj})
* */
let state = ref({name:'lnj', age:18});
// 注意點: 如果想通過toRaw拿到ref類型的原始數據(創建時傳入的那個數據)
// 那么就必須明確的告訴toRaw方法, 要獲取的是.value的值
// 因為經過Vue處理之后, .value中保存的才是當初創建時傳入的那個原始數據
// let obj2 = toRaw(state);
let obj2 = toRaw(state.value);
console.log(state);
console.log(obj2);
function myFn() {
// 獲取的源數據更改,不會觸發頁面更新
obj2.name = 'zs';
console.log(obj2); // {name: "zs", age: 18}
// state.name = 'zs';
// console.log(state);// {name: "zs", age: 18}
}
return {state, myFn}
}
}
</script>
<style>
</style>
markRow
<template>
<div>
<p>{{state}}</p>
<button @click="myFn">按鈕</button>
</div>
</template>
<script>
/*
1.markRaw
將數據標記為永遠不能追蹤的數據 一般在編寫自己的第三方庫時使用
* */
import {reactive, markRaw} from 'vue';
export default {
name: 'App',
setup() {
let obj = {name: 'lnj', age: 18};
// 不能追蹤,監聽,作為響應式的數據
obj = markRaw(obj);
let state = reactive(obj);
function myFn() {
// 數據更改了,但是頁面ui還是沒有發生改變
state.name = 'zs';
}
return {state, myFn}
}
}
</script>
<style>
</style>
