国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

vue組件三大核心概念圖文詳解

2019-11-19 11:26:00
字體:
供稿:網(wǎng)友

前言

本文主要介紹屬性、事件和插槽這三個vue基礎(chǔ)概念、使用方法及其容易被忽略的一些重要細節(jié)。如果你閱讀別人寫的組件,也可以從這三個部分展開,它們可以幫助你快速了解一個組件的所有功能。

本文的代碼請猛戳 github博客 ,紙上得來終覺淺,大家動手多敲敲代碼!

一、屬性

1.自定義屬性props

prop 定義了這個組件有哪些可配置的屬性,組件的核心功能也都是它來確定的。寫通用組件時,props 最好用對象的寫法,這樣可以針對每個屬性設(shè)置類型、默認值或自定義校驗屬性的值,這點在組件開發(fā)中很重要,然而很多人卻忽視,直接使用 props 的數(shù)組用法,這樣的組件往往是不嚴謹?shù)摹?/p>

// 父組件 <props name='屬性'      :type='type'      :is-visible="false"      :on-change="handlePropChange"      :list=[22,33,44]      title="屬性Demo"      class="test1"      :class="['test2']"      :style="{ marginTop: '20px' }" //注意:style 的優(yōu)先級是要高于 style      style="margin-top: 10px"> </props>// 子組件 props: {  name: String,  type: {  //從父級傳入的 type,它的值必須是指定的 'success', 'warning', 'danger'中的一個,如果傳入這三個以外的值,都會拋出一條警告   validator: (value) => {    return ['success', 'warning', 'danger'].includes(value)   }  },  onChange: {  //對于接收的數(shù)據(jù),可以是各種數(shù)據(jù)類型,同樣也可以傳遞一個函數(shù)   type: Function,   default: () => { }  },  isVisible: {   type: Boolean,   default: false  },  list: {   type: Array,   // 對象或數(shù)組默認值必須從一個工廠函數(shù)獲取   default: () => []  } }

從上面的例中,可以得出props 可以顯示定義一個或一個以上的數(shù)據(jù),對于接收的數(shù)據(jù),可以是各種數(shù)據(jù)類型, 同樣也可以傳遞一個函數(shù)。

2.inheritAttrs

這是2.4.0 新增的一個API,默認情況下父作用域的不被認作 props 的特性綁定將會“回退”且作為普通的 HTML 特性應(yīng)用在子組件的根元素上??赏ㄟ^設(shè)置 inheritAttrs 為 false,這些默認行為將會被去掉。注意: 這個選項不影響 class 和 style 綁定 。

上個例中,title屬性沒有在子組件中props中聲明,就會默認掛在子組件的根元素上,如下圖所示:

3. data與props區(qū)別

相同點

兩者選項里都可以存放各種類型的數(shù)據(jù),當行為操作改變時,所有行為操作所用到和模板所渲染的數(shù)據(jù)同時都會發(fā)生同步變化。

不同點

data 被稱之為動態(tài)數(shù)據(jù),在各自實例中,在任何情況下,我們都可以隨意改變它的 數(shù)據(jù)類型和數(shù)據(jù)結(jié)構(gòu) ,不會被任何環(huán)境所影響。

props 被稱之為靜態(tài)數(shù)據(jù),在各自實例中,一旦在初始化被定義好類型時,基于 Vue 是單向數(shù)據(jù)流,在數(shù)據(jù)傳遞時始終不能改變它的數(shù)據(jù)類型,而且不允許在子組件中直接操作 傳遞過來的props數(shù)據(jù),而是需要通過別的手段,改變傳遞源中的數(shù)據(jù)。至于如何改變,我們接下去詳細介紹:

4.單向數(shù)據(jù)流

這個概念出現(xiàn)在組件通信。props的數(shù)據(jù)都是通過父組件或者更高層級的組件數(shù)據(jù)或者字面量的方式進行傳遞的,不允許直接操作改變各自實例中的props數(shù)據(jù),而是需要通過別的手段,改變傳遞源中的數(shù)據(jù)。那如果有時候我們想修改傳遞過來的prop,有哪些辦法呢?

方法1:過渡到 data 選項中

在子組件的 data 中拷貝一份 prop,data 是可以修改的

export default { props: {  type: String }, data () {  return {   currentType: this.type  } }}

在 data 選項里通過 currentType接收 props中type數(shù)據(jù),相當于對 currentType= type進行一個賦值操作,不僅拿到了 currentType的數(shù)據(jù),而且也可以改變 currentType數(shù)據(jù)。

方法2:利用計算屬性

export default { props: {  type: String }, computed: {  normalizedType: function () {   return this.type.toUpperCase();  } }}

以上兩種方法雖可以在子組件間接修改props的值,但如果子組件想修改數(shù)據(jù)并且同步更新到父組件,卻無濟于事。在一些情況下,我們可能會需要對一個 prop 進行『雙向綁定』,此時就推薦以下這兩種方法:

方法3:使用.sync

// 父組件<template> <div class="hello">  <div>   <p>父組件msg:{{ msg }}</p>   <p>父組件數(shù)組:{{ arr }}</p>  </div>  <button @click="show = true">打開model框</button>  <br />  <demo :show.sync="show" :msg.sync="msg" :arr="arr"></demo> </div></template><script>import Demo from "./demo.vue";export default { name: "Hello", components: {  Demo }, data() {  return {   show: false,   msg: "模擬一個model框",   arr: [1, 2, 3]  }; }};</script>// 子組件<template> <div v-if="show" class="border">  <div>子組件msg:{{ msg }}</div>  <div>子組件數(shù)組:{{ arr }}</div>  <button @click="closeModel">關(guān)閉model框</button>  <button @click="$emit('update:msg', '浪里行舟')">   改變文字  </button>  <button @click="arr.push('前端工匠')">改變數(shù)組</button>  </div></template><script>export default { props: {  msg: {   type: String  },  show: {   type: Boolean  },  arr: {   type: Array //在子組件中改變傳遞過來數(shù)組將會影響到父組件的狀態(tài)  } }, methods: {  closeModel() {   this.$emit("update:show", false);  } }};

父組件向子組件 props 里傳遞了 msg 和 show 兩個值,都用了.sync 修飾符,進行雙向綁定。

不過.sync 雖好,但也有限制,比如:

1) 不能和表達式一起使用 (如 v-bind:title.sync="doc.title + '!'" 是無效的);

2) 不能用在字面量對象上 (如 v-bind.sync="{ title: doc.title }" 是無法正常工作的)。

方法4:將父組件中的數(shù)據(jù)包裝成對象傳遞給子組件

這是因為在 JavaScript 中對象和數(shù)組是通過引用傳入的,所以對于一個數(shù)組或?qū)ο箢愋偷?prop 來說,在子組件中改變這個對象或數(shù)組本身將會影響到父組件的狀態(tài)。比如上例中在子組件中修改父組件傳遞過來的數(shù)組arr,從而改變父組件的狀態(tài)。

5.向子組件中傳遞數(shù)據(jù)時加和不加 v-bind?

對于字面量語法和動態(tài)語法,初學者可能在父組件模板中向子組件中傳遞數(shù)據(jù)時到底加和不加 v-bind 會感覺迷惑。

v-bind:msg = 'msg'

這是通過 v-bind 進行傳遞數(shù)據(jù)并且傳遞的數(shù)據(jù)并不是一個字面量,雙引號里的解析的是一個表達式,同樣也可以是實例上定義的數(shù)據(jù)和方法(其實就是引用一個變量)。

msg='浪里行舟'

這種在沒有 v-bind 的模式下只能傳遞一個字面量,這個字面量只限于 String 類量,字符串類型。那如果想通過字面量進行數(shù)據(jù)傳遞時, 如果想傳遞非String類型,必須props名前要加上v-bind ,內(nèi)部通過實例尋找,如果實例方?jīng)]有此屬性和方法,則默認為對應(yīng)的數(shù)據(jù)類型。

:msg='11111' //Number :msg='true' //Bootlean :msg='()=>{console.log(1)}' //Function:msg='{a:1}' //Object

二、事件

 1.事件驅(qū)動與數(shù)據(jù)驅(qū)動

用原生JavaScript事件驅(qū)動通常是這樣的流程:

先通過特定的選擇器查找到需要操作的節(jié)點 -> 給節(jié)點添加相應(yīng)的事件監(jiān)聽 然后用戶執(zhí)行某事件(點擊,輸入,后退等等) -> 調(diào)用 JavaScript 來修改節(jié)點

這種模式對業(yè)務(wù)來說是沒有什么問題,但是從開發(fā)成本和效率來說會比較不理想,特別是在業(yè)務(wù)系統(tǒng)越來越龐大的時候。另一方面,找節(jié)點和修改節(jié)點這件事,效率本身就很低,因此出現(xiàn)了數(shù)據(jù)驅(qū)動模式。

Vue的一個核心思想是數(shù)據(jù)驅(qū)動。所謂數(shù)據(jù)驅(qū)動,是指視圖是由數(shù)據(jù)驅(qū)動生成的,我們對視圖的修改,不會直接操作 DOM,而是通過修改數(shù)據(jù),其流程如下:

用戶執(zhí)行某個操作 -> 反饋到 VM 處理(可以導致 Model 變動) -> VM 層改變,通過綁定關(guān)系直接更新頁面對應(yīng)位置的數(shù)據(jù)

可以簡單地理解:數(shù)據(jù)驅(qū)動不是操作節(jié)點的,而是通過虛擬的抽象數(shù)據(jù)層來直接更新頁面。主要就是因為這一點,數(shù)據(jù)驅(qū)動框架才得以有較快的運行速度(因為不需要去折騰節(jié)點),并且可以應(yīng)用到大型項目。

2.修飾符事件

Vue事件分為普通事件和修飾符事件,這里我們主要介紹修飾符事件。

Vue 提供了大量的修飾符封裝了這些過濾和判斷,讓開發(fā)者少寫代碼,把時間都投入的業(yè)務(wù)、邏輯上,只需要通過一個修飾符去調(diào)用。我們先來思考這樣問題:怎樣給這個自定義組件 custom-component 綁定一個原生的 click 事件?

<custom-component>組件內(nèi)容</custom-component>

如果你的回答是 <custom-component @click="xxx"> ,那就錯了。這里的 @click 是自定義事件 click,并不是原生事件 click。綁定原生的 click 是這樣的:

<custom-component @click.native="xxx">組件內(nèi)容</custom-component>

實際開發(fā)過程中離不開事件修飾符,常見事件修飾符有以下這些:

表單修飾符

1).lazy

在默認情況下, v-model 在每次  input 事件觸發(fā)后將輸入框的值與數(shù)據(jù)進行同步 。你可以添加  lazy 修飾符,從而轉(zhuǎn)變?yōu)槭褂?nbsp; change 事件進行同步。適用于輸入完所有內(nèi)容后,光標離開才更新視圖的場景。

2).trim

如果要自動過濾用戶輸入的首尾空白字符,可以給 v-model 添加 trim 修飾符:

<input v-model.trim="msg">

這個修飾符可以過濾掉輸入完密碼不小心多敲了一下空格的場景。需要注意的是, 它只能過濾首尾的空格 !首尾,中間的是不會過濾的。

3).number

如果想自動將用戶的輸入值轉(zhuǎn)為數(shù)值類型,可以給 v-model 添加 number 修飾符:

<input v-model.number="value" type="text" />

從上面例子,可以得到如果你先輸入數(shù)字,那它就會限制你輸入的只能是數(shù)字。如果你先輸入字符串,那它就相當于沒有加.number

事件修飾符

<!-- 阻止單擊事件繼續(xù)傳播 --><a v-on:click.stop="doThis"></a><!-- 提交事件不再重載頁面 --><form v-on:submit.prevent="onSubmit"></form><!-- 修飾符可以串聯(lián) --><a v-on:click.stop.prevent="doThat"></a>

三、插槽

插槽分為普通插槽和作用域插槽,其實兩者很類似,只不過作用域插槽可以接受子組件傳遞過來的參數(shù)。

1.作用域插槽

我們不妨通過一個todolist的例子來了解作用域插槽。如果當item選中后,文字變?yōu)辄S色(如下圖所示),該如何實現(xiàn)呢?

// 父組件<template> <div class="toList">  <input v-model="info" type="text" /> <button @click="addItem">添加</button>  <ul>   <TodoItem v-for="(item, index) in listData" :key="index">    <template v-slot:item="itemProps"> // 這是個具名插槽    // 其中itemProps的值就是子組件傳遞過來的對象     <span      :style="{       fontSize: '20px',       color: itemProps.checked ? 'yellow' : 'blue'      }"      >{{ item }}</span     >    </template>   </TodoItem>  </ul> </div></template><script>import TodoItem from "./TodoItem";export default { components: {  TodoItem }, data() {  return {   info: "",   listData: []  }; }, methods: {  addItem() {   this.listData.push(this.info);   this.info = "";  } }};</script>// 子組件<template> <div>  <li class="item">   <input v-model="checked" type="checkbox" />   <slot name="item" :checked="checked"></slot> // 將checked的值傳遞給父組件  </li> </div></template><script>export default { data() {  return {   checked: false  }; }};</script>

值得注意:v-bind:style 的對象語法十分直觀――看著非常像 CSS,但其實是一個 JavaScript 對象。CSS 屬性名可以用駝峰式 (camelCase) 或短橫線分隔 (kebab-case,記得用引號括起來) 來命名。

2.v-slot新語法

在 2.6.0 中,我們?yōu)榫呙宀酆妥饔糜虿宀垡肓艘粋€新的統(tǒng)一的語法 (即 v-slot 指令)。它取代了  slot 和  slot-scope 。

我們通過一個例子介紹下默認插槽、具名插槽和作用域插槽的新語法:

// 父組件<template> <div class="helloSlot">  <h2>2.6 新語法</h2>  <SlotDemo>   <p>默認插槽:default slot</p>   <template v-slot:title>    <p>具名插槽:title slot1</p>    <p>具名插槽:title slot2</p>   </template>   <template v-slot:item="props">    <p>作用域插槽:item slot-scope {{ props }}</p>   </template>  </SlotDemo> </div></template><script>import Slot from "./slot";export default { components: {  SlotDemo: Slot }};</script>// 子組件<template> <div>  <slot />  <slot name="title" />  <slot name="item" :propData="propData" /> </div></template><script>export default { data() {  return {   propData: {    value: "浪里行舟"   }  }; }};</script>

總結(jié)

以上所述是小編給大家介紹的vue組件三大核心概念圖文詳解,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對武林網(wǎng)網(wǎng)站的支持!
如果你覺得本文對你有幫助,歡迎轉(zhuǎn)載,煩請注明出處,謝謝!

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 奎屯市| 桐梓县| 锦州市| 泸定县| 丰台区| 茌平县| 新营市| 云安县| 台南市| 佛教| 石嘴山市| 沧源| 长白| 黄平县| 乃东县| 梅州市| 咸宁市| 梨树县| 淮安市| 思茅市| 建瓯市| 开远市| 新干县| 田阳县| 大荔县| 沧源| 台中市| 西城区| 铜梁县| 石林| 云南省| 龙州县| 巩义市| 富裕县| 伊通| 宝清县| 宜春市| 定南县| 德阳市| 招远市| 德阳市|