一、setup
- setup函數(shù)可以被理解為函數(shù)的入口
- setup函數(shù)接收兩個(gè)參數(shù):
props、context(包含attrs、slots、emit) - setup函數(shù)是處于生命周期函數(shù)
beforeCreate之前執(zhí)行,執(zhí)行setup函數(shù)時(shí)組件實(shí)例并未被創(chuàng)建,this不指向vue實(shí)例 - 與模板一起使用:須在
ref或reactive中聲明然后return出去使用才是響應(yīng)式的 - 使用渲染函數(shù):可以返回一個(gè)渲染函數(shù),該函數(shù)可以直接使用在同一作用域中聲明的響應(yīng)式狀態(tài)
二、setup第一個(gè)參數(shù)props
props 是響應(yīng)式的,當(dāng)傳入新的 prop 時(shí),它將被更新。
export default {
props: {
title: String
},
setup(props) {
console.log(props.title)
}
}
因?yàn)?props 是響應(yīng)式的,不能使用 ES6 解構(gòu),會(huì)消除 prop 的響應(yīng)性。
如果需要解構(gòu) prop,可以在 setup 函數(shù)中使用 [toRefs]函數(shù)來(lái)完成此操作:
setup(props) {
const { title } = toRefs(props)
return{ title }
}
三、setup第二個(gè)參數(shù)context
context 是一個(gè)普通 JavaScript 對(duì)象,暴露了其它可能在 setup 中有用的值
setup(props, context) {
// Attribute (非響應(yīng)式對(duì)象,等同于 $attrs)
console.log(context.attrs)
// 插槽 (非響應(yīng)式對(duì)象,等同于 $slots)
console.log(context.slots)
// 觸發(fā)事件 (方法,等同于 $emit)
console.log(context.emit)
// 暴露公共 property (函數(shù))
console.log(context.expose)
}
context不是響應(yīng)的,可以用ES6進(jìn)行解構(gòu)
setup(props, { attrs, slots, emit, expose }) {
...
}
四、ref
引入
import { ref } from "vue";
setup(){
const arr = ref(["小美", "小紅", "小藍(lán)", "小綠"]);
const str = ref("1小美");
const onBtn = function(index: number) {
str.value = index + 1 + arr.value[index];
};
return { arr, onBtn, str };
}
注意:ref引入的值需要使用.value才能拿到
使用
<template>
<button v-for="(item, index) in arr" :key="index" @click="onBtn(index)">
{{ index + 1 }}:{{ item }}
</button>
<div>您點(diǎn)擊了:{{ str }}</div>
<button @click="complete">完成</button>
</template>
五、reactive
reactive和ref的作用差不多,都是引入響應(yīng)式數(shù)據(jù),但是reactive看起來(lái)結(jié)構(gòu)更加清晰
import { reactive} from "vue";
const obj: type = reactive({
arr: ["小美", "小紅", "小藍(lán)", "小綠"],
str: "",
onBtn: (index): void => {
obj.str = index + 1 + obj.arr[index];
}
});
const obj1 = toRefs(obj);
return { ...obj1 };
// 未使用toRefs時(shí),不能用ES6結(jié)構(gòu) 老老實(shí)實(shí)寫(xiě)obj.arr...
其實(shí)在工作上為了嚴(yán)謹(jǐn)不能讓TS自己猜類型,需要定義類型
interface type {
arr: Array<string>;
str: string;
// onBtn: (index: number):void => {};錯(cuò)誤寫(xiě)法
onBtn: (index: number) => void
}
六、watch
1、監(jiān)聽(tīng)ref的值
const xxx = ref("")
watch(xxx, (newV, oldV) => {
console.log(newV, oldV, 88);
});
2、監(jiān)聽(tīng)reactive的值
const obj= reactive({
str: "",
})
watch(() => obj.str, (newV, oldV) => {});
原因:vue無(wú)法監(jiān)聽(tīng)對(duì)象內(nèi)部的值,需要將值return出去監(jiān)聽(tīng)
3、監(jiān)聽(tīng)多個(gè)值
watch([xxx,() => obj.str], (newV, oldV) => {
console.log(newV[0],newV[1])
console.log(oldV[0],oldV[1])
});
七、 vue3的生命周期鉤子
setup里的生命周期鉤子,同級(jí)別中比vue2的先執(zhí)行
onBeforeMount(() => {});

image.png
八、調(diào)試API
// 主要用于調(diào)試 打出全部的值
onRenderTracked(event => {
console.log(event);
});
// 主要用于調(diào)試 打出變化的新舊值
onRenderTriggered(event => {
console.log(event);
});
九、模塊化
一個(gè)簡(jiǎn)單的模塊化的時(shí)間
<template>
<button @click="tiemf">開(kāi)始</button>
<div>{{ time }}</div>
</template>
<script lang="ts">
import { time, tiemf } from "./useTs";
export default {
setup() {
return { time, tiemf };
}
};
</script>
import { ref } from "vue";
const time = ref("00:00:00")
const tiemf = () =>{
setInterval(() => {
const hour = new Date().getHours();
const minute = new Date().getMinutes();
const sec = new Date().getSeconds();
time.value = hour + ":" + minute + ":" +sec;
}, 1000);
}
export {time,tiemf}