前端學習-vue影片學習015-其他API

ayubene發表於2024-04-10

尚矽谷影片教程

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}
}

相關文章