好看的網(wǎng)頁千篇一律叮称,有趣的代碼萬里挑一购撼。
2022新年好唱逢!
關(guān)鍵字:
Vue3高階\Hook函數(shù)\ 生命周期\toRef和toRefs \其他的組合式API
1. Hook函數(shù)
useCar
import {ref,computed} from 'vue'
//導(dǎo)出去一個函數(shù)
export default function(){
//汽車數(shù)據(jù)
let carName = ref('保時捷')
let carPrice = ref(100)
//汽車的計算屬性
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(){
//手機數(shù)據(jù)
let phoneName = ref('華為')
let phonePrice = ref(5000)
//手機的計算屬性
let phonePrice2 = computed(()=>{
return (phonePrice.value*0.5).toFixed(2)
})
//操作手機的方法
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>汽車價格:{{carPrice}}萬</li>
<li>優(yōu)惠價格:{{carPrice2}}萬</li>
<li>
<button @click="updateCar">修改汽車信息</button>
</li>
</ul>
</div>
<div class="phone">
<h2>手機信息</h2>
<ul>
<li>手機名稱:{{phoneName}}</li>
<li>手機價格:{{phonePrice}}</li>
<li>優(yōu)惠價格:{{phonePrice2}}</li>
<li>
<button @click="updatePhone">修改手機信息</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(),
//返回手機信息
...usePhone()
}
}
}
2. 生命周期
變化挺大的:
<h1>生命周期</h1>
<h3>
數(shù)量:{{count}}
<button @click="count++">數(shù)量++</button>
</h3>
// 組合式API生命周期函數(shù)
import {onBeforeMount,onMounted,onBeforeUpdate,onUpdated,onBeforeUnmount,onUnmounted} from 'vue'
export default {
// beforeCreate() {
// console.log('創(chuàng)建之前');
// },
// created() {
// console.log('創(chuàng)建完成');
// },
// beforeMount() {
// console.log('掛載之前1');
// },
// mounted() {
// console.log('掛載完成1');
// },
// beforeUpdate() {
// console.log('更新之前1');
// },
// updated() {
// console.log('更新完成1');
// },
//注意:在vue3中危融,對beforeDestroy和destroyed這兩個生命周期函數(shù)鞋怀,進行了重命名
/* beforeDestroy() {
console.log('銷毀之前');
},
destroyed() {
console.log('銷毀完成');
}, */
// 在vue3中双泪,beforeUnmount 替換了 beforeDestroy;unmounted 替換了 destroyed
// beforeUnmount() {
// console.log('卸載之前1');
// },
// unmounted() {
// console.log('卸載完成1');
// },
data() {
return {
count:1
}
},
// setup()函數(shù)密似,可以替代beforeCreate 和 created 這兩個生命周期函數(shù)
setup() {
console.log('setup');
//組合式API生命周期函數(shù)焙矛,會先與傳統(tǒng)的生命周期函數(shù)執(zhí)行
onBeforeMount(()=>{
console.log('掛載之前2');
})
onMounted(()=>{
console.log('掛載完成2');
})
onBeforeUpdate(()=>{
console.log('修改之前2');
})
onUpdated(()=>{
console.log('修改完成2');
})
onBeforeUnmount(()=>{
console.log('卸載之前2');
})
onUnmounted(()=>{
console.log('卸載完成2');
})
}
}
3. toRef和toRefs
<h1>toRef和toRefs</h1>
<div class="stu">
<h2>學(xué)生信息</h2>
<ul>
<li>姓名:{{name}}</li>
<li>姓名:{{age}}</li>
<li>車名:{{car.name}}</li>
<li>車價:{{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ù),可以用來為一個 reactive 對象的屬性創(chuàng)建一個 ref
// 這樣做的好處是残腌,簡化了模板中的表達式村斟。
// toRef()函數(shù),需要傳兩個參數(shù):1.reactive 對象抛猫,2.具體的屬性名
// name:toRef(stuData,'name'),
// age:toRef(stuData,'age'),
// car:toRef(stuData,'car')
// 假如 reactive 對象中蟆盹,有100個屬性,上面的操作要寫100次闺金,所以逾滥,一般都直接用toRefs函數(shù)
// toRefs函數(shù),把一個響應(yīng)式對象轉(zhuǎn)換成普通對象败匹,該普通對象的每個 屬性 都是一個 ref
...toRefs(stuData)
}
}
}
4.其他的組合式API
<h1>其他的組合式API</h1>
<div>
學(xué)生信息:{{stuData}}
<br>
<button @click="stuData.age++">修改年齡</button>
<button @click="stuData.car.price++">修改車價</button>
</div>
<div>
num3的值:{{num3}}
</div>
<div>
汽車信息:{{car}}
<button @click="updateCar">修改汽車</button>
</div>
<div>
手機信息:{{phone}}
<button @click="updatePhone">修改手機</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ù)讥巡,這個只讀是“深層的”,內(nèi)部任何嵌套的屬性也都是只讀的
let stuData = readonly({
name:'張三',
age:20,
car:{
name:'大眾',
price:20
}
})
let num1 = ref(100)
let num2 = 200
// isRef()函數(shù)舔哪,檢查一個值是否為一個 ref 對象
// isProxy()函數(shù)欢顷,檢查一個對象是否是由 reactive 或者 readonly 方法創(chuàng)建的代理
// isReactive()函數(shù),檢查一個對象是否是由 reactive 創(chuàng)建的響應(yīng)式代理
// isReadonly()函數(shù)捉蚤,檢查一個對象是否是由 readonly 創(chuàng)建的只讀代理
// let num3 = (isRef(num1)?num1.value:num1) + (isRef(num2)?num2.value:num2)
// unref()函數(shù)吱涉,如果參數(shù)是一個 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() 返回一個淺層的響應(yīng)式代理盅蝗,只對對象的第一層屬性創(chuàng)建響應(yīng)式
let phone = shallowReactive({
name:'華為',
type:{
typeName:'滑蓋手機'
}
})
// toRaw() 將代理對象轉(zhuǎn)為一個普通對象返回
let phone2 = toRaw(phone)
console.log(phone2);
console.log('--------------------');
//定義了一份數(shù)據(jù)
// markRaw() 記一個對象為“永遠(yuǎn)不會轉(zhuǎn)為響應(yīng)式代理”
let food = markRaw({
name:'面包'
})
// 注意:food2就是一個普通對象
let food2 = reactive(food)
console.log(food2);
let updatePhone = ()=>{
//修改name鳖链,會觸發(fā)頁面更新
// phone.name += "!"
//修改type里面的屬性,不會觸發(fā)頁面更新
phone.type.typeName += "!"
}
//自定義一個ref
function useDebouncedRef(value, delay = 200) {
let timeout
// customRef(),用于自定義一個 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
}
}
}