vue.js之組件篇

Vue.js 組件

  • 模塊化:是從代碼邏輯的角度進行劃分的;
  • 組件化:是從UI界面的角度進行劃分的。

組件(Component)是 Vue.js 最強大的功能之一,組件能夠擴展 HTML 元素,封裝可重用的代碼。javascript

組件系統讓咱們能夠用獨立可複用的小組件來構建大型應用,幾乎任意類型的應用的界面均可以抽象爲一個組件樹,以下圖所示:css

使用Vue.extend來建立全局vue組件:

var com1 = Vue.extend({
template: '<h3>這是使用 Vue.extend 建立的組件</h3>' // 經過template屬性,指定了組件要展現的HTML結構
})

此時只是聲明瞭一個叫com1的組件,若是要在vue實例中使用組件,還須要經過如下方式來註冊組件:

   Vue.component('myCom1', com1)

組件的調用: 

  <div id="app">
    <!-- 若是要使用組件,直接把組件的名稱以HTML標籤的形式,引入到頁面中便可 -->
    <my-com1></my-com1>
  </div>

 注意事項:

  1. 若是使用 Vue.component 註冊組件的時候,組件名稱使用了駝峯命名,則在引用組件的時候,須要把大寫的駝峯改成小寫的字母,同時,兩個單詞之間使用 「-」 鏈接
  2. 若是不使用駝峯,則直接拿名稱來使用便可;

其它兩種建立組件的方式:

    Vue.component('myCom1', Vue.extend({
      template: '<h3>這是使用Vue.extend建立的組件</h3>'
    }))
    Vue.component('mycom2', {
      template: '<div><h3>這是直接使用Vue.component建立出來的組件</h3><span>123</span></div>'
    })

注意:不管是哪一種方式建立出來的組件,組件的 template 屬性指向的模板內容,必須有且只能有惟一的一個根元素

在被控制的#app外面,使用template元素,定義組件的HTML模板結構:

  <template id="tmpl">
    <div>
      <h1>這是經過 template 元素,在外部定義的組件結構,這個方式,有代碼的智能提示和語法高亮</h1>
    </div>
  </template>
   Vue.component('mycom3', {
      template: '#tmpl' //引用template的id屬性
    })

 私有組件:

  <template id="tmpl2">
    <h1>這是私有的 login 組件</h1>
  </template>
    var vm2 = new Vue({
      el: '#app2',
      components: { // 定義實例內部私有組件的
        login: {
          template: '#tmpl2'
        }
      },
    })

組件中的data和methods:

  1. 組件能夠有本身的data數據;
  2. 組件的data和實例的data有點不同,實例中的data能夠爲一個對象,可是組件中的data必須是一個方法;
  3. 組件中的data除了必須爲一個方法以外,這個方法內部還必須返回一個對象;
  4. 組件中的data數據,使用方式和實例中的data使用方式徹底同樣
    Vue.component('mycom1', {
      template: '<h1>這是全局組件 --- {{msg}}</h1>',
      data: function () {
        return {
          msg: '這是組件的中data定義的數據'
        }
      }
    })

 爲何組件中的data必需要是一個方法,演示以下:

Html代碼:html

  <div id="app">
    <counter></counter>
    <hr>
    <counter></counter>
    <hr>
    <counter></counter>
  </div>
  <template id="tmpl">
    <div>
      <input type="button" value="+1" @click="increment">
      <h3>{{count}}</h3>
    </div>
  </template>

javascript代碼:vue

    var dataObj = { count: 0 }
    //這是一個計數器的組件, 身上有個按鈕,每當點擊按鈕,讓data中的count值+1
    Vue.component('counter', {
      template: '#tmpl',
      data: function () {
        // return dataObj
        return { count: 0 }
      },
      methods: {
        increment() {
          this.count++
        }
      }
    })
    // 建立 Vue 實例,獲得 ViewModel
    var vm = new Vue({
      el: '#app',
      data: {},
      methods: {}
    });

調用測試結果以下 :java

每一個計數器的count是獨立的,如將將返回的值改成:
app

        return dataObj
        //return { count: 0 }

結果爲:模塊化

每一個組件的count是共享的,組件的data必須是一個方法,且必須返回一個對象。要解決的問題就是提升組件的複用性,防止組件與組件之間成員干擾。組件化

組件的切換:

<body>
  <div id="app">
    <a href="" @click.prevent="flag=true">登陸</a>
    <a href="" @click.prevent="flag=false">註冊</a>
    <login v-if="flag"></login>
    <register v-else="flag"></register>
  </div>
  <script>
    Vue.component('login', {
      template: '<h3>登陸組件</h3>'
    })
    Vue.component('register', {
      template: '<h3>註冊組件</h3>'
    })
    var vm = new Vue({
      el: '#app',
      data: {
        flag: true
      },
      methods: {}
    });
  </script>
</body>

演示結果以下,默認顯示登陸組件,點擊註冊切換到註冊組件,點擊登陸切換的登陸組件。測試

 

 

 

缺點分析:若是在一個需求中須要切換更多的組件,這種方式不利於擴展。動畫

    <!-- Vue提供了component ,來展現對應名稱的組件 -->
    <!-- component 是一個佔位符, 「:is」是屬性,能夠用來指定要展現的組件的名稱 -->
  <div id="app">
    <a href="" @click.prevent="comName='login'">登陸</a>
    <a href="" @click.prevent="comName='register'">註冊</a>
    <component :is="comName"></component>
  </div>
  <script>
    // 組件名稱是字符串
    Vue.component('login', {
      template: '<h3>登陸組件</h3>'
    })
    Vue.component('register', {
      template: '<h3>註冊組件</h3>'
    })
    // 建立 Vue 實例,獲得 ViewModel
    var vm = new Vue({
      el: '#app',
      data: {
        comName: 'login' //當前component中的 :is 綁定的組件的名稱
      },
    });
  </script>

組件切換動畫:

html代碼:

  <div id="app">
    <a href="" @click.prevent="comName='login'">登陸</a>
    <a href="" @click.prevent="comName='register'">註冊</a>

    <!-- 經過 mode 屬性,設置組件切換時候的模式爲先出後進-->
    <transition mode="out-in">
      <component :is="comName"></component>
    </transition>

  </div>

  <script>
    // 組件名稱是 字符串
    Vue.component('login', {
      template: '<h3>登陸組件</h3>'
    })

    Vue.component('register', {
      template: '<h3>註冊組件</h3>'
    })
    var vm = new Vue({
      el: '#app',
      data: {
        comName: 'login' // 當前 component 中的 :is 綁定的組件的名稱
      },
    });
  </script>

css代碼:

  <style>
    .v-enter,
    .v-leave-to {
      opacity: 0;
      transform: translateX(150px);
    }

    .v-enter-active,
    .v-leave-active {
      transition: all 0.5s ease;
    }
  </style>

子組件引用父組件的值:

 1     <div id="app">
 2         <com1></com1>
 3     </div>
 4     <script>
 5 
 6             Vue.component
 7             var vm = new Vue({ 8  el:'#app', 9  data:{ 10  msg:"heelo !" 11  }, 12  methods:{ 13  }, 14  components:{ 15  com1:{ 16  template:'<h1>這是子組件---{{msg}}</h1>' 17  } 18  } 19  }) 20 </script>

執行結果:

默認狀況下子組件是不能引用父組件的屬性和對象的,咱們能夠在引用子組件的時候,經過屬性綁定的形式(v-bind)的形式,把須要傳遞給子組件的數據,以屬性綁定的形式傳遞到子組件內部,供子組件使用,而且在props中聲明該屬性(props中的數據都是經過父組傳遞過來的,這裏的數據是隻讀的),代碼以下:

 1     <div id="app">
 2         <com1 v-bind:parentmsg="msg"></com1>
 3     </div>
 4     <script>
 5         Vue.component
 6         var vm = new Vue({ 7  el: '#app', 8  data: { 9  msg: "heelo !" 10  }, 11  methods: { 12  }, 13  components: { 14  data() { 15 return { 16  title: '123', 17  content: 'pppp' 18  } 19  }, 20  com1: { 21  props: ['parentmsg'], 22  template: '<h1>這是子組件---{{parentmsg}}</h1>' 23  } 24  } 25  }) 26 </script>

子組件調用父組件的方法:

請詳細看下面代碼中的註釋

 1  <div id="app">
 2      
3 <com2 @func="show"></com2> 4 </div> 5 <template id="tmpl"> 6 <div> 7 <h1>這是子組件</h1> 8 <input type="button" value="這是子組件中的點擊按鈕" @click="myclick"> 9 </div> 10 </template> 11 <script> 12 //定義了一個字面量類型的組件模板對象 13 var com2 = { 14 template: '#tmpl', 15 data() { 16 return { 17 sonmsg: { name: 'wjl', age: 16 } 18 } 19 }, 20 methods: { 21 myclick() { 22 //當點擊子組件的按鈕時,經過$emit拿到父組件傳遞過來的func 23 //emit的英文願意爲觸發、調用、發射的意思 24 this.$emit('func', this.sonmsg, 123, 456) 25 } 26 } 27 } 28 var vm = new Vue({ 29 el: '#app', 30 data: { 31 datamsg: null 32 }, 33 methods: { 34 show(data, data1, data2) { 35 console.log('調用了父組件的show方法:' + data.name + data1 + data2); 36 } 37 }, 38 components: { 39 com2 40 } 41 }) 42 </script>

執行結果:

個人博客即將搬運同步至騰訊雲+社區,邀請你們一同入駐:https://cloud.tencent.com/developer/support-plan?invite_code=2lv2gsiubr6sw

相關文章
相關標籤/搜索