1.vue3社區(qū)生態(tài):
ant-design-vue:https://antdv.com/docs/vue/introduce-cn/,螞蟻金服,ant-design-vue 是 Ant Design 的 Vue 實現(xiàn),組件的風格與 Ant Design 保持同步
element-plus:https://element-plus.gitee.io/#/zh-CN麸折,Element Plus茶鉴,一套為開發(fā)者政模、設計師和產(chǎn)品經(jīng)理準備的基于 Vue 3.0 的桌面端組件庫
vant:https://vant-contrib.gitee.io/vant/v3/#/zh-CN,有贊前端團隊開源的移動端組件庫褐荷,于 2016 年開源弄痹,已持續(xù)維護 4 年時間
Naive UI:https://www.naiveui.com/zh-CN/饭入,一個 Vue 3 組件庫比較完整,主題可調(diào)肛真,使用 TypeScript圣拄。
VueUse:https://vueuse.org/,基于composition組合api的常用集合
2.選項式Api和組合式Api
選項式Api版本實現(xiàn):
<template>
<div>
<!-- 功能一模板 -->
<button @click="show">顯示</button>
<button @click="hide">隱藏</button>
<div v-if="showDiv">一個被控制顯隱的div</div>
</div>
<div>
<!-- 功能二模板 -->
<button @click="changeRed">紅色</button>
<button @click="changeYellow">藍色</button>
<div :style="`color:${fontColor}`">一個被控制字體顏色的的div</div>
</div>
</template>
<script>
export default {
name: 'App',
data() {
return {
showDiv: true, // 功能一數(shù)據(jù)
fontColor: '' // 功能二數(shù)據(jù)
}
},
methods: {
// 功能一方法
show() {
this.showDiv = true
},
hide() {
this.showDiv = false
},
// 功能二方法
changeRed() {
this.fontColor = 'red'
},
changeYellow() {
this.fontColor = 'blue'
}
}
}
</script>
組合式API版本實現(xiàn):
<template>
<div>
<!-- 功能一模板 -->
<button @click="show">顯示</button>
<button @click="hide">隱藏</button>
<div v-if="showDivFlag">一個被控制顯隱的div</div>
</div>
<div>
<!-- 功能二模板 -->
<button @click="changeRed">紅色</button>
<button @click="changeBlue">藍色</button>
<div :style="`color:${fontColor}`">一個被控制字體顏色的的div</div>
</div>
</template>
<script>
import { ref } from 'vue'
export default {
name: 'App',
setup() {
// 功能一
const showDivFlag = ref(true)
function show() {
showDivFlag.value = true
}
function hide() {
showDivFlag.value = false
}
// 功能二
const fontColor = ref('')
function changeRed() {
fontColor.value = 'red'
}
function changeBlue() {
fontColor.value = 'blue'
}
return { showDivFlag, show, hide, fontColor, changeRed, changeBlue }
}
}
</script>
組合式API優(yōu)化
<script>
import { ref } from 'vue'
// 功能A
function useShow() {
const showDivFlag = ref(true)
function show() {
showDivFlag.value = true
}
function hide() {
showDivFlag.value = false
}
return { showDivFlag, show, hide }
}
// 功能B
function useColor() {
const fontColor = ref('')
function changeRed() {
fontColor.value = 'red'
}
function changeBlue() {
fontColor.value = 'blue'
}
return { fontColor, changeRed, changeBlue }
}
export default {
name: 'App',
setup() {
// 功能一
const { showDivFlag, show, hide } = useShow()
// 功能二
const { fontColor, changeRed, changeBlue } = useColor()
return { showDivFlag, show, hide, fontColor, changeRed, changeBlue }
}
}
</script>
3.組合式api具體說明:
setup 入口:
a. setup 函數(shù)是一個新的組件選項毁欣,作為組件中組合式API 的起點(入口)
b. setup函數(shù)只會在組件初始化的時候執(zhí)行一次
c. setup函數(shù)在beforeCreate生命周期鉤子執(zhí)行之前執(zhí)行庇谆,實例還沒生成,沒有this
reactive:
reactive是一個函數(shù)凭疮,接收一個普通的對象傳入饭耳,把對象數(shù)據(jù)
轉(zhuǎn)化為響應式對象并返回
import { reactive } from 'vue'
const state = reactive({
name: 'cp',
age: 18
})
ref:
ref是一個函數(shù),接受一個簡單類型或者復雜類型的傳入并返回一個響應式且可變的 ref 對象
import { ref } from 'vue'
let money = ref(100)
reative 對比 ref:
a. ref 函數(shù)可以接收一個簡單類型的值执解,返回一個可改變的 ref 響應式對象寞肖,從而彌補reactive函數(shù)不支持簡單類型的問題
b. reactive和ref函數(shù)都可以提供響應式數(shù)據(jù)的轉(zhuǎn)換,具體什么時候需要使用哪個API社區(qū)還沒有最佳實踐衰腌,暫時可以使用自己熟練的API進行轉(zhuǎn)換
c. **推薦寫法 **只有我們明確知道要轉(zhuǎn)換的對象內(nèi)部的字段名稱我們才使用reactive新蟆,否則就一律使用ref,從而降低在語法選擇上的心智負擔
watch:
對響應數(shù)據(jù)進行監(jiān)聽右蕊,可定義是否立即執(zhí)行一次和是否深度監(jiān)聽琼稻,包含三個參數(shù),第一個參數(shù)是function饶囚,返回值為要監(jiān)聽的數(shù)據(jù)帕翻,注意,要寫return萝风!第二個參數(shù)也是function嘀掸,監(jiān)聽到第一個參數(shù)返回值變化后,要做什么操作规惰;第三個參數(shù)是對象睬塌,包含:{
immediate: true,deep: true}歇万,immediate(是否立即執(zhí)行一次)揩晴,deep(是否深度監(jiān)聽)
import { reactive, toRefs, watch } from 'vue'
setup() {
const state = reactive({
name: 'cp',
info: {
age: 18
}
})
watch(() => {
return state
}, () => {
// 數(shù)據(jù)變化之后的回調(diào)函數(shù)
console.log('age發(fā)生了變化')
}, {
deep: true
})
return {
state
}
}
toRefs:
toRefs 用于將響應式對象轉(zhuǎn)換為結(jié)果對象,其中結(jié)果對象的每個屬性都是指向原始對象相應屬性的ref堕花。
常用于es6的解構(gòu)賦值操作文狱,因為在對一個響應式對象直接解構(gòu)時解構(gòu)后的數(shù)據(jù)將不再有響應式,而使用toRefs可以方便解決這一問題
生命周期函數(shù):
代碼演示:
import { onMounted } from 'vue'
export default {
setup() {
// 時機成熟 回調(diào)函數(shù)自動執(zhí)行
onMounted(() => {
console.log('mounted生命周期執(zhí)行了')
})
onMounted(() => {
console.log('mounted生命周期函數(shù)又執(zhí)行了')
})
}
}
父子通信
- setup函數(shù)提供倆個參數(shù)缘挽,第一個參數(shù)為props瞄崇,第二個參數(shù)為一個對象context
- props為一個對象,內(nèi)部包含了父組件傳遞過來的所有prop數(shù)據(jù)壕曼,context對象包含了attrs苏研,slots, emit屬性腮郊,其中的
emit
可以觸發(fā)自定義事件的執(zhí)行從而完成子傳父
<template>
<son :msg="msg" @get-msg="getMsg"></son>
</template>
<script>
import { ref } from 'vue'
import Son from './components/son'
export default {
components: {
Son
},
setup() {
const msg = ref('this is msg')
function getMsg(msg) {
console.log(msg)
}
return {
msg,
getMsg
}
}
}
</script>
<template>
<div>
{{msg}}
<button @click="setMsgFromSon">set</button>
</div>
</template>
<script>
export default {
props: {
msg: {
type: String
}
},
emits: ['get-msg'], // 聲明當前組件觸發(fā)的自定義事件
setup(props,{emit}) {
function setMsgFromSon(){
emit('get-msg','這是一條來自子組件的新的msg信息')
}
return {
setMsgToSon
}
}
}
</script>
provide 和 inject:
通常我們使用props進行父子之間的數(shù)據(jù)傳遞摹蘑,但是如果組件嵌套層級較深,一層一層往下傳遞將會變的非常繁瑣轧飞,有沒有一種手段可以把這個過程簡化一下呢衅鹿,有的撒踪,就是我們馬上要學習的provide 和 inject,它們配合起來可以方便的完成從上層組件向任意下層組件傳遞數(shù)據(jù)的效果
<template>
<father></father>
<button @click="changeName">change name</button>
</template>
<script>
import Father from '@/components/Father'
import { provide, ref } from 'vue'
export default {
components: {
Father
},
setup() {
// 使用ref轉(zhuǎn)換成響應式再傳遞
let name = ref('張三')
function changeName(){
name.value = 'pink'
}
provide('name', name)
return {
changeName
}
}
}
</script>
<template>
我是子組件
{{ name }}
</template>
<script>
import { inject } from 'vue'
export default {
setup() {
const name = inject('name')
return {
name
}
}
}
</script>
TemplateRef:
- 使用ref函數(shù)傳入null創(chuàng)建 ref對象 =>
const hRef = ref(null)
- 模板中通過定義ref屬性等于1中創(chuàng)建的ref對象名稱建立關(guān)聯(lián) =>
<h1 ref="hRef"></h1>
- 把
hRef
return出去 - 使用 =>
hRef.value
<template>
<h1 ref="h1Ref">我是普通dom標簽</h1>
<ref-comoonent ref="comRef"></ref-comoonent>
</template>
<script>
import { onMounted, ref } from 'vue'
import RefComoonent from '@/components/RefComponent'
export default {
components: {
RefComoonent
},
setup() {
const h1Ref = ref(null)
const comRef = ref(null)
onMounted(() => {
console.log(h1Ref.value)
console.log(comRef.value)
})
// 必須return
return {
h1Ref,
comRef
}
}
}
</script>
語法兼容問題:
- 過濾器filter移除 (插值表達式里不能再使用過濾器 可以使用methods替代)
- .sync語法移除 (dialog) (和v-model語法合并)
- eventBus
emit