天天看點

Vue.js高效前端開發 • 【Vue元件】

全部章節 >>>>

文章目錄

  • 一、Vue元件介紹
    • 1、元件概述
    • 2、元件使用步驟
    • 3、實踐練習
  • 一、Vue元件使用
    • 1、元件注冊
    • 2、元件注冊文法糖
    • 3、使用script或template标簽
    • 4、元件的el和data選項
    • 5、實踐練習
  • 三、元件之間的通信
    • 1、父元件和子元件
    • 2、通過props向子元件傳遞資料
  • 四、Vue的插槽
    • 1、插槽使用
    • 2、作用域插槽使用
  • 總結:

元件系統是Vue其中一個重要的概念,它提供了一種抽象,讓可以使用獨立可複用的

小元件

來建構大型應用,任意類型的應用界面都可以抽象為一個

元件樹

,如圖所示。

Vue.js高效前端開發 • 【Vue元件】

元件是可複用的

Vue執行個體

,且帶有一個名字。元件可以

擴充HTML元素

,封裝可重用的HTML代碼,可以将元件看作自定義的HTML元素。例如,頁面中可能會有

頁頭

側邊欄

内容區

等元件,每個元件又包含了其他的像

導航連結

博文

之類的元件。

Vue的元件的使用有

3個步驟:

建立元件:

通過調用

Vue.extend()

方法建立元件。

注冊元件:

調用

Vue.component()

方法元件元件。

使用元件:

使用Vue執行個體的頁面内自定義元件标簽。

Vue.js高效前端開發 • 【Vue元件】

示例:

按Vue元件使用步驟建立了顯示歡迎詞的元件,然後在頁面中使用該元件

<!-- HTML代碼: -->
<div id="app" style="margin:20px auto;width:600px">
  <!--使用元件-->
  <my-comp></my-comp> <!--元件挂載到某個Vue執行個體下-->
</div>
           
// JavaScript代碼:
// 建立元件
var myComp=Vue.extend({   //調用Vue.extend()建立一個元件
  template:"<h1>使用Vue元件!</h1>"  //template屬性用于定義元件要渲染的HTML
});
// 注冊元件
Vue.component("my-comp",myComp);   //使用Vue.component()注冊元件
// 執行個體化Vue
var vm = new Vue({
  el: "#app"
})
           
Vue.js高效前端開發 • 【Vue元件】

注冊元件過程又細分為全局注冊和局部注冊。

(1) 全局注冊

在調用

Vue.component()

注冊元件時,元件的注冊是全局的,這意味着該元件可以在目前頁面的任意Vue執行個體下使用。

Vue.component('my-component-name', { /* ... */ })
           

示例:

建立了一個Vue元件分别在兩個Vue執行個體中使用

<!-- HTML代碼: -->
<div id="app1">
  <h1>Vue執行個體1</h1>
 <my-comp></my-comp>
</div>
<div id="app2">
  <h1>Vue執行個體2</h1>
  <my-comp></my-comp>
</div>
           
// JavaScript代碼:
// 建立元件
var myComp = Vue.extend({
  template: "<h3>使用全局Vue元件!</h3>"
});
// 注冊元件
Vue.component("my-comp", myComp);
// 執行個體化Vue執行個體1
var vm1 = new Vue({
  el: "#app1"
});
// 執行個體化Vue執行個體2
var vm2 = new Vue({
  el: "#app2"
});
           
Vue.js高效前端開發 • 【Vue元件】

(2) 局部注冊

如果不需要全局注冊,或者是讓元件使用在其他元件内使用,可以用Vue執行個體化時,設定選項參數的

components

參數屬性

實作局部注冊

。如下下面代碼所示:

// 建立元件
var myComp=Vue.extend({
  template:"<h1>使用全局Vue元件!</h1>"
});
           
// 執行個體化Vue
var vm = new Vue({
  el: "#app",
  components:{
    "my-comp":myComp // 局部注冊元件
  }
});
           

示例:

修改上一個示例,在Vue執行個體1中注冊元件,而Vue執行個體2沒有注冊元件

<!-- HTML代碼: -->
<div id="app1">
  <h1>Vue執行個體1</h1>
  <my-comp></my-comp>
</div>
<div id="app2">
  <h1>Vue執行個體2</h1>
  <!-- 不能使用my-comp元件,因為my-comp是一個局部元件,它屬于#app1-->
  <my-comp></my-comp>
</div>
           
// JavaScript代碼:
// 建立元件
var myComp=Vue.extend({
  template:"<h4>使用局部Vue元件!</h4>"
});
// 執行個體化Vue執行個體1
var vm1 = new Vue({
  el: "#app1",
  components:{
    "my-comp":myComp // 局部注冊元件
  }
});
// 執行個體化Vue執行個體2
var vm2 = new Vue({
  el: "#app2"
});
           
Vue.js高效前端開發 • 【Vue元件】

上述元件注冊的方式有些繁瑣,Vue.js為了簡化這個過程,提供了注冊文法糖,即在注冊元件時,直接建立和注冊元件,Vue在背後會自動地調用

Vue.extend()

(1) 簡化全局注冊

使用

Vue.component()

直接建立和注冊元件的代碼如下所示:

// 全局注冊,my-comp是元件标簽名稱
Vue.component('my-comp',{
  template: '<div><h1>使用Vue元件!</h1></div>'
})
           

(2) 簡化局部注冊

在選項對象的

components

屬性中實作局部注冊的代碼如下所示:

var vm = new Vue({
  el: '#app',
  components: {
    // 局部注冊,my-comp是元件标簽名稱
    'my-comp': {
      template: '<div><h1>使用Vue元件!</h1></div>'
    }
  }
})
           

盡管文法糖簡化了元件注冊,但在template選項中拼接HTML元素比較麻煩,這也導緻了HTML和JavaScript的高耦合性。Vue提供了兩種方式将定義在JavaScript中的HTML模闆分離出來。

使用< script>标簽

// < script>标簽方式
<script type="text/x-template" id="myComp">
 <!-- 模闆代碼 -->
</script>
           

使用< template>标簽

// <template>标簽方式
<template id="模闆id">
  <!-- 模闆代碼 -->
</template>
           

示例:①

<!-- HTML代碼: -->
<div id="app">
  <my-comp></my-comp>
</div>
           
// <script>模闆代碼:
<script type="text/x-template" id="myComp">
  <div><h1>使用Vue元件!</h1></div>
</script>
           
// JavaScript代碼:
Vue.component('my-compt',{
  template: '#myComp' //根據id查找對應的元素
});	
var vm=new Vue({
  el: '#app',
  components:{
    'my-comp' : {
      template: '#myComp'
    }
  }
});	
           

< script>

标簽時,type指定為

text/x-template

,意在告訴浏覽器這不是一段js腳本,這樣浏覽器在解析HTML文檔時會忽略

< script>

标簽内定義的内容。

示例:①

<!-- HTML代碼: -->
<div id="app">
  <my-comp></my-comp>
</div>
           
// <template>模闆代碼:
<template id="myComp"> //不需要指定type屬性
  <div><h1>使用Vue元件!</h1></div>
</template>
           
// JavaScript代碼:
var vm=new Vue({
  el: '#app',
  components:{
    'my-comp':{
      template: '#myComp' //根據id查找對應的元素
    }
  }
});	
           
  • 最好使用< script>或< template>标簽來定義元件的HTML模闆
  • 在Vue.js中,可建立.vue字尾的檔案,在.vue檔案中定義元件。

  • 一般執行個體化Vue的多數選項也可以用在

    Vue.extend()

    Vue.component()

    中的,不過有兩個特殊選項參數除外即

    data

    el

    。Vue.js規定:在定義元件的選項時,

    data

    el

    選項

    必須使用函數

  • 如果data選項指向

    某個對象

    ,這意味着所有的

    元件執行個體

    共用一個

    data

    。使用一個函數作為

    data選項

    ,讓這個函數傳回一個

    新對象

    ,文法如下所示:

文法:

// 全局注冊元件
Vue.component("元件名稱", {
  el:function(){ ... },
  data: function(){
    return {
      屬性 : 值
    }
  },
  template:"元件模闆"	
})
           
// 局部注冊元件
var vm1 = new Vue({
  el: "#app",
  components:{
    "元件名稱":{
    el:function(){ ... },
    data: function(){
      return {
        屬性 : 值
      }
    },
    template:"元件模闆"
    }
  }
});
           

示例:

<!-- HTML代碼: -->
<div id="app">
  <h3>新奇水果</h3>
  <fruit-list-comp></fruit-list-comp>
</div>
           
// <template>模闆代碼:
<template>
  <div>
    <ul>
      <li v-for="fruit in fruitList">{{ fruit }}</li>
    </ul>
  </div>
</template>
           
// JavaScript代碼:
var vm1 = new Vue({
  el: "#app",
  components: {
    "fruit-list-comp": {
      data: function () {
        return {
          fruitList: ["龍珠果", "刺角瓜", "蓮霧", "佛手柑", "費約果"]
        }
      },
      template:"#fruitTemplate"
    }
  }
});	
           
Vue.js高效前端開發 • 【Vue元件】

示例:

可以在元件中定義并使用其他元件,這就構成了

父子元件

的關系

// HTML代碼:
<div id="app">
  <parent-component></parent-component>
</div>
           
// JavaScript代碼:
// 建立子元件
var child= Vue.extend({
  template:"<p>This is a child component!</p>"
});
           
// JavaScript代碼:
// 建立父元件
var parent= Vue.extend({
  // 在父元件内使用<child-component>标簽
  template:"<p>This is a parent component!<child-component></child-component></p>",
  components:{
    "child-component":child // 注冊子元件
  }
});
	
           
// JavaScript代碼:
// 注冊父元件
Vue.component( "parent-component",parent )
var vm = new Vue({
  el: "#app"
});	
           
Vue.js高效前端開發 • 【Vue元件】

下面分

6個步驟

來了解代碼:

  1. var child = Vue.extend(…)定義一個子元件。
  2. var parent = Vue.extend(…)定義一個父元件。
  3. components: { ‘child-component’: child },将子元件注冊到父元件,并将子元件的标簽設定為child-component。
  4. template :’< p>This is a parent component < child-component>< /child-component>< /p>’,在父元件内以标簽的形式使用子元件。
  5. Vue.component(‘parent-component’, parent)全局注冊父元件。
  6. 在頁面中使用< parent-component>标簽渲染父元件的内容,同時子元件的内容也被渲染出來。
    Vue.js高效前端開發 • 【Vue元件】

子元件是在父元件中注冊的,它隻能在父元件中使用,确切地說:

子元件隻能在父元件的template中使用。

請注意下面兩種子元件的使用方式是

錯誤的

  • 以子标簽的形式在父元件中使用
  • 在父元件标簽外使用子元件
<div id="app">
  <parent-component>
    <child-component></child-component>
  </parent-component>
</div>
           
<div id="app">
  <parent-component> </parent-component>
  <child-component></child-component>
</div>
           

  • 元件執行個體的作用域是孤立的。這意味着不能并且不應該在子元件的模闆内直接引用父元件的資料。
  • 可以使用props把資料傳給子元件。
  • 一個元件預設可以擁有任意數量的prop(屬性),任何值都可以傳遞給任何prop。
  • 在元件中,使用選項props來聲明需要從父元件接收的資料,props的值可以是兩種,一種是字元串數組,一種對象。

文法:

props的值是字元串數組

var component=Vue.extend({
  props: ["屬性名",… "屬性名"],
  template: "模闆"
});
           
HTML中的屬性名是大小寫不敏感的,是以浏覽器會把所有大寫字元解釋為小寫字元。在

DOM

模闆

中使用屬性名時,

camelCase(駝峰命名法)

的屬性名需要使用其等價的

kebab-case(短橫線分隔命名)

命名,如下面代碼所示:
Vue.component("blog-post", {
  // 在JavaScript中是camelCase命名
  props: ["postTitle"],
  template: '<h3>{{ postTitle }}</h3>'
})
<!--在HTML中是kebab-case的命名 -->
<blog-post post-title="hello!"></blog-post>
           

文法:

props的值是對象

var component=Vue.extend({
  props: {
    屬性名: String,
    屬性名: Number,
    屬性名: Boolean,
    …
  },
  template: "模闆"
});
           
屬性類型包含

String(字元串)

Number(數字

)、

Boolean(布爾)

Array(數組)

Object(對象)

Date(日期)

Function(函數)

Symbol(符号)

對元件屬性傳值是單向的,并且可以靜态和動态綁定屬性。

示例:

可以在元件中定義并使用其他元件,這就構成了父子元件的關系

HTML代碼:
<div id="app">
<banner-component v-bind:is-style="isShowStyle" message="消暑玩一夏!"></banner-component>
</div>
           

v-bind:is-style="isShowStyle"

動态綁定屬性,

message="消暑玩一夏!"

靜态綁定屬性
<!-- HTML代碼: -->
<!--子元件-->
<template id="childComp">      
  <span>{{ subMessage }}</span>     
</template>
<!--父元件-->
<template id="parentComp">
<div>
<h1 :class="{ banner: isStyle }">
{{ message }} 
<child-component sub-message="不玩就out啦!"></child-component>
</h1>           
</div>
</template>
           
// JavaScript代碼:
var vm = new Vue({
  el: "#app",
  data : {
    isShowStyle:true
  },
  components: {
    "banner-component": {
      props: ["message", "isStyle"],
      template: "#parentComp", // 注冊父元件
      components:{
        "child-component":{
          props:{
            subMessage:String
          },
          template:"#childComp" // 注冊子元件
        }
      }
    }
  }
});
           
Vue.js高效前端開發 • 【Vue元件】

插槽(Slot)是Vue提出來的一個概念,正如名字一樣,插槽用于将所攜帶的内容插入到指定的某個位置,進而使

模闆分塊

,具有子產品化的特質和更大的

重用性

。插槽顯不顯示、怎樣顯示是由父元件來控制的,而插槽在哪裡顯示就由子元件來進行控制。
插槽一般在Vue的父子元件中使用,在子元件使用

< slot>标簽

将不同的DOM樹組合在一起。< slot>标簽是元件内部的占位符,使用者可以使用自己的标記來填充。通過定義一個或多個< slot>标簽,可将外部标記引入到元件的虛拟DOM中進行渲染,相當于“在此處渲染使用者的标記”。
插槽有兩種使用方式:

預設插槽

具名插槽

插槽(Slot)是為網絡元件建立“聲明性API”的一種方法。它們混入到使用者的DOM中,幫助對整個元件進行渲染,進而将不同的DOM樹組合在一起。

示例:

預設插槽

HTML代碼:
<div id="app">
  <div>
    <p-comp> 需要分發的内容 </p-comp>
  </div>
</div>
           
// <template>模闆代碼:
<template id="pComp">
  <div>
    <h1>使用預設插槽</h1>           
    <slot></slot>
  </div>
</template>
           
// JavaScript代碼:
var vm = new Vue({
  el: "#app",
  components: {
    "p-comp": {
      template: "#pComp"
    }
  }
});
           
Vue.js高效前端開發 • 【Vue元件】

示例:

具名插槽

預設插槽隻能有一個,當需要使用多個插槽時,要使用具名的插槽,即對插槽命名。

HTML代碼:
<div id="app">
  <div>
    <p-comp>           
    	<!-- 具名插槽填充内容 -->
      <template slot="header">
        <h1>商品管理系統</h1>
      </template>
      商品管理内容
      <template slot="footer">
        <h3>版權聲明</h3>
      </template>
    </p-comp>
  </div>
</div>
           
// <template>模闆代碼:
<template id="pComp">
  <div>           
    <slot name="header"></slot>  //具名插槽
    <slot></slot>  //預設插槽
    <slot name="footer"></slot>  //具名插槽
  </div>
</template>
           
// JavaScript代碼:
var vm = new Vue({
  el: "#app",
  components: {
    "p-comp": {
        template: "#pComp"
    }
  }
});
           
Vue.js高效前端開發 • 【Vue元件】

插槽可以控制html模闆的顯示與不顯示。

作用域插槽(slot-scope)

其實就是

帶資料的插槽

。原來

父元件

可以通過綁定資料傳遞給

子元件

。而作用域插槽可以通過

子元件

綁定資料傳遞給

父元件

。作用域插槽的使用場景:既可以複用子元件的slot,又可以使slot内容不一緻。

示例:

<!-- HTML代碼: -->
<div id="app">
  <div>
  <book-list :books="bookList">
    <template slot="book" slot-scope="props">
      <li>{{ props.bookname }}</li>                 
    </template>
  </book-list>
  </div>
</div>
           
// <template>模闆代碼:
<template id="bookComp">
  <div>    
    <ul>      
      <slot name="book" v-for="book in books" :bookname="book.name"></slot>           
    </ul> 
  </div>
</template>
           
// JavaScript代碼:
var vm = new Vue({
  el: "#app",
  data:{
    bookList:[
      { name:"《Vue.js實戰》" },
      { name:"《ASP.NET實戰》" },
      { name:"《深入淺出Webpack》" }
    ]
  },
  components: {
    "book-list": {
      rops:["books"],
      emplate: "#bookComp"
    }
  }
});
           
Vue.js高效前端開發 • 【Vue元件】

Vue的元件的使用有3個步驟:
  • 建立元件:

    Vue.extend()

  • 注冊元件:

    Vue.component()

  • 使用元件:

元件名的方式有兩種:
  • kebab-case(短橫線分隔命名)

    ,如< my-component-name>。
  • PascalCase(首字母大寫命名)

    ,如< MyComponentName>。
直接在DOM(即非字元串的模闆)中使用時隻有kebab-case是有效的,是以一般推薦使用kebab-case方式命名元件名。
元件執行個體的作用域是孤立的。這意味着不能并且不應該在子元件的模闆内直接引用父元件的資料。可以使用props把資料傳給子元件。
插槽在Vue的父子元件中使用,在子元件使用标簽将不同的DOM樹組合在一起。

本文來自部落格園,作者:明金同學,轉載請注明原文連結:https://www.cnblogs.com/vmuu/p/15663279.html

公衆号:【明金同學】

繼續閱讀