淺談Vue 中的組件

淺談 vue 中的組件

一 、初識組件

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

一、定義組件

Vue自定義組件分爲兩種:全局註冊和局部註冊,全局組件能夠在任何地方引用,局部組件只能在當前Vue實例使用。vue

  1. 全局註冊 放在經過new建立的Vue實例當中java

    Vue.component('my-component', {
      template: '<p>我是被全局註冊的組件</p>'
    })
    /*
      Vue.component(組件名稱[字符串], 組件對象)
    */ 
    new Vue({
      el: '#app',
      template: '<my-component></my-component>'
    })
  2. 局部註冊vuex

    const child = {
      template: '<p>我是局部註冊的組件</p>'
    }
    /*
       經過components選項屬性進行局部註冊:
       components: {
        組件名稱[字符串]: 組件對象
       }
    */ 
    new Vue({
      el: '#app',
      template: '<my-component></my-component>',
      components: {
        'my-component': child
      }
    })

preview

2、自定義事件

自定義事件原理

經過$emit(event)觸發一個自定義事件app

而後經過$on(event,callback) 去執行對應的callback(回調函數)ide

(兩個event是字符串,且必須名稱相同)函數

但$on不能在父組件中監聽子組件拋出的事件,因此咱們要作到這一點,能夠在父組件的模板中使用到子組件的時候,直接用v-on綁定 (和$on做用效果一致)ui

3、組件通訊

組件是 vue.js 最強大的功能之一,而組件實例的做用域是相互獨立的,這就意味着不一樣組件之間的數據沒法相互引用。通常來講,組件能夠有如下幾種關係:this

clipboard.png

如上圖所示,A 和 B、B 和 C、B 和 D 都是父子關係,C 和 D 是兄弟關係,A 和 C 是隔代關係(可能隔多代)。spa

針對不一樣的使用場景,如何選擇行之有效的通訊方式?這是咱們所要探討的主題。本文總結了 vue 組件間通訊的幾種方式,如 props、$emit/$on、vuex、$parent / $children$attrs/$listeners和 provide/inject等

一、方法一props/$emit

父組件 A 經過 props 的方式向子組件 B 傳遞,B to A 經過在 B 組件中 $emit, A 組件中 v-on 的方式實現。

  • 父組件向子組件傳值

    //App.vue父組件
    <template>
      <div id="app">
        <users v-bind:users="users"></users>//前者自定義名稱便於子組件調用,後者要傳遞數據名
      </div>
    </template>
    <script>
    import Users from "./components/Users"
    export default {
      name: 'App',
      data(){
        return{
          users:["Henry","Bucky","Emily"]
        }
      },
      components:{
        "users":Users
      }
    }
    //users子組件
    <template>
      <div class="hello">
        <ul>
          <li v-for="user in users">{{user}}</li>//遍歷傳遞過來的值,而後呈現到頁面
        </ul>
      </div>
    </template>
    <script>
    export default {
      name: 'HelloWorld',
      props:{
        users:{           //這個就是父組件中子標籤自定義名字
          type:Array,
          required:true
        }
      }
    }
    </script>
  • 子組件向父組件傳值

    子組件經過 events 給父組件發送消息,實際上就是子組件把本身的數據發送到父組件。

    <template>
      <header>
        <h1 @click="changeTitle">{{title}}</h1>//綁定一個點擊事件
      </header>
    </template>
    <script>
    export default {
      name: 'app-header',
      data() {
        return {
          title:"Vue.js Demo"
        }
      },
      methods:{
        changeTitle() {
          this.$emit("titleChanged","子向父組件傳值");//自定義事件  傳遞值「子向父組件傳值」
        }
      }
    }
    </script>
    // 父組件
    <template>
      <div id="app">
        <app-header v-on:titleChanged="updateTitle" ></app-header>//與子組件titleChanged自定義事件保持一致
       // updateTitle($event)接受傳遞過來的文字
        <h2>{{title}}</h2>
      </div>
    </template>
    <script>
    import Header from "./components/Header"
    export default {
      name: 'App',
      data(){
        return{
          title:"傳遞的是一個值"
        }
      },
      methods:{
        updateTitle(e){   //聲明這個函數
          this.title = e;
        }
      },
      components:{
       "app-header":Header,
      }
    }
    </script>

二、方法二 $emit/$on

這種方法經過一個空的 Vue 實例做爲中央事件總線(事件中心),用它來觸發事件和監聽事件,巧妙而輕量地實現了任何組件間的通訊,包括父子、兄弟、跨級。當咱們的項目比較大時,能夠選擇更好的狀態管理解決方案 vuex。

  1. 例子

    <div id="app">
          <v-about></v-about>
          <hr />
          <v-more></v-more>
        </div>
        <template id="about">
          <div>
            我是about組件
            <button @click="toMore">我要把about中的數據傳給more</button>
          </div>
        </template>
        <template id="more">
          <div>
            我是more組件
          </div>
        </template>
        <script src="../vue.js"></script>
        <script>
          //about------>more
          const eventBus = new Vue(); //中央事件總線
    
          const More = {
            template: `#more`,
            data() {
              return {
                msg: '我是用來接收從about傳過來的數據'
              };
            },
            mounted() {
              eventBus.$on('FormAboutToMore', function(data) {
                this.msg = data;
                console.log(this.msg);
              });
            }
          };
          const About = {
            template: `#about`,
            data() {
              return {
                msg: '我是about中的數據'
              };
            },
            methods: {
              toMore() {
                eventBus.$emit('FormAboutToMore', this.msg);
              }
            }
          };
          const app = new Vue({
            el: '#app',
            data() {
              return {
                msg: '我是根組件的數據'
              };
            },
            methods: {},
            components: {
              'v-about': About,
              'v-more': More
            }
          });
        </script>
相關文章
相關標籤/搜索