欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

深入探討Vue.js組件和組件通信

 更新時(shí)間:2016年09月12日 15:08:06   作者:lihongxun945  
這篇文章主要和大家一起深入探討Vue.js組件和組件通信的相關(guān)資料,感興趣的小伙伴們可以參考一下

基本是按照官網(wǎng)的 Guide 全部梳理了一遍:http://vuejs.org/guide/index.html 這里我們以一個(gè) Todo List 應(yīng)用為例來(lái)把相關(guān)的只是都串起來(lái),這篇里面的全部代碼都在github上 https://github.com/lihongxun945/vue-todolist

 Vue 實(shí)例

一個(gè) Vue 應(yīng)用是由一個(gè) root vue instance 引導(dǎo)啟動(dòng)的,而 Vue instance 是這么創(chuàng)建的:

var vm = new Vue({
 // options
})

 一個(gè) instance 實(shí)際上就是 MVVM 中的一個(gè) VM。 傳入的配置對(duì)象中data里的所有屬性都會(huì)被掛載到 instance上,而為了避免命名沖突,Vue 內(nèi)置方法都會(huì)以 $ 開(kāi)頭的屬性掛載到 instance 上。

instance 從創(chuàng)建到銷(xiāo)毀會(huì)經(jīng)歷如下生命周期:

在初始化的時(shí)候大致經(jīng)過(guò)三步:
 •綁定數(shù)據(jù)監(jiān)聽(tīng),即對(duì) data 的監(jiān)聽(tīng)
 •編譯模板
 •插入document或者替換對(duì)應(yīng)dom
 # Vue 基本語(yǔ)法

數(shù)據(jù)綁定

Vue 使用的是一種 類(lèi) mastache 語(yǔ)法。常用綁定語(yǔ)法分這么幾類(lèi):
 •mastache 語(yǔ)法,比如 {{ data }} {{ data | filter}}
 •v-bind 綁定屬性,比如 v-bind: href, v-bind:class
 •v-on 綁定事件, 比如 v-on:click, v-on:submit 

其中 v-* 都是 directive

例子:
<div v-bind:class="[classA, isB ? classB : '']">

 屬性計(jì)算

Vue 支持一個(gè)很有意思的屬性計(jì)算語(yǔ)法,可以指定一個(gè)屬性由其他屬性計(jì)算出來(lái),這樣就不用通過(guò) $watch 來(lái)實(shí)現(xiàn)了:

var vm = new Vue({
 el: '#example',
 data: {
 a: 1
 },
 computed: {
 // a computed getter
 b: function () {
 // `this` points to the vm instance
 return this.a + 1
 }
 }
})

 ## 流程控制和列表相關(guān)的語(yǔ)法 包括 `v-if`, `v-show`, `v-else`, `v-for`

表單

雙向數(shù)據(jù)綁定:

<input type="text" v-model="message" placeholder="edit me">

<input type="checkbox" id="jack" value="Jack" v-model="checkedNames">

 ## 動(dòng)畫(huà) 動(dòng)畫(huà)的實(shí)現(xiàn)方式和 Angular 以及 React 都是一樣的,都是通過(guò)添加和刪除 class 來(lái)實(shí)現(xiàn)的。 # Component

組件的基本用法

Component 的定義包括兩部分:

1 創(chuàng)建component類(lèi):

var Profile = Vue.extend({
 template: "<div> Lily </div>"
});

 2 注冊(cè)一個(gè) tagname:

Vue.component("me-profile", Profile);

 這樣我們就可以通過(guò) tagname 來(lái)使用這么組件了:

 <div id="todo">
 <my-profile></my-profile>
 <form v-on:submit="add" v-on:submit.prevent>
 <input type="text" v-model="input"/>
 <input type="submit" value='add' />
 </form>
 ...
</div>

 Vue.component("me-profile", Profile); 屬于全局注冊(cè),如果只是在某一個(gè)頁(yè)面內(nèi)使用,可以通過(guò)局部注冊(cè)的方式:

var vm = new Vue({
 el: "#todo",
 components: {
 "my-profile": Profile
 },
 ...
}

 其中因?yàn)槲覀兊?Vue 實(shí)例是綁定在 todo 元素上的,所以如果把 my-profile 放在這個(gè)元素外面是無(wú)效的,只有放在這個(gè)里面才會(huì)被 Vue 的這個(gè)實(shí)例引導(dǎo)初始化。

注意事項(xiàng):

Vue 構(gòu)造函數(shù)可以傳的參數(shù)基本都可以用在 Vue.extend 上,但是對(duì) el 和 data 兩個(gè)參數(shù)需要注意,為了避免不同實(shí)例間共享同一個(gè)對(duì)象,總是要通過(guò) function 返回一個(gè)新的對(duì)象比較靠譜:

var MyComponent = Vue.extend({
 data: function () {
 return { a: 1 }
 }
})

 因?yàn)閰?shù)都一樣,其實(shí)他們倆就是同一個(gè)東西,不過(guò)一個(gè)是組件,一個(gè)是用來(lái)引導(dǎo)Vue啟動(dòng)的。

模板注意事項(xiàng)

因?yàn)?Vue 就是原生的DOM,所以有些自定義標(biāo)簽可能不符合DOM標(biāo)準(zhǔn),比如想在 table 中自定義一個(gè) tr,如果直接插入 my-component 不符合規(guī)范,所以應(yīng)該這樣寫(xiě):

<table>
 <tr is="my-component"></tr>
</table>

 Props 傳遞數(shù)據(jù)

在 Vue 中每個(gè)組件都是獨(dú)立的,不能也不應(yīng)該直接訪問(wèn)父類(lèi)的data。所以我們通過(guò) props 來(lái)向子組件傳遞數(shù)據(jù),是不是和 React 的方式很像?

不同于 React,在 Vue 中子組件需要先聲明自己的 props 才行:

var Profile = Vue.extend({
 props: ["name"],
 template: `
 <h2>{{name}}'s Todo List</h2>
 <h4>{{name}} is a good girl</h4>
 `
});

 然后我們可以在使用 Profile 的時(shí)候這樣傳遞參數(shù):
<my-profile name='Lily'></my-profile>

 這種是通過(guò)字面量傳遞參數(shù),所以傳遞的值一定是字符串。還有一種方式是動(dòng)態(tài)傳參,通過(guò) v-bind 來(lái)傳遞參數(shù),可以雙向綁定數(shù)據(jù)或者傳非字符串參數(shù):
<my-profile v-bind:name=‘input'></my-profile>

 v-bind 如果是一個(gè)字符串,則是綁定父組件的data中對(duì)應(yīng)的字段,比如上面就是雙向綁定了 input 的值。如果是一個(gè)數(shù)字則就是綁定了一個(gè)數(shù)字。

Vue 還可以顯式指定單向還是雙向的數(shù)據(jù)綁定:

<!-- default, one-way-down binding -->
<child :msg="parentMsg"></child>

<!-- explicit two-way binding -->
<child :msg.sync="parentMsg"></child>

<!-- explicit one-time binding -->
<child :msg.once="parentMsg"></child>

 Props 校驗(yàn)

一個(gè)好的組件總是應(yīng)該先驗(yàn)證參數(shù)是否正確,另外可能還需要設(shè)置一些參數(shù)的默認(rèn)值:

var Profile = Vue.extend({
 input: {
 type: String
 }
});

 父子組件通信

上面講到的 props 其實(shí)就是父組件向子組件傳遞消息的一種方式。
在子組件中有一個(gè) this.$parent 和 this.$root 可以用來(lái)方法父組件和根實(shí)例。不過(guò),現(xiàn)在我們應(yīng)該避免這么做。因?yàn)榻M件本身就是為了封裝獨(dú)立的邏輯,如果又去直接訪問(wèn)父組件的數(shù)據(jù)就破壞了組件的封裝性。
所以我們應(yīng)該還是應(yīng)該通過(guò)父組件向子組件傳遞 props 的方式來(lái)通信。

當(dāng)然 props 其實(shí)只能做回調(diào)。在 React 中就探討過(guò)這個(gè)問(wèn)題,React 的做法就是通過(guò) props 來(lái)做,傳一個(gè)回調(diào)函數(shù)給子組件。其實(shí)我不是很喜歡這種把回調(diào)函數(shù)傳來(lái)傳去的方式,我更喜歡的是事件的方式。Vue 中子組件可以通過(guò)通過(guò)事件和父組件進(jìn)行通信的。向父組件發(fā)消息是通過(guò) this.$dispatch,而向子組件發(fā)送消息是通過(guò) this.$boardcast,這里都是向所有的父親和孩子發(fā)送消息,但是一旦執(zhí)行一個(gè)回調(diào)之后就會(huì)停止,除非這個(gè)回調(diào)函數(shù)顯式返回了 true。

我們把之前的Todo List拆成不同的組件來(lái)實(shí)現(xiàn),這樣可以體驗(yàn)下如何進(jìn)行組件的雙向通信,我們拆分出兩個(gè)組件,分別是 List 和 Form 。

Form 負(fù)責(zé)處理用戶輸入,并在提交表單的時(shí)候向父組件發(fā)送一個(gè) add 消息,代碼如下:

var Form = Vue.extend({
 props: {
 username: {
 type: String,
 default: "Unnamed"
 }
 },
 data: function() {
 return {
 input: "",
 };
 },
 template: `
 <h1>{{username}}'s Todo List</h1>
 <form v-on:submit="add" v-on:submit.prevent>
 <input type="text" v-model="input"/>
 <input type="submit" value='add' />
 </form>
 `,
 methods: {
 add: function() {
 this.$dispatch("add", this.input); //這里就是向父組件發(fā)送消息
 this.input = "";
 }
 }
});

 List 只負(fù)責(zé)展示列表和處理用戶勾選操作,它接收到 add 消息之后會(huì)在自己上添加一個(gè)條目:

var List = Vue.extend({
 template: `
 <ul>
 <li v-for='todo in list'>
 <label v-bind:class="{ done : todo.done }" >
  <input type="checkbox" v-model="todo.done"/>
  {{todo.title}}
 </label>
 </li>
 </ul>`,
 props: {
 initList: {
 type: Array
 }
 },
 data: function() {
 return {
 list: []
 }
 },
 events: {
 add: function(input) {
 if(!input) return false;
 this.list.unshift({
 title: input,
 done: false
 });
 }
 }
});

 然后,因?yàn)檫@是兩個(gè)組件,當(dāng)然需要一個(gè) Vue 實(shí)例來(lái)引導(dǎo)啟動(dòng),我們的實(shí)例如下:

var vm = new Vue({
 el: "#todo",
 components: {
 "todo-form": Form,
 "todo-list": List
 },
 events: {
 add: function(input) {
 this.$broadcast("add", input);
 }
 }
});

 注意,其實(shí) Form 和 List 在邏輯上是平級(jí)的組件,所以他們沒(méi)有父子關(guān)系,他們共同都是 vm 的孩子。這里 vm 接到 Form 的消息之后會(huì)轉(zhuǎn)發(fā)給 List。

html 代碼就更簡(jiǎn)單了:

 <div id="todo">
 <todo-form username='Lily'></todo-form>
 <todo-list></todo-list>
 </div>

 Slot

通過(guò) Slot 可以實(shí)現(xiàn)把父組件渲染出來(lái)的HTML插入到子組件中,目前還不清楚什么時(shí)候會(huì)需要這樣做,而且這么做對(duì)子組件的侵入性太大。

動(dòng)態(tài)切換組件

這個(gè)功能感覺(jué)有點(diǎn)多余,感覺(jué)很多情況下我們應(yīng)該是通過(guò)邏輯代碼來(lái)實(shí)現(xiàn)切換,而不是通過(guò)Vue內(nèi)置的動(dòng)態(tài)組件來(lái)切換。不過(guò)用來(lái)實(shí)現(xiàn)一個(gè)類(lèi)似 tab 切換的功能還是很方便的。

我們這里給 Todo List 增加一個(gè) about 頁(yè)面。那么首先我們需要把 vm 改成一個(gè)組件,這個(gè)組件叫 Todo,它就是整個(gè) Todo 頁(yè)面:

var Todo = Vue.extend({
 template: `
 <div id="todo">
 <todo-form username='Lily'></todo-form>
 <todo-list></todo-list>
 <slot>not show</slot>
 </div>
 `,
 components: {
 "todo-form": Form,
 "todo-list": List
 },
 events: {
 add: function(input) {
 this.$broadcast("add", input);
 }
 }
});

 其實(shí)改動(dòng)就第一行。

然后我們需要?jiǎng)?chuàng)建一個(gè) About 組件:

var About = Vue.extend({
 template: `
 <div id="about">
 <p>About Todo List V0.1.0</p>
 <p>Content here</p>
 </div>`
});

 接下來(lái)是重點(diǎn)了,我們要?jiǎng)?chuàng)建一個(gè)實(shí)例 vm,這vm要負(fù)責(zé)切換這兩個(gè)頁(yè)面:

var vm = new Vue({
 el: "body",
 data: {
 currentView: "todo"
 },
 components: {
 "todo": Todo,
 "about": About
 }
});

 這里我們定義了一個(gè) currentView 字段,當(dāng)然可以是任意名稱(chēng),然后通過(guò)特殊的 component 標(biāo)簽來(lái)進(jìn)行組件切換:

<component :is="currentView"></component>
 <ul>
 <li><label><input type="radio" name='page' value='todo' v-model='currentView'> Home</label></li>
 <li><label><input type="radio" name='page' value='about' v-model='currentView'> About</label></li>
 </ul>

 上面的代碼有兩處需要注意:
 •通過(guò) component這個(gè)特殊標(biāo)簽,然后用 :is 屬性來(lái)進(jìn)行組件的切換。
 •radio 通過(guò)雙向綁定來(lái)修改 currentView 字段,從而實(shí)現(xiàn)點(diǎn)擊之后就可以進(jìn)行切換。

數(shù)據(jù)綁定的實(shí)現(xiàn)原理

Vue 把雙向綁定稱(chēng)作 reactive,可以翻譯為響應(yīng)式數(shù)據(jù)綁定。內(nèi)部是通過(guò) ES5 定義的 getter 和 setter 方法實(shí)現(xiàn)的,所以不支持 IE8 及以下瀏覽器,這種實(shí)現(xiàn)方式有兩個(gè)容易犯錯(cuò)的地方:
 •如果在 data 上直接添加和刪除屬性是無(wú)法被檢測(cè)到的,一般刪除是不會(huì)的,但是可能會(huì)動(dòng)態(tài)添加,這個(gè)時(shí)候應(yīng)該通過(guò) vm.$set(“name”, value) 的方式來(lái)添加。
 •無(wú)法檢測(cè)到對(duì)象內(nèi)部的變化,也就是只能檢測(cè) data 的屬性變化,如果 data.a 是一個(gè)對(duì)象,那么 data.a.b = 1 這種變化是無(wú)法被檢測(cè)到的。這種情況下應(yīng)該創(chuàng)建一個(gè)新的對(duì)象并賦值給 data.a 就行了。 

異步更新機(jī)制

Vue 對(duì)DOM的更新是異步的! 這個(gè)異步是在一個(gè)異步隊(duì)列中進(jìn)行的,不過(guò)這個(gè)異步隊(duì)列會(huì)在當(dāng)前的 Event Loop 中執(zhí)行完,所以如果修改了 Data 立刻去DOM中做查詢操作是不對(duì)的,這個(gè)時(shí)候DOM還沒(méi)有更新,正確的做法是這樣做:

vm.msg = 'new message' // change data
vm.$el.textContent === 'new message' // false
Vue.nextTick(function () {
 vm.$el.textContent === 'new message' // true
})

 或者這樣:

vm.$nextTick(function () {
 this.$el.textContent === 'new message' // true
})

 花了半天時(shí)間才看完組件,下面應(yīng)該去看一下另一個(gè)重點(diǎn): Directive

本文已被整理到了《Vue.js前端組件學(xué)習(xí)教程》,歡迎大家學(xué)習(xí)閱讀。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 用Vue.extend構(gòu)建消息提示組件的方法實(shí)例

    用Vue.extend構(gòu)建消息提示組件的方法實(shí)例

    本篇文章主要介紹了用Vue.extend構(gòu)建消息提示組件的方法實(shí)例,具有一定的參考價(jià)值,有興趣的可以了解一下
    2017-08-08
  • vuex如何在非組件中調(diào)用mutations方法

    vuex如何在非組件中調(diào)用mutations方法

    這篇文章主要介紹了vuex如何在非組件中調(diào)用mutations方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • vue實(shí)現(xiàn)表單未編輯或未保存離開(kāi)彈窗提示功能

    vue實(shí)現(xiàn)表單未編輯或未保存離開(kāi)彈窗提示功能

    這篇文章主要介紹了vue實(shí)現(xiàn)表單未編輯或未保存離開(kāi)彈窗提示功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-04-04
  • vue數(shù)據(jù)初始化initState的實(shí)例詳解

    vue數(shù)據(jù)初始化initState的實(shí)例詳解

    Vue 實(shí)例在建立的時(shí)候會(huì)運(yùn)行一系列的初始化操作,而在這些初始化操作里面,和數(shù)據(jù)綁定關(guān)聯(lián)最大的是 initState。這篇文章主要介紹了vue數(shù)據(jù)初始化--initState,需要的朋友可以參考下
    2019-04-04
  • vue2.0 移動(dòng)端實(shí)現(xiàn)下拉刷新和上拉加載更多的示例

    vue2.0 移動(dòng)端實(shí)現(xiàn)下拉刷新和上拉加載更多的示例

    本篇文章主要介紹vue2.0 移動(dòng)端實(shí)現(xiàn)下拉刷新和上拉加載更多的示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-04-04
  • Vue父子組件屬性傳遞實(shí)現(xiàn)方法詳解

    Vue父子組件屬性傳遞實(shí)現(xiàn)方法詳解

    這篇文章主要介紹了Vue父子組件屬性傳遞實(shí)現(xiàn)方法,我們主要從案例出發(fā),用Vue3的寫(xiě)法寫(xiě)父子組件之間的屬性傳遞,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2023-02-02
  • vue3的內(nèi)置組件匯總

    vue3的內(nèi)置組件匯總

    本文主要介紹了vue3的內(nèi)置組件匯總,詳細(xì)的介紹了Fragment,Teleport,Suspense三個(gè)組件的使用,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-01-01
  • Vue使用v-viewer插件實(shí)現(xiàn)圖片預(yù)覽和縮放和旋轉(zhuǎn)等功能(推薦)

    Vue使用v-viewer插件實(shí)現(xiàn)圖片預(yù)覽和縮放和旋轉(zhuǎn)等功能(推薦)

    v-viewer是一個(gè)基于viewerjs封裝的vue圖片預(yù)覽組件,有預(yù)覽縮放拉伸旋轉(zhuǎn)切換拖拽等功能,支持配置化,這篇文章主要介紹了Vue使用v-viewer插件實(shí)現(xiàn)圖片預(yù)覽和縮放和旋轉(zhuǎn)等功能,需要的朋友可以參考下
    2023-02-02
  • vue?父子組件共用mixins的注意點(diǎn)

    vue?父子組件共用mixins的注意點(diǎn)

    這篇文章主要介紹了vue?父子組件共用mixins的注意點(diǎn),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • vue實(shí)現(xiàn)聯(lián)動(dòng)選擇

    vue實(shí)現(xiàn)聯(lián)動(dòng)選擇

    這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)聯(lián)動(dòng)選擇,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03

最新評(píng)論