Vue3高階

1. Hook函數(shù)

useCar

import {ref,computed} from 'vue'
//導(dǎo)出去一個(gè)函數(shù)
export default function(){
    //汽車數(shù)據(jù)
    let carName = ref('保時(shí)捷')
    let carPrice = ref(100)
    //汽車的計(jì)算屬性
    let carPrice2 = computed(()=>{
        return (carPrice.value*0.8).toFixed(2)
    })
    //操作汽車的方法
    let updateCar = ()=>{
        carName.value = '賓利'
        carPrice.value = 300
    }
    //返回暴露給外界的內(nèi)容
    return {
        carName,
        carPrice,
        carPrice2,
        updateCar
    }
}

usePhone

import {ref,computed} from 'vue'
export default function(){
    //手機(jī)數(shù)據(jù)
    let phoneName = ref('華為')
    let phonePrice = ref(5000)
    //手機(jī)的計(jì)算屬性
    let phonePrice2 = computed(()=>{
        return (phonePrice.value*0.5).toFixed(2)
    })
    //操作手機(jī)的方法
    let updatePhone = ()=>{
        phoneName.value = '蘋果'
        phonePrice.value = 9000
    }
    //返回暴露給外界的內(nèi)容
    return {
        phoneName,
        phonePrice,
        phonePrice2,
        updatePhone
    }
}

組件

<h1>Hook函數(shù)</h1>
<div class="car">
    <h2>汽車信息</h2>
    <ul>
        <li>汽車名稱:{{carName}}</li>
        <li>汽車價(jià)格:{{carPrice}}萬</li>
        <li>優(yōu)惠價(jià)格:{{carPrice2}}萬</li>
        <li>
            <button @click="updateCar">修改汽車信息</button>
        </li>
    </ul>
</div>
<div class="phone">
    <h2>手機(jī)信息</h2>
    <ul>
        <li>手機(jī)名稱:{{phoneName}}</li>
        <li>手機(jī)價(jià)格:{{phonePrice}}</li>
        <li>優(yōu)惠價(jià)格:{{phonePrice2}}</li>
        <li>
            <button @click="updatePhone">修改手機(jī)信息</button>
        </li>
    </ul>
</div>
// 導(dǎo)入hook函數(shù)
import useCar from '../hooks/useCar'
import usePhone from '../hooks/usePhone'
export default {
    setup() {
        // 返回模板中需要使用的數(shù)據(jù)
        return {
            //返回汽車信息
            ...useCar(),
            //返回手機(jī)信息
            ...usePhone()
        }
    }
}

2. toRef和toRefs

toRef()方法,用于將一個(gè)reactive對象里面的指定屬性以ref形式的對象返回
這樣寫的好處是,可以簡化模板里面的語法。

     name:toRef(student,'name'),
     age:toRef(student,'age'),
     sex:toRef(student,'sex'),
     address:toRef(student,'address')

`
toRefs()方法,用于將一個(gè)reactive對象返回一個(gè)新對象,
該對象里面的所有屬性都是一個(gè)ref對象。

<h1>toRef和toRefs</h1>
<div class="stu">
    <h2>學(xué)生信息</h2>
    <ul>
        <li>姓名:{{name}}</li>
        <li>姓名:{{age}}</li>
        <li>車名:{{car.name}}</li>
        <li>車價(jià):{{car.price}}</li>
    </ul>
</div>
import { reactive,toRef,toRefs } from 'vue'
export default {
    setup() {
        // 定義數(shù)據(jù)
        let stuData = reactive({
            name:'張三',
            age:20,
            car:{
                name:'大眾',
                price:'20W'
            }
        })
        return{
            // toRef()函數(shù),可以用來為一個(gè) reactive 對象的屬性創(chuàng)建一個(gè) ref
            // 這樣做的好處是,簡化了模板中的表達(dá)式。
            // toRef()函數(shù),需要傳兩個(gè)參數(shù):1.reactive 對象,2.具體的屬性名
            // name:toRef(stuData,'name'),
            // age:toRef(stuData,'age'),
            // car:toRef(stuData,'car')
            // 假如 reactive 對象中,有100個(gè)屬性,上面的操作要寫100次,所以,一般都直接用toRefs函數(shù)
            // toRefs函數(shù),把一個(gè)響應(yīng)式對象轉(zhuǎn)換成普通對象,該普通對象的每個(gè) 屬性 都是一個(gè) ref 
            ...toRefs(stuData)
        }
    }
}

3. 其他的組合式API

readonly()函數(shù),返回一份只讀數(shù)據(jù),這個(gè)只讀是“深層的”,內(nèi)部任何嵌套的屬性也都是只讀的
注意:該方法,不能將一個(gè)普通值類型數(shù)據(jù)轉(zhuǎn)為只讀數(shù)據(jù)
isRef()檢查值是否為一個(gè) ref 對象。
customRef()創(chuàng)建一個(gè)自定義的 ref,并對其依賴項(xiàng)跟蹤和更新觸發(fā)進(jìn)行顯式控制。它需要一個(gè)工廠函數(shù),該函數(shù)接收 track 和 trigger 函數(shù)作為參數(shù),并且應(yīng)該返回一個(gè)帶有 get 和 set 的對象.
shallowRef()創(chuàng)建一個(gè)跟蹤自身 .value 變化的 ref,但不會使其值也變成響應(yīng)式的。
triggerRef()手動執(zhí)行與 shallowRef 關(guān)聯(lián)的任何作用 (effect)。

<h1>其他的組合式API</h1>
<div>
    學(xué)生信息:{{stuData}}
    <br>
    <button @click="stuData.age++">修改年齡</button>
    <button @click="stuData.car.price++">修改車價(jià)</button>
</div>
<div>
    num3的值:{{num3}}
</div>
<div>
    汽車信息:{{car}}
    <button @click="updateCar">修改汽車</button>
</div>
<div>
    手機(jī)信息:{{phone}}
    <button @click="updatePhone">修改手機(jī)</button>
</div>
<div>
    年齡:{{age}}
    <button @click="age++">年齡++</button>
</div>
import {ref,reactive,readonly,isRef,unref, shallowRef, isReactive, shallowReactive,customRef,toRaw, markRaw} from 'vue'
export default {
    setup() {
        // 定義數(shù)據(jù)
        // readonly()函數(shù),返回一份只讀數(shù)據(jù),這個(gè)只讀是“深層的”,內(nèi)部任何嵌套的屬性也都是只讀的
        let stuData = readonly({
            name:'張三',
            age:20,
            car:{
                name:'大眾',
                price:20
            }
        })
        let num1 = ref(100)
        let num2 = 200
        // isRef()函數(shù),檢查一個(gè)值是否為一個(gè) ref 對象
        // isProxy()函數(shù),檢查一個(gè)對象是否是由 reactive 或者 readonly 方法創(chuàng)建的代理
        // isReactive()函數(shù),檢查一個(gè)對象是否是由 reactive 創(chuàng)建的響應(yīng)式代理
        // isReadonly()函數(shù),檢查一個(gè)對象是否是由 readonly 創(chuàng)建的只讀代理
        // let num3 = (isRef(num1)?num1.value:num1) + (isRef(num2)?num2.value:num2)
        // unref()函數(shù),如果參數(shù)是一個(gè) ref 則返回它的 value,否則返回參數(shù)本身
        let num3 = unref(num1) + unref(num2)
        // ref() 返回的對象 value 屬性值是 reactive對象(代理對象)
        // shallowRef() 返回的對象 value 屬性值是 object對象(普通對象),不再具備任何響應(yīng)式了
        let car = shallowRef({
            name:'大眾',
            type:{
                typeName:'SUV'
            }
        })
        let updateCar = ()=>{
            // 由于value返回的是object對象,所以,這里不再具有響應(yīng)式
            car.value.name = '奔馳'
            car.value.type.typeName = '跑車'
        }
        // shallowReactive() 返回一個(gè)淺層的響應(yīng)式代理,只對對象的第一層屬性創(chuàng)建響應(yīng)式
        let phone = shallowReactive({
            name:'華為',
            type:{
                typeName:'滑蓋手機(jī)'
            }
        })
        // toRaw() 將代理對象轉(zhuǎn)為一個(gè)普通對象返回
        let phone2 = toRaw(phone)
        console.log(phone2);
        console.log('--------------------');
        //定義了一份數(shù)據(jù)
        // markRaw() 記一個(gè)對象為“永遠(yuǎn)不會轉(zhuǎn)為響應(yīng)式代理”
        let food = markRaw({
            name:'面包'
        })
        // 注意:food2就是一個(gè)普通對象
        let food2 = reactive(food)
        console.log(food2);
        let updatePhone = ()=>{
            //修改name,會觸發(fā)頁面更新
            // phone.name += "!"
            //修改type里面的屬性,不會觸發(fā)頁面更新
            phone.type.typeName += "!"
        }
        //自定義一個(gè)ref
        function useDebouncedRef(value, delay = 200) {
            let timeout
            // customRef(),用于自定義一個(gè) ref
            return customRef((track, trigger) => {
                return {
                    get() {
                        track()
                        return value
                    },
                    set(newValue) {
                        clearTimeout(timeout)
                            timeout = setTimeout(() => {
                            value = newValue
                            trigger()
                        }, delay)
                    },
                }
            })
        }
        let age = useDebouncedRef(20,2000)
        return {
            stuData,
            num3,
            car,
            updateCar,
            phone,
            updatePhone,
            age
        }
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容