Vue組件

測(cè)試代碼

創(chuàng)鍵組件

兩種方式:
方法一:使用Vue.extend({})

var component = Vue.extend({
  template: '<div>component</div>'
});
// 里面還可以添加其他的屬性

方法二:使用字面量

 var component = {
   template: '<div>component</div>'
}

注冊(cè)組件

全局注冊(cè)
語法:

Vue.component('my-component', {
  // 選項(xiàng)
})

示例:

// 創(chuàng)建組件
var component = {template: '<div>component</div>'}
// 全局注冊(cè)組件

Vue.component('my-component', component);

局部注冊(cè)

// 創(chuàng)建組件
var component = {template: '<div>component</div>'}
// 在 Vue組件實(shí)例內(nèi)注冊(cè)component組件,該組件只能在該實(shí)例中使用
var vm = new Vue({
            el: '#app',
            components: {
                'mycomponent ': component ,
            }
        })

注意點(diǎn):

  • HTML 特性是不區(qū)分大小寫的。所以笛质,當(dāng)使用的不是字符串模版陆错,camelCased (駝峰式) 命名的 prop 需要轉(zhuǎn)換為相對(duì)應(yīng)的 kebab-case (短橫線隔開式) 命名:
Vue.component('child', {
  // camelCase in JavaScript
  props: ['myMessage'],      // 這里使用的是駝峰式命名
  template: '<span>{{ myMessage }}</span>'
})
// 在下面的HTML文件中引用時(shí),需要改為kebab-case的形式剪侮,也就是短橫線隔開
<child my-message="hello!"></child>

如果你使用字符串模版汤善,則沒有這些限制。

注意(謹(jǐn)記):在HTML中票彪,屬性是不區(qū)分大小寫的红淡,例如:class、Class或CLASS都是表示class降铸,因此在旱,當(dāng)在Vue中使用props向子組件傳遞數(shù)據(jù)時(shí),如果props是駝峰式命名推掸,那么在HTML文件中使用時(shí)桶蝎,需要修改為kebab-case(短橫線隔開式或稱為烤肉串)的形式,否則谅畅,Vue將會(huì)無法解析

使用props傳遞數(shù)據(jù)

Vue.component('child', {
  // 聲明 props
  props: ['message'],
  // 就像 data 一樣登渣,prop 可以用在模板內(nèi)
  // 同樣也可以在 vm 實(shí)例中像“this.message”這樣使用
  template: '<span>{{ message }}</span>'
})
// 通過下面這種方式傳遞數(shù)據(jù)
<child message="hello!"></child>

動(dòng)態(tài)prop

將父組件的數(shù)據(jù)通過v-bind綁定到子組件上,與綁定HTML特性是一樣的毡泻;每當(dāng)父組件的數(shù)據(jù)變化都會(huì)反映到子組件上

<div>
  <input v-model="parentMsg">
  <br>
  <child v-bind:my-message="parentMsg"></child>
</div>

字面量語法 VS 動(dòng)態(tài)語法

初學(xué)者常犯的一個(gè)錯(cuò)誤是使用字面量語法傳遞數(shù)值:

<!-- 傳遞了一個(gè)字符串 "1" -->
<comp some-prop="1"></comp>

因?yàn)樗且粋€(gè)字面 prop胜茧,它的值是字符串 "1" 而不是 number。如果想傳遞一個(gè)實(shí)際的 number仇味,需要使用 v-bind呻顽,從而讓它的值被當(dāng)作 JavaScript 表達(dá)式計(jì)算:

<!-- 傳遞實(shí)際的 number -->
<comp v-bind:some-prop="1"></comp>

通過v-bind:some-props="1"傳遞的是一個(gè)number,而通過some-prop="1"傳遞的是一個(gè) 字符串

props數(shù)據(jù)校驗(yàn)

Vue.component("example", {
  props: {
    // 基礎(chǔ)類型檢測(cè) (`null` 意思是任何類型都可以)
    propA: Number,
    // 多種類型
    propB: [String, Number],
    // 必傳且是字符串
    propC: {
      type: String,
      required: true
    },
    // 數(shù)字丹墨,有默認(rèn)值
    propD: {
      type: Number,
      default: 100
    },
    // 數(shù)組/對(duì)象的默認(rèn)值應(yīng)當(dāng)由一個(gè)工廠函數(shù)返回
    propE: {
      type: Object,
      default: function () {
        return { message: 'hello' }
      }
    },
    // 自定義驗(yàn)證函數(shù)
    propF: {
      validator: function (value) {
        return value > 10
      }
    }
  }
});

注意:props會(huì)在組件實(shí)例創(chuàng)建之前進(jìn)行校驗(yàn)廊遍,所以在default、validator函數(shù)里贩挣,諸如:data, computedmethods等實(shí)例屬性都無法使用

非props特性傳遞

在Vue中喉前,在大多數(shù)情況下,傳遞給組件的值會(huì)覆蓋組件本身就設(shè)定的值王财,例如傳遞type=large會(huì)覆蓋組件上的type=small卵迂,且有可能破壞該組件,但是搪搏,對(duì)于class和style特性在傳遞時(shí)狭握,不會(huì)發(fā)生覆蓋,只會(huì)合并疯溺,假如組件上class=one论颅,又傳遞class=two哎垦,則最終組件的class= one two

原生事件監(jiān)聽

通過在事件上添加.native可以增加對(duì)原生事件的監(jiān)聽恃疯,如下:
`<my-component v-on:click.native="doTheThing"></my-component>

.sync修飾符

一般情況下漏设,子組件對(duì)props的修改無法更新到父組件中,但是在2.3.0之后的版本中添加了.sync修飾符今妄,可以在子組件上更新props郑口,同時(shí)同步到父組件上,如下:
<comp :foo.sync="bar"></comp>
上面這段代碼會(huì)被擴(kuò)展為盾鳞,如下代碼:
<comp :foo="bar" @update:foo=" val => bar = val"></comp>
如果子組件需要更新犬性,則按如下方式即可:
this.$emit('update:foo', newValue);

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

prop綁定數(shù)據(jù)是單向的,當(dāng)父組件的屬性變化時(shí)腾仅,將傳導(dǎo)給子組件乒裆,但是不會(huì)反過來。這是為了防止子組件無意修改了父組件的狀態(tài)——這會(huì)讓應(yīng)用的數(shù)據(jù)流難以理解推励。

另外鹤耍,每次父組件更新時(shí),子組件的所有 prop 都會(huì)更新為最新值验辞。這意味著你不應(yīng)該在子組件內(nèi)部改變 prop稿黄。如果你這么做了,Vue 會(huì)在控制臺(tái)給出警告

使用插槽分發(fā)內(nèi)容(slot)

單個(gè)插槽

注意幾點(diǎn):

  1. 當(dāng)子組件沒有slot插槽時(shí)跌造,父組件調(diào)用子組件時(shí)杆怕,包含的內(nèi)容都會(huì)丟失
  2. 當(dāng)父組件調(diào)用子組件沒有包含內(nèi)容時(shí),顯示slot中的內(nèi)容

示例1:子組件沒有slot插槽時(shí)

<div>
  <h1>我是父組件的標(biāo)題</h1>
  <c-child>
    <p>這是一些初始內(nèi)容</p>
    <p>這是更多的初始內(nèi)容</p>
  </c-child>
</div>

// 子組件child的模板鼻听,在該組件中沒有slot财著,因此父組件調(diào)用子組件時(shí)包含的內(nèi)容不會(huì)顯示出來
<template id="child">
  <div>
    <h2>我是子組件的標(biāo)題</h2>
  </div>
</template>

Vue.component("c-child", {
   template: "#child"
});

new Vue({
   el: "#app-1"
});

上面代碼輸出結(jié)果如下:


沒有slot的顯示效果

當(dāng)在child組件中添加slot,修改為如下代碼:

<template id="child">
  <div>
    <h2>我是子組件的標(biāo)題</h2>
    <slot></slot>
  </div>
</template>

顯示結(jié)果如下:

添加slot后撑碴,父組件調(diào)用子組件時(shí)包含的內(nèi)容顯示出來了

示例2:當(dāng)父組件調(diào)用子組件時(shí),沒有包含內(nèi)容朝墩,則顯示slot中的內(nèi)容

<div>
  <h1>我是父組件的標(biāo)題</h1>
  <c-child>
  </c-child>
</div>

// 子組件child的模板醉拓,在該組件中沒有slot,因此父組件調(diào)用子組件時(shí)包含的內(nèi)容不會(huì)顯示出來
<template id="child">
  <div>
    <h2>我是子組件的標(biāo)題</h2>
    <slot>顯示slot內(nèi)容</slot>
  </div>
</template>

Vue.component("c-child", {
   template: "#child"
});

new Vue({
   el: "#app-1"
});

如下:


顯示slot內(nèi)容

具名插槽

<slot> 元素可以用一個(gè)特殊的屬性 name 來配置如何分發(fā)內(nèi)容收苏。多個(gè)插槽可以有不同的名字亿卤。具名插槽將匹配內(nèi)容片段中有對(duì)應(yīng) slot 特性的元素。

也就是說鹿霸,在子組件中可以為slot通過name屬性定義名字排吴,然后在父組件調(diào)用子組件的時(shí)候,可以通過slot="header"來為子組件中name="header"的slot指定內(nèi)容懦鼠,假如指定的name 在子組件中沒有找到钻哩,那么該內(nèi)容將會(huì)被拋棄

// 子組件模板
<div class="container">
  <header>
    <slot name="header"></slot>
  </header>
  <main>
    <slot></slot>
  </main>
  <footer>
    <slot name="footer"></slot>
  </footer>
</div>

// 父組件
<app-layout>
  <h1 slot="header">這里可能是一個(gè)頁面標(biāo)題</h1>
  <p>主要內(nèi)容的一個(gè)段落屹堰。</p>
  <p>另一個(gè)主要段落。</p>
  <p slot="footer">這里有一些聯(lián)系信息</p>
</app-layout>

最終的渲染結(jié)果如下:

<div class="container">
  <header>
    <h1>這里可能是一個(gè)頁面標(biāo)題</h1>
  </header>
  <main>
    <p>主要內(nèi)容的一個(gè)段落街氢。</p>
    <p>另一個(gè)主要段落扯键。</p>
  </main>
  <footer>
    <p>這里有一些聯(lián)系信息</p>
  </footer>
</div>

該特性非常有用

作用域插槽

作用域插槽是一種特殊類型的插槽,用作一個(gè)替換已渲染元素的 (能被傳遞數(shù)據(jù)的) 可重用模板珊肃。
在子組件中荣刑,只需將數(shù)據(jù)傳遞到插槽,就像你將 props 傳遞給組件一樣:

<div class="child">
  <slot text="hello from child"></slot>
</div>

在父級(jí)中伦乔,具有特殊屬性 scope 的 <template> 元素必須存在厉亏,表示它是作用域插槽的模板。scope 的值對(duì)應(yīng)一個(gè)臨時(shí)變量名烈和,此變量接收從子組件中傳遞的 props 對(duì)象:

<div class="parent">
  <child>
    <template scope="props">
      <span>hello from parent</span>
      <span>{{ props.text }}</span>
    </template>
  </child>
</div>

以上代碼渲染結(jié)果:

<div class="parent">
  <div class="child">
    <span>hello from parent</span>
    <span>hello from child</span>
  </div>
</div>

一個(gè)示例:

image.png

參考:Vue作用域插槽的使用

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

Vue中的動(dòng)態(tài)組件需要指定一個(gè)掛載點(diǎn)爱只,在該掛載點(diǎn)之下,可以動(dòng)態(tài)的切換組件

用法:
通過<component v-bind:is="currentView"></component> 來調(diào)用組件斥杜,當(dāng)currentView改變時(shí)虱颗,就切換組件,

實(shí)例:

var vm = new Vue({
  el: "#example",
  data: {
     currentView: 'home'
  },
  // 在該實(shí)例下的組件
  components: {
      home: { /* home組件 */},
      posts: { /* posts組件 */ },
  }
});

// 當(dāng)vm.currentView改變時(shí)就進(jìn)行組件切換蔗喂,組件就在當(dāng)前位置進(jìn)行顯示
<component v-bind:is="currentView">
  <!-- 組件在 vm.currentview 變化時(shí)改變忘渔! -->
</component>

在使用動(dòng)態(tài)組件進(jìn)行切換時(shí),被切換出來的組件會(huì)被消除缰儿,這樣就存在一個(gè)問題:當(dāng)重復(fù)的切換組件時(shí)畦粮,組件不斷地被消除,然后又重建乖阵,導(dǎo)致性能很差宣赔,這時(shí)可以使用 keep-alive 來使被切換的組件保持在內(nèi)存中,避免了重新渲染瞪浸,keep-alive的用法如下:

// 只需要添加keep-alive即可
<keep-alive>
  <component v-bind:is="currentView">
    <!-- 組件在 vm.currentview 變化時(shí)改變儒将! -->
  </component>
</keep-alive>

參考:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市对蒲,隨后出現(xiàn)的幾起案子钩蚊,更是在濱河造成了極大的恐慌,老刑警劉巖蹈矮,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件砰逻,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡泛鸟,警方通過查閱死者的電腦和手機(jī)蝠咆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來北滥,“玉大人刚操,你說我怎么就攤上這事闸翅。” “怎么了赡茸?”我有些...
    開封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵缎脾,是天一觀的道長。 經(jīng)常有香客問我占卧,道長遗菠,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任华蜒,我火速辦了婚禮辙纬,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘叭喜。我一直安慰自己贺拣,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開白布捂蕴。 她就那樣靜靜地躺著譬涡,像睡著了一般。 火紅的嫁衣襯著肌膚如雪啥辨。 梳的紋絲不亂的頭發(fā)上涡匀,一...
    開封第一講書人閱讀 49,166評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音溉知,去河邊找鬼陨瘩。 笑死,一個(gè)胖子當(dāng)著我的面吹牛级乍,可吹牛的內(nèi)容都是我干的舌劳。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼玫荣,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼甚淡!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起捅厂,我...
    開封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤材诽,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后恒傻,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡建邓,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年盈厘,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片官边。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡沸手,死狀恐怖外遇,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情契吉,我是刑警寧澤跳仿,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站捐晶,受9級(jí)特大地震影響菲语,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜惑灵,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一山上、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧英支,春花似錦佩憾、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至池凄,卻和暖如春抡驼,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背修赞。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來泰國打工婶恼, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人柏副。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓勾邦,卻偏偏與公主長得像,于是被迫代替她去往敵國和親割择。 傳聞我的和親對(duì)象是個(gè)殘疾皇子眷篇,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容

  • 此文基于官方文檔,里面部分例子有改動(dòng)荔泳,加上了一些自己的理解 什么是組件蕉饼? 組件(Component)是 Vue.j...
    陸志均閱讀 3,805評(píng)論 5 14
  • 什么是Vue組件 組件 (Component) 是 Vue.js 最強(qiáng)大的功能之一。組件可以擴(kuò)展 HTML 元素玛歌,...
    bacbcc94613b閱讀 960評(píng)論 0 0
  • Vue/組件 創(chuàng)建組件 單獨(dú)聲明一個(gè)Vue.component昧港,使用只需要在Vue實(shí)例下使用定義的組件名在組件中d...
    一刀一個(gè)小黃魚閱讀 603評(píng)論 0 51
  • 這篇筆記主要包含 Vue 2 不同于 Vue 1 或者特有的內(nèi)容,還有我對(duì)于 Vue 1.0 印象不深的內(nèi)容支子。關(guān)于...
    云之外閱讀 5,045評(píng)論 0 29
  • 組件 什么是組件创肥? 組件(Component)是 Vue.js 最強(qiáng)大的功能之一。組件可以擴(kuò)展 HTML 元素,封...
    陸志均閱讀 2,421評(píng)論 0 0