vue3 新特性
整理的比較好的文檔:https://www.jianshu.com/p/1fd73091e2e4
組合式 API
vue3 中加入了組合式 ,這個功能的作用是將單個vue組件的,邏輯部分也能自由拆分組合,更深層次的實現解耦和高復用性
vue2 如果單個vue文件邏輯部分過大 ,我們往往 需要單獨用一個js文件或ts文件存放 邏輯(函數)並且為了使用vue組件上的響應式屬性不得不將vue實例傳進這個函數中,總有一種怪怪的感覺;
// vue2 單獨存放邏輯的文件
export default function handle(vue,xx){
vue.yy = xx ;
....
}
setup
在Vue3中,定義
methods
、watch
、computed
、data
數據 等都放在了setup()
函數中
響應式
- ref 用於創建簡單數據類型的響應式數據
- reactive 只能用於創建對象數據類型的相應式數據
teleport
teleport 可以將組件生成的dom節點 ,轉移到其他dom下作為其子節點
讓我們修改
modal-button
以使用<teleport>
,並告訴 Vue “Teleport 這個 HTML 到該‘body’標簽”。
app.component('modal-button', {
template: `
<button @click="modalOpen = true">
Open full screen modal! (With teleport!)
</button>
<teleport to="body"> // teleport 的 to屬性就是作為哪個dom的字節的
<div v-if="modalOpen" class="modal">
<div>
I'm a teleported modal!
(My parent is "body")
<button @click="modalOpen = false">
Close
</button>
</div>
</div>
</teleport>
`,
data() {
return {
modalOpen: false
}
}
})
Props:
to
-string
。需要 prop,必須是有效的查詢選擇器(獨一無二的類名或id或屬性)或HTMLElement
(如果在瀏覽器環境中使用)。指定將在其中移動<teleport>
內容的目標元素
<!-- 正確 -->
<teleport to="#some-id" />
<teleport to=".some-class" />
<teleport to="[data-teleport]" />
<!-- 錯誤 -->
<teleport to="h1" />
<teleport to="some-string" />
disabled
-boolean
。此可選屬性可用於禁用<teleport>
的功能,這意味着其插槽內容將不會移動到任何位置,而是在您在周圍父組件中指定了<teleport>
的位置渲染。
<teleport to="#popup" :disabled="displayVideoInline">
<video src="./my-movie.mp4">
</teleport>
請注意,這將移動實際的 DOM 節點,而不是被銷毀和重新創建,並且它還將保持任何組件實例的活動狀態。所有有狀態的 HTML 元素 (即播放的視頻) 都將保持其狀態。
片段
Vue 3 現在正式支持了多根節點的組件,也就是片段!
在 3.x 中,組件可以包含多個根節點!但是,這要求開發者顯式定義 attribute 應該分布在哪里。
<!-- Layout.vue -->
<template>
<header>...</header>
<main v-bind="$attrs">...</main>
<footer>...</footer>
</template>
因為2.x只有一個根節點 \(attrs 就會綁定到根節點上,現在3.x會有多個根節點,所以需要定義\)attrs需要綁定到到那個節點上
v-model
2.x 使用input + value 實現v-model , 3.x 里使用使用 modelValue
( 自己定義字段名與update:后面的字段一致即可 ,默認值是modelValue
) 作為 prop 和 update:modelValue
作為事件
app.component('my-component', {
props: {
title: String
},
emits: ['update:title'],
template:
` <input
type="text"
:value="title"
@input="$emit('update:title', $event.target.value)">
`
})
<my-component v-model:title="bookTitle"></my-component>
注意點:v-model 后面需要加對應的update后的的字段名 習慣於2.x語法后 前幾次會忘記加
並且可以使用多個v-model 只需要在v-model后面加上對應的prop字段名即可
v-model
修飾符
在2.x中v-model的修飾符有.trim、
.number和
.lazy,
在3.x中我們可以自定義修飾符,比如 v-model:title.capitalize="bar"
在子組件中 prop中 titleModifiers
中可以接收到 capitalize:ture
再做對應處理后
prop中修飾符的屬性名為 : arg + "Modifiers"
:(綁定value字段名 + "Modifiers")
父組件
<HelloWorld v-model:title.capitalize="inputValue" />
子組件
<input type="text" :value="title" @input="handleCapitalize" />
//prop
props: {
title: String,
titleModifiers: { //使用title + Modifiers 獲取修飾符對象 { capitalize:ture }
type: Object,
default: () => ({})
}
},
// mothods
handleCapitalize(event) {
let value = event.target.value;
if (this.titleModifiers.capitalize) { // capitalize:ture
value = value.toLocaleUpperCase();
}
this.$emit("update:title", value);
}
如果
v-modle
使用默認值modelValue
時,prop修飾符對象使用modelModifiers
作為屬性名
單文件組件狀態驅動的 CSS 變量(實驗性)
3.x
單文件組件中style中可是使用當前vue
實例的data數據
<template>
<div class="text">hello</div>
</template>
<script>
export default {
data() {
return {
color: 'red', // data中的變量在style中都可以使用 使用v-bind (11月10日最新提議)
font: { // 之前的提議是 var(--變量名)
size: '2em'
}
}
}
</script>
<style>
.text {
color: v-bind(color);
/* 使用對象.屬性 包在''引號中 */
font-size: v-bind('font.size');
}
</style>
單文件組件樣式作用域的變化
<style lang="scss" scoped>
/* deep (css選擇器) */
::v-deep(.foo) {}
/*可以在()里寫, 在sass less scss 等預編譯器中可以寫在 {} 中*/
::v-deep() {
.foo{
...
}
}
/* 簡寫 */
:deep(.foo) {}
/* 插槽 :TODO:目前沒發現怎么用 如果是父組件里寫 直接加選擇器就可以 子組件又怎么確定選擇器呢 ? */
::v-slotted(.foo) {}
/* 簡寫 */
:slotted(.foo) {}
/* 在 scoped 中作用全局的樣式 功能就 跟不加scoped一樣 感覺有點脫褲子放屁的感覺 */
::v-global(.foo) {}
/* 簡寫 */
:global(.foo) {}
</style>
tip 名詞含義
SFC
- 單文件組件