1. Hook函數(shù)
useCar
import {ref,computed} from 'vue'
//導(dǎo)出去一個(gè)函數(shù)
export default function(){
//汽車(chē)數(shù)據(jù)
let carName = ref('保時(shí)捷')
let carPrice = ref(100)
//汽車(chē)的計(jì)算屬性
let carPrice2 = computed(()=>{
return (carPrice.value*0.8).toFixed(2)
})
//操作汽車(chē)的方法
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 = '蘋(píng)果'
phonePrice.value = 9000
}
//返回暴露給外界的內(nèi)容
return {
phoneName,
phonePrice,
phonePrice2,
updatePhone
}
}
組件
<h1>Hook函數(shù)</h1>
<div class="car">
<h2>汽車(chē)信息</h2>
<ul>
<li>汽車(chē)名稱(chēng):{{carName}}</li>
<li>汽車(chē)價(jià)格:{{carPrice}}萬(wàn)</li>
<li>優(yōu)惠價(jià)格:{{carPrice2}}萬(wàn)</li>
<li>
<button @click="updateCar">修改汽車(chē)信息</button>
</li>
</ul>
</div>
<div class="phone">
<h2>手機(jī)信息</h2>
<ul>
<li>手機(jī)名稱(chēng):{{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 {
//返回汽車(chē)信息
...useCar(),
//返回手機(jī)信息
...usePhone()
}
}
}
2. toRef和toRefs
toRef()方法,用于將一個(gè)reactive對(duì)象里面的指定屬性以ref形式的對(duì)象返回
這樣寫(xiě)的好處是伍俘,可以簡(jiǎn)化模板里面的語(yǔ)法。
name:toRef(student,'name'),
age:toRef(student,'age'),
sex:toRef(student,'sex'),
address:toRef(student,'address')
`
toRefs()方法楣铁,用于將一個(gè)reactive對(duì)象返回一個(gè)新對(duì)象,
該對(duì)象里面的所有屬性都是一個(gè)ref對(duì)象更扁。
<h1>toRef和toRefs</h1>
<div class="stu">
<h2>學(xué)生信息</h2>
<ul>
<li>姓名:{{name}}</li>
<li>姓名:{{age}}</li>
<li>車(chē)名:{{car.name}}</li>
<li>車(chē)價(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ù)盖腕,可以用來(lái)為一個(gè) reactive 對(duì)象的屬性創(chuàng)建一個(gè) ref
// 這樣做的好處是,簡(jiǎn)化了模板中的表達(dá)式疯潭。
// toRef()函數(shù)赊堪,需要傳兩個(gè)參數(shù):1.reactive 對(duì)象,2.具體的屬性名
// name:toRef(stuData,'name'),
// age:toRef(stuData,'age'),
// car:toRef(stuData,'car')
// 假如 reactive 對(duì)象中竖哩,有100個(gè)屬性哭廉,上面的操作要寫(xiě)100次,所以相叁,一般都直接用toRefs函數(shù)
// toRefs函數(shù)遵绰,把一個(gè)響應(yīng)式對(duì)象轉(zhuǎn)換成普通對(duì)象,該普通對(duì)象的每個(gè) 屬性 都是一個(gè) ref
...toRefs(stuData)
}
}
}
3. 其他的組合式API
readonly()函數(shù)增淹,返回一份只讀數(shù)據(jù)椿访,這個(gè)只讀是“深層的”,內(nèi)部任何嵌套的屬性也都是只讀的
注意:該方法虑润,不能將一個(gè)普通值類(lèi)型數(shù)據(jù)轉(zhuǎn)為只讀數(shù)據(jù)
isRef()檢查值是否為一個(gè) ref 對(duì)象成玫。
customRef()創(chuàng)建一個(gè)自定義的 ref,并對(duì)其依賴(lài)項(xiàng)跟蹤和更新觸發(fā)進(jìn)行顯式控制。它需要一個(gè)工廠函數(shù)哭当,該函數(shù)接收 track 和 trigger 函數(shù)作為參數(shù)猪腕,并且應(yīng)該返回一個(gè)帶有 get 和 set 的對(duì)象.
shallowRef()創(chuàng)建一個(gè)跟蹤自身 .value 變化的 ref,但不會(huì)使其值也變成響應(yīng)式的钦勘。
triggerRef()手動(dòng)執(zhí)行與 shallowRef
關(guān)聯(lián)的任何作用 (effect)陋葡。
<h1>其他的組合式API</h1>
<div>
學(xué)生信息:{{stuData}}
<br>
<button @click="stuData.age++">修改年齡</button>
<button @click="stuData.car.price++">修改車(chē)價(jià)</button>
</div>
<div>
num3的值:{{num3}}
</div>
<div>
汽車(chē)信息:{{car}}
<button @click="updateCar">修改汽車(chē)</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 對(duì)象
// isProxy()函數(shù)肛响,檢查一個(gè)對(duì)象是否是由 reactive 或者 readonly 方法創(chuàng)建的代理
// isReactive()函數(shù)岭粤,檢查一個(gè)對(duì)象是否是由 reactive 創(chuàng)建的響應(yīng)式代理
// isReadonly()函數(shù),檢查一個(gè)對(duì)象是否是由 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() 返回的對(duì)象 value 屬性值是 reactive對(duì)象(代理對(duì)象)
// shallowRef() 返回的對(duì)象 value 屬性值是 object對(duì)象(普通對(duì)象)门扇,不再具備任何響應(yīng)式了
let car = shallowRef({
name:'大眾',
type:{
typeName:'SUV'
}
})
let updateCar = ()=>{
// 由于value返回的是object對(duì)象雹有,所以,這里不再具有響應(yīng)式
car.value.name = '奔馳'
car.value.type.typeName = '跑車(chē)'
}
// shallowReactive() 返回一個(gè)淺層的響應(yīng)式代理臼寄,只對(duì)對(duì)象的第一層屬性創(chuàng)建響應(yīng)式
let phone = shallowReactive({
name:'華為',
type:{
typeName:'滑蓋手機(jī)'
}
})
// toRaw() 將代理對(duì)象轉(zhuǎn)為一個(gè)普通對(duì)象返回
let phone2 = toRaw(phone)
console.log(phone2);
console.log('--------------------');
//定義了一份數(shù)據(jù)
// markRaw() 記一個(gè)對(duì)象為“永遠(yuǎn)不會(huì)轉(zhuǎn)為響應(yīng)式代理”
let food = markRaw({
name:'面包'
})
// 注意:food2就是一個(gè)普通對(duì)象
let food2 = reactive(food)
console.log(food2);
let updatePhone = ()=>{
//修改name霸奕,會(huì)觸發(fā)頁(yè)面更新
// phone.name += "!"
//修改type里面的屬性,不會(huì)觸發(fā)頁(yè)面更新
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
}
}
}