Vue.js學習記錄-5-Vue進階:元件
6.元件 - 計數器Demo為例
-
元件使用細節
-
全域性元件 and 區域性元件
全域性元件:
// 全域性元件(子元件) Vue.component('row', { template: '<tr><td>{{ content }}</td></tr>', // 2. 子元件中的data必須是函式方法形式返回唯一的資料物件 data: function () { return { content: 'this is content' } } }),
區域性元件: 在根元件中需要宣告區域性元件
var counter = { template: '<tr><td>{{ content }}</td></tr>', // 2. 子元件中的data必須是函式方法形式返回唯一的資料物件 data: function () { return { content: 'this is content' } } } var vm = new Vue({ el: "#root", // 宣告區域性元件 components: { counter: counter }, )}
-
元件複用:元件進行任意次數的複用
<!-- 計數器Demo --> <counter @change="handleChange" ref="one"></counter> <counter @change="handleChange" ref="two"></counter>
-
元件中 data 必須是一個函式,每個元件例項可以維護一份被返回物件的獨立拷貝。
-
-
父子元件傳值
-
父元件通過屬性props向子元件進行傳值
<div id="root"> <!-- 父元件通過屬性向子元件進行傳值 --> <counter :count="0" @inc="handleIncrease"></counter> <counter :count="0" @inc="handleIncrease"></counter> <div>{{ total }}</div> </div> **可以看出,上述程式碼通過:count,綁定了count屬性,並添加了@inc自定義事件。** 父元件(根元件)通過**:count**,對子元件進行傳值。此時,子元件通過**props**對父元件傳值進行獲取。 // 定義區域性元件 var counter = { // 子元件通過props獲取父元件傳過來的值。注意:子元件不可直接對props中的資料進行更改,單向資料流原理。 props: ['count'], // 對父元件傳遞過來的值,子元件進行備份後進行更改 data: function () { return { number: this.count } }, // 下文待填充 }
-
子元件通過事件$emit向父元件進行傳值
通過上述操作,子元件可以對父元件的資料進行**獲取**,並由於**單項資料流原理進行了備份**。 接下來,**根據備份的父元件資料number進行模板渲染**。 template: "<div @click='handleCilck'>{{ number }}</div>", 此時,在子元件渲染的\<div>中添加了**click事件**,當塊級元素被點選時,向父元件進行傳值。 methods: { handleCilck: function () { this.number ++ // 向父元件傳遞已更改的值,觸發事件 this.$emit('inc', 1) } } 點選該塊級元素時,**備份資料number執行自增操作**,之後,**通過$emit方法進行自定義事件inc宣告,以及引數傳遞**。 上述提到的**@inc="handleIncrease"**,在父元件接收子元件的觸發事件,並獲取事件攜帶引數。 var vm = new Vue({ el: "#root", // 宣告區域性元件 components: { counter: counter }, data: { total: 0 }, methods: { // 接收子元件觸發事件,獲取事件攜帶引數 handleIncrease: function (step) { this.total += step } } }) **自定義方法inc**所對應的 **handleIncrease** 方法觸發後,**響應式更新資料 total 的值**。
-
元件的引數校驗與非Props特性
-
Prop驗證:元件的 prop 指定驗證要求,對格式、長度等方面進行引數驗證。
<child content="hello "></child>
子元件中新增Prop驗證:
Vue.component('child', { props: { content :{ // 型別驗證,陣列可包含多個數據型別 type: [String, Number], // 是否必需 required: false, // 預設值 default: 'default value', // 引數長度判斷 validator: function (value) { return (value.length > 5) } } }, template: '<div>{{content}}</div>', })
-
Props特性和非Props特性
Props特性:常規配置,父元件傳值、子元件接值、DOM內直接使用。 非Pros特性:
1. 子元件未通過props接收,因此不能顯示在DOM上。 2. 子元件模板內直接寫入內容而非插值表示式,會顯示在DOM最外層標籤上。
-
-
元件繫結原生事件
在元件的根元素上直接進行原生事件的監聽,此時可以使用v-on的.native修飾符。
<div id="root"> <!-- 子元件中繫結原生的點選事件 --> <child @click.native="handleCilck"></child> </div> <script> Vue.component('child', { template: '<div>Child</div>' }) var vm = new Vue({ el: "#root", methods: { handleCilck: function () { alert("元件繫結原生事件") } } }) </script>
-
非父子元件間傳值(Bus/匯流排/釋出訂閱模式/觀察者模式)
業務場景如下,圖片取自Vue.js官網文件,非父子元件進行傳值的幾種形式。
舉例: 兄弟元件之間的傳值問題,頁面如下:
<div id="root"> <child content="Tom"></child> <child content="Jerry"></child> </div>
元件中的設定:
// 對Vue中prototype的bus屬性新增vue例項 Vue.prototype.bus = new Vue() // 全域性元件 Vue.component('child', { // 元件模板 template: "<div @click='handleClick'>{{selfContent}}</div>", // 父元件通過props進行資料傳遞 props: { content: { // 資料傳遞約束 type: String, required: true } }, // 應對單項資料流問題,建立資料副本 data: function () { return { selfContent: this.content } }, methods: { handleClick: function () { // 由於bus屬性是一個vue例項,因此可以使用$emit進行事件的宣告,攜帶引數,當前資料副本 this.bus.$emit('change', this.selfContent) } }, // 生命週期鉤子函式 mounted() { // 防止this作用域發生變化,建立儲存副本 var this_ = this // 使用$on進行自定義事件change的處理 this.bus.$on('change', function (msg) { this_.selfContent = msg }) }, })
TIPS:採用 $emit 和 $on 實現非父子元件的傳值操作,需要注意的是:$emit 和 $on 事件必須在一個公共例項上,才能觸發。(本例中,公共例項為:bus )
-
v-once指令和動態元件
動態元件場景,頁面中需要通過按鈕進行元件的切換。
頁面:針對元件新增v-if,進行元件判斷
<div id="root"> <child-one v-if="type === 'child-one'"></child-one> <child-two v-if="type === 'child-two'"></child-two> <button @click="handleBtnClick">change</button> </div>
元件配置: 在handleBtnClick方法中,根例項進行三元表示式判斷,通過data中的type進行元件切換。
<script> Vue.component('child-one', { template: '<div>child-one</div>' }) Vue.component('child-two', { template: '<div>child-two</div>' }) var vm = new Vue({ el: '#root', data: { type: 'child-one' }, methods: { handleBtnClick: function () { this.type = this.type === 'child-one' ? 'child-two' : 'child-one' } } }) </script>
改造上述程式碼:
-
component為動態元件,屬性is繫結元件名稱(對應根例項中data中的type)。
<!-- component標籤為動態元件 屬性is繫結元件名稱 --> <component :is="type"></component>
-
採用v-once指令,提高靜態資料內容的渲染效率。
template: '<div v-once>child-one</div>'
TIPS:本篇內容關於Vue中is特性以及ref和$refs的使用將在後續博文中補充說明。
-