尚矽谷影片教程
shallowRef shallowReactive
- 淺層次的響應式資料(僅第一層)
- shallowRef :只能整體修改 person.value可以修改,但是person.value.name無法修改
- shallowReactive :只能修改物件的第一層資料 car.brand可以修改,但是car.options.color無法修改
- 主要用處在於:如果資料量非常大的時候,所有資料都要保持響應式會效能不好
<template>
<h3>{{ person }}</h3>
<button @click="changeName">changeName</button>
<button @click="changePerson">changePerson</button>
<h3>{{ car }}</h3>
<button @click="changeBrand">changeBrand</button>
<button @click="changeColor">changeColor</button>
</template>
<script setup name="App" lang="ts">
import { ref,reactive } from 'vue';
import { shallowRef,shallowReactive } from 'vue';
let person = shallowRef({
name:'aaa',
age:18
})
function changeName(){
person.value.name = 'vvvvvvvvvv'
}
function changePerson(){
person.value = {name:'eeeeeeee',age:99}
}
let car = shallowReactive({
brand:'car',
options:{
color:'red'
}
})
function changeBrand(){
car.brand = 'vvvvvvvvvv'
}
function changeColor(){
car.options.color = 'blue'
}
</script>
readonly,shallowReadonly
- readonly 建立只讀的物件快照
- shallowReadonly 僅第一層只讀,更深層次的資料可以修改
<template>
<h3>{{ copyPerson }}</h3>
<button @click="changeName">changeName</button>
<button @click="changePerson">changePerson</button>
<h3>{{ car }}</h3>
<button @click="changeBrand">changeBrand</button>
<button @click="changeColor">changeColor</button>
</template>
<script setup name="App" lang="ts">
import { ref,reactive } from 'vue';
// import { shallowRef,shallowReactive } from 'vue';
import { readonly,shallowReadonly } from 'vue';
let person = ref({
name:'aaa',
age:18
})
let copyPerson = readonly(person)
function changeName(){
copyPerson.value.name = 'vvvvvvvvvv' // 不能修改
}
function changePerson(){
copyPerson.value = {name:'eeeeeeee',age:99} // 不能修改
}
let car = reactive({
brand:'car',
options:{
color:'red'
}
})
let copyCar = shallowReadonly(car)
function changeBrand(){
copyCar.brand = 'vvvvvvvvvv' // 不能修改
}
function changeColor(){
copyCar.options.color = 'blue' // 能修改
}
</script>
toRaw,markRaw
- toRaw: 可以將reactive定義的響應式資料變為普通物件,用於要將響應式物件傳給非vue的庫或者其他系統時
- markRaw:標記為非響應式,防止被改;如mockjs
<template>
<h3>{{ rawPerson }}</h3>
<button @click="changeName">changeName</button>
<button @click="changePerson">changePerson</button>
<h3>{{ rawCar }}</h3>
<button @click="changeBrand">changeBrand</button>
<button @click="changeColor">changeColor</button>
</template>
<script setup name="App" lang="ts">
import { ref,reactive } from 'vue';
// import { shallowRef,shallowReactive } from 'vue';
// import { readonly,shallowReadonly } from 'vue';
import { toRaw,markRaw } from 'vue';
let person = {
name:'aaa',
age:18
}
// let rawPerson = ref(person)
let rawPerson = markRaw(person)
console.log(person);
console.log(rawPerson);
function changeName(){
rawPerson.value.name = 'vvvvvvvvvv'
}
function changePerson(){
rawPerson.value = {name:'eeeeeeee',age:99}
}
let car = reactive({
brand:'car',
options:{
color:'red'
}
})
let rawCar = toRaw(car)
console.log(car);
console.log(rawCar);
function changeBrand(){
rawCar.brand = 'vvvvvvvvvv'
}
function changeColor(){
rawCar.options.color = 'blue'
}
</script>
customRef自定義ref
- 重點在:track監視資料的變化,trigger通知vue資料已經變化了
- get在資料被讀取時呼叫,set在資料被修改時呼叫
- 可以使用hooks的知識封裝方法(需要return)
// App.vue
<template>
<h3>msg {{ msg }}</h3>
<input type="text" v-model="msg">
<h3>customMsg {{ customMsg }}</h3>
<input type="text" v-model="customMsg">
</template>
<script setup name="App" lang="ts">
import { ref,customRef } from 'vue';
import useMsgRef from './useMsgRef'
let msg = ref('111')
let {customMsg} = useMsgRef('ssssss',2000)
</script>
// useMsgRef.vue
import { ref,customRef } from 'vue';
export default function(initMsg,delay){
let timer:number
let customMsg = customRef((track,trigger)=>{
return {
// 資料被讀取時呼叫
get() {
// 監視資料的變化
track()
return initMsg
},
// 資料被修改時呼叫
set(value) {
clearInterval(timer)
timer = setTimeout(()=>{
initMsg = value
// 通知vue資料已經變化了
trigger()
},delay)
}
}
})
return {customMsg}
}