Vue:入門9(組件基礎)

component創建的組件可以當作自定義元素使用,並且有組件的相應功能

  • 因爲組件是可複用的 Vue 實例,所以它們與 new Vue 接收相同的選項,
    例如 data、computed、watch、methods 以及生命週期鉤子等。
    僅有的例外是像 el 這樣根實例特有的選項。
  • 組件的data必須是一個函數,這樣寫。所有組件都是互不影響的
</div>
<div id="id1">
   <button-counter></button-counter>
   <button-counter></button-counter>
   <button-counter></button-counter>
</div>
<script>
   Vue.component('button-counter',{
      data:function () {
         return {
            count:0
         }
      },
      template:'<button v-on:click="count++">{{count}}</button>'
   });
   new Vue({
      el:'#id1',
   });
</script>
<!--如果是這樣寫的話,所有組件的count都是一樣的-->
<div id="id2">
  <button-counter></button-counter>
  <button-counter></button-counter>
  <button-counter></button-counter>
</div>
<script>

  var returnData = {
     count:0
  };
  Vue.component('button-counter',{
     data:function () {
        return returnData;
     },
     template:'<button v-on:click="count++">{{count}}</button>'
  });
  new Vue({
     el:'#id2',
  });
</script>

通過 Prop 向子組件傳遞數據

<!--方式1:直接在組件中。這樣頁面會將組件對應值替換
結果:<h3 id="id3">My journey with Vue</h3>
-->
<blog-post id="id3" title="My journey with Vue"></blog-post>
<script>
   Vue.component('blog-post',{
      props:['title'],
      template:'<h3 >{{title}}</h3>'
   });
   new Vue({
      el:'#id3',
   });
</script>
<!--方式二:通過Vue對象中傳值,注意key這個屬性不會在頁面源碼上顯示出來
結果:
<div id="id4">
   <h3 id="1">My journey with Vue</h3>
   <h3 id="2">Blogging with Vue</h3>
   <h3 id="3">Why Vue is so fun</h3>
</div>
-->
<div id="id4">
   <blog-post2 v-for="post in posts" v-bind:id="post.id" v-bind:key="post.id" v-bind:title="post.title"></blog-post2>
</div>
<script>
   Vue.component('blog-post2',{
      props:['title'],
      template:'<h3>{{title}}</h3>'
   });
   new Vue({
      el: '#id4',
      data: {
         posts: [
            { id: 1, title: 'My journey with Vue' },
            { id: 2, title: 'Blogging with Vue' },
            { id: 3, title: 'Why Vue is so fun' }
         ]
      }
   });
</script>

注意這裏進行了 v-bind:post=“post”,這樣才能在template中使用這個對象

<!--其中一個頁面結果是,注意看生成的id的位置:
<div id="1"><h3>My journey with Vue</h3> <div>1111</div></div>
-->
<div id="id5">
   <blog-post v-for="post in posts" v-bind:id="post.id" v-bind:key="post.id" v-bind:post="post"></blog-post>
</div>
<script>
   Vue.component('blog-post',{
      props:['post'],
      template:' <div>\n' +
              '      <h3>{{ post.title }}</h3>\n' +
              '      <div v-html="post.content"></div>\n' +
              '    </div>',
   });
   new Vue({
      el:'#id5',
      data:{
         posts: [
            { id: 1, title: 'My journey with Vue',content:'1111'},
            { id: 2, title: 'Blogging with Vue' ,content:'2222'},
            { id: 3, title: 'Why Vue is so fun' ,content:'3333'}
         ]
      }
   });
</script>
<!-- 效果:點擊按鈕增加div的字體大小
 首先添加了一個v-on:enlarge-text="postFontSize += 0.1"
 然後通過 v-on:click=$emit('enlarge-text')調用對應的方法
 -->
<div id="id6">
   <div :style="{fontSize : postFontSize1 + 'em'}">
      <blog-post v-on:enlarge-text="postFontSize1 += 0.1" v-for="post in posts"  v-bind:post="post" v-bind:key="post.id"> </blog-post>
   </div>
<!--   同時$emit('enlarge-text',0.2) 第二個參數也可以通過$event獲取。第二個div每次+0.2-->
   <div :style="{fontSize : postFontSize2 + 'em'}">
      <blog-post v-on:enlarge-text="postFontSize2 += $event" v-for="post in posts"  v-bind:post="post" v-bind:key="post.id"> </blog-post>
   </div>
<!-- 同時還可以通過函數的方式  -->
   <div :style="{fontSize : postFontSize3 + 'em'}">
      <blog-post v-on:enlarge-text="onEnlargeText" v-for="post in posts"  v-bind:post="post" v-bind:key="post.id"> </blog-post>
   </div>
</div>
<script>
   Vue.component('blog-post',{
      props:['post'],
      template:'<div><h3>{{post.title}}</h3>' +
              '<button v-on:click="$emit(\'enlarge-text\',0.2)">enlarge text</button>' +
              '<div v-html="post.content"></div></div>'
   });
   new Vue({
      el: '#id6',
      data: {
         posts: [
            { id: 1, title: 'My journey with Vue',content:'1111'},
         ],
         postFontSize1: 1,
         postFontSize2: 1,
         postFontSize3: 1,
      },
      methods:{
         onEnlargeText: function (arg) {
            this.postFontSize3 += arg;
         }
      }
   });

</script>

組件使用v-model

<!--
<custom-input v-model="searchText"></custom-input>
實際是
<custom-input :value="searchText" @input="searchText = $event" ></custom-input>
-->
<div id="id7">
   <custom-input v-model="searchText"></custom-input>
   <span>{{searchText}}</span>
</div>
<script>
   Vue.component('custom-input',{
      props:['value'],
      template:' <input\n' +
              '      v-bind:value="value"\n' +
              '      v-on:input="$emit(\'input\', $event.target.value)"\n' +
              '    >',
   });
   new Vue({
      el:'#id7',
      data:{
         searchText:0,
      }
   });
</script>

通過插槽分發內容

<!--
<slot></slot>代表對應的'omething bad happened.'
結果:
<div id="id8"><strong>Error!</strong>
   Something bad happened.
</div>
-->
<alert-box id="id8">
   Something bad happened.
</alert-box>

<script>
   Vue.component('alert-box', {
      template: `
    <div>
      <strong>Error!</strong>
      <slot></slot>
    </div>
  `
   });
   new Vue({
      el:'#id8',
   })
</script>

動態組件

<!--
效果點擊切換頁面會一直切換不同的組件
這裏用到了:is 可以認爲:is=對應的組件名稱
-->
<div id="id9">
   <button @click="change">切換頁面</button>
   <component v-bind:is="currentTabComponent"></component>
</div>
<script>
   Vue.component('tab-home', { template: '<div>Home component</div>' });
   Vue.component('tab-posts', { template: '<div>Posts component</div>' });
   Vue.component('tab-archive', { template: '<div>Archive component</div>' });
   new Vue({
      el: '#id9',
      data: {
         currentTab: 'Home',
         index :0,
         tabs: ['Home', 'Posts', 'Archive']
      },
      computed: {
         currentTabComponent: function () {
            return 'tab-' + this.currentTab.toLowerCase()
         }
      },
      methods: {
         change:function () {
            this.index ++;
            if (this.index >= 3) {
               this.index = 0;
            }
            this.currentTab = this.tabs[this.index];
         }
      }
   })
</script>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章