### 一、自定義組件使用`v-model`實現雙休數據綁定
前面的課程我們給大家講過v-model,v-model主要用于表單的雙休數據綁定。現在給大家講解一下v-model實現自定義組件的雙休數據綁定。
#### 1.1、單個v-mode數據綁定
默認情況下,組件上的 `v-model` 使用 `modelValue` 作為 prop 和 `update:modelValue` 作為事件。我們可以通過向 `v-model` 傳遞參數來修改這些名稱:
~~~
<my-component v-model:foo="bar"></my-component>
~~~
在本例中,子組件將需要一個 `foo` prop 并發出 `update:foo` 要同步的事件:
~~~
const app = Vue.createApp({})
app.component('my-component', {
props: {
foo: String
},
template: `
<input
type="text"
:value="foo"
@input="$emit('update:foo', $event.target.value)">
`
})
~~~
#### 1.2、多個 v-model 綁定
通過利用以特定 prop 和事件為目標的能力,正如我們之前在 [`v-model` 參數](https://v3.cn.vuejs.org/guide/component-custom-events.html#v-model-%E5%8F%82%E6%95%B0)中所學的那樣,我們現在可以在單個組件實例上創建多個 v-model 綁定。
每個 v-model 將同步到不同的 prop,而不需要在組件中添加額外的選項。
~~~
<user-name
v-model:first-name="firstName"
v-model:last-name="lastName"
></user-name>
~~~
~~~
const app = Vue.createApp({})
app.component('user-name', {
props: {
firstName: String,
lastName: String
},
template: `
<input
type="text"
:value="firstName"
@input="$emit('update:firstName', $event.target.value)">
<input
type="text"
:value="lastName"
@input="$emit('update:lastName', $event.target.value)">
`
})
~~~
### 二、自定義組件slots
Vue 實現了一套內容分發的 API,這套 API 的設計靈感源自 [Web Components 規范草案](https://github.com/w3c/webcomponents/blob/gh-pages/proposals/Slots-Proposal.md),將 `<slot>` 元素作為承載分發內容的出口。
#### 1、自定義一個按鈕組件
~~~
<template>
<button class="btn-primary">
<slot></slot>
</button>
</template>
<script>
export default {
}
</script>
<style lang="scss">
.btn-primary {
padding: 5px 10px;
background: orange;
color: #fff;
border: none;
}
</style>
~~~
#### 2、調用這個組件
~~~
<v-button class="btn-primary">登錄</v-button>
~~~
slot還允許在自定義組件里面傳入任意的html標簽,或者其他組件
~~~
<v-button class="btn-primary">
<i>Icon</i> 登錄
</v-button>
~~~
slot中還可以綁定父組件的數據
~~~
<v-button class="btn-primary">
<i>Icon</i> 登錄
{{title}}
</v-button>
~~~
### 三、slots默認值
~~~
<button type="submit">
<slot>Submit</slot>
</button>
~~~
~~~
<submit-button></submit-button>
~~~
“Submit”將會被渲染為:
~~~
<button type="submit">
Submit
</button>
~~~
### 五、Vue3.x非 Prop 的Attribute 繼承
一個非 prop 的 attribute 是指傳向一個組件,但是該組件并沒有相應 [props](https://v3.cn.vuejs.org/guide/component-props) 或 [emits](https://v3.cn.vuejs.org/guide/component-custom-events.html#defining-custom-events) 定義的 attribute。常見的示例包括 `class`、`style` 和 `id` 屬性。
#### 2.1、當組件返回單個根節點時,非 prop attribute 將自動添加到根節點的 attribute 中。
**如:**
子組件DatePicker.vue
~~~
<template>
<div class="date-picker">
<input type="date" />
</div>
</template>
<script>
export default {
}
</script>
~~~
父組件:
~~~
<template>
<date-picker data-status="activated"></date-picker>
</template>
<script>
import DatePicker from "./DatePicker"
export default {
data() {
return {
title: "你好vue"
}
},
components: {
DatePicker
}
}
</script>
~~~
**渲染完成的效果:**
~~~
<div class="date-picker" data-status="activated">
<input type="datetime" />
</div>
~~~
#### 2.2、同樣的規則適用于事件監聽器:
**父組件:**
~~~
<date-picker @change="submitChange"></date-picker>
~~~
**子組件:**
~~~
mounted() {
console.log(this.$attrs) // { onChange: () => {} }
}
~~~
#### 2.3、完整示例:
**子組件DatePicker.vue**
~~~
<template>
?<select>
<option value="1">Yesterday</option>
<option value="2">Today</option>
<option value="3">Tomorrow</option>
</select>
</template>
~~~
**父組件**
~~~
<date-picker @change="showChange"></date-picker>
~~~
~~~
methods: {
showChange(event) {
console.log(event.target.value) // 獲取子組件選擇的值
}
}
~~~
### 六、自定義 Attribute 繼承
如果你**不**希望組件的根元素繼承 attribute,你可以在組件的選項中設置 `inheritAttrs: false`。例如:
禁用 attribute 繼承的常見情況是需要將 attribute 應用于根節點之外的其他元素。
通過將 `inheritAttrs` 選項設置為 `false`,你可以訪問組件的 `$attrs` property,該 property 包括組件 `props` 和 `emits` property 中未包含的所有屬性 (例如,`class`、`style`、`v-on` 監聽器等)。
**子組件:**
~~~
<template>
<div class="date-picker">
<input type="date" v-bind="$attrs" />
</div>
</template>
<script>
export default {
inheritAttrs: false,
data() {
return {
}
}
}
</script>
~~~
**父組件:**
~~~
<template>
<date-picker data-status="activated"></date-picker>
</template>
<script>
import DatePicker from "./DatePicker"
export default {
data() {
return {
title: "你好vue"
}
},
components: {
DatePicker
}
}
</script>
~~~
**渲染完成的效果:**
~~~
<div class="date-picker">
<input type="datetime" data-status="activated" />
</div>
~~~
### 七、多個根節點上的 Attribute 繼承
與單個根節點組件不同,具有多個根節點的組件不具有自動 attribute 回退行為。如果未顯式綁定 `$attrs`,將發出運行時警告。
~~~
<custom-layout id="custom-layout" @click="changeValue"></custom-layout>
~~~
~~~
// 這將發出警告
app.component('custom-layout', {
template: `
<header>...</header>
<main>...</main>
<footer>...</footer>
`
})
// 沒有警告,$attrs被傳遞到<main>元素
app.component('custom-layout', {
template: `
<header>...</header>
<main v-bind="$attrs">...</main>
<footer>...</footer>
`
})
~~~
- 空白目錄
- 第一節 Vue3.x教程、Vue3.x簡介、搭建Vue3.x環境、創建運行Vue3.x項目、分析Vue目錄結構
- 第二節 Vue3.x綁定數據、綁定html、綁定屬性、循環數據
- 第三節 Vue3.x中的事件方法入門、模板語法模板中類和樣式綁定
- 第四節 Vue3.x中的事件方法詳解、事件監聽、方法傳值、事件對象、多事件處理程序、事件修飾符、按鍵修飾符
- 第五節 Vue3.x中Dom操作$refs 以及表單( input、checkbox、radio、select、 textarea )結合雙休數據綁定實現在線預約功能
- 第六節 Vue3.x中使用JavaScript表達式 、條件判斷、 計算屬性和watch偵聽
- 第七節 Vue3.x 實現一個完整的toDoList(待辦事項) 以及類似京東App搜索緩存數據功能
- 第八節 Vue3.x中的模塊化以及封裝Storage實現todolist 待辦事項 已經完成的持久化
- 第九節 Vue3.x中的單文件組件 定義組件 注冊組件 以及組件的使用
- 第十節 Vue3.x父組件給子組件傳值、Props、Props驗證、單向數據流
- 第十一節 Vue3.x父組件主動獲取子組件的數據和執行子組件方法 、子組件主動獲取父組件的數據和執行父組件方法
- 第十二節 Vue3.x組件自定義事件 以及mitt 實現非父子組件傳值
- 第十三節 Vue3.x自定義組件上面使用v-mode雙休數據綁定 以及 slots以及 Prop 的Attribute 繼承 、禁用 Attribute 繼承
- 第十四節 Vue3.x中組件的生命周期函數(lifecycle)、 this.$nextTick、動態組件 keep-alive、Vue實現Tab切換
- 第十五節 Vue3.x中全局綁定屬性、使用Axios和fetchJsonp請求真實api接口數據、函數防抖實現百度搜索
- 第十六節 Vue3.x中的Mixin實現組件功能的復用 、全局配置Mixin
- 第十七節 Vue3.x Teleport、使用Teleport自定義一個模態對話框的組件
- 第十八節 Vue3.x Composition API 詳解
- 第十九節 Vue3.x中集成Typescript 使用Typescript
- 第二十節 Vue-Router 詳解
- 第二十節 Vuex教程-Vuex 中的 State Mutation Getters mapGetters Actions Modules