Vue元件間傳遞資料

李不遠發表於2018-11-20

元件是Vue很強大的一個功能,所以掌握Vue元件之間的資訊傳遞很重要。大致分為三種常見的情況。

  • 父元件向子元件傳遞資料
  • 子元件向父元件傳遞資料
  • 兄弟元件傳遞資料

下面我們就這三種情況,分別演示其方法

父元件通過rop向子元件傳遞資料

Prop 是你可以在元件上註冊的一些自定義特性。當一個值傳遞給一個 prop 特性的時候,它就變成了那個元件例項的一個屬性。

  • 一個元件可以擁有任意數量的prop
  • 任何值都可以傳遞給任何prop
    demo
<div id="app">
    <my-component title="我是第一個元件"></my-component>
    <my-component title="我是第二個元件"></my-component>
    <my-component title="我是第三個元件"></my-component>
</div>

<script src="https://cdn.bootcss.com/vue/2.5.17/vue.js"></script>
<script>
    Vue.component('my-component', {
        props: ['title'],
        template: '<h2>{{title}}</h2>'
    })


    new Vue({
        el: '#app',
        data: {},
    })
</script>
複製程式碼

通過事件子元件向父元件傳送資料

類似於JavaScript的設計模式——觀察者模式,dispatchEventaddEventListener。在Vue中,子元件用$emit()來觸發事件,父元件用$on() 來監聽子元件的事件。

  • 自定義事件
  • 在子元件中用$emit觸發事件,第一個引數是事件名,後邊的引數是要傳遞的資料
  • 在自定義事件中用一個引數來接受
    demo
<div id="app">
    <div :style="{ fontSize: postFontSize + 'em' }">
        <blog-post
                v-for="post in posts"
                v-bind:key="post.id"
                v-bind:post="post"
                @change="enlargeText"
        ></blog-post>
    </div>
</div>
<script>
    Vue.component('blog-post', {
        props: ['post'],
        template: `
    <div class="blog-post">
      <h3>{{ post.title }}</h3>
      <button @click="$emit('change')">
        增大字號
      </button>
      <div v-html="post.content"></div>
    </div>
  `
    })

    new Vue({
        el: '#app',
        data: {
            posts: [
                {id: 1, title: '我是標題一'},
                {id: 2, title: '我是標題二'},
                {id: 3, title: '我是標題三'}
            ],
            postFontSize: 1
        },
        methods: {
            enlargeText: function () {
                this.postFontSize += 0.1
            }
        }
    })
</script>
複製程式碼

使用bus進行兄弟元件傳遞資料

在兄弟元件進行資料傳遞時,通常的做法是使用一個空的Vue例項作為中央事件匯流排:

var bus = new Vue()
複製程式碼
//觸發元件A中的事件
bus.$emit('id-selected',1)
複製程式碼
//在元件B建立的鉤子中監聽事件
bus.$on('id-selected',function(id){
    //...
})
複製程式碼

demo

<div id="app">
    <first-component></first-component>
    <second-component></second-component>
</div>

<script>
    Vue.component('first-component', {
        template: `<div><button @click="handle">點我向b元件傳遞資料</button></div>`,
        data: function () {
            return {
                aaa: '我是來自A元件的內容'
            }
        },
        methods: {
            handle: function () {
                this.$root.bus.$emit('haha', this.aaa)
            }
        }
    })
    Vue.component('second-component', {
        template: `<div>我是一個元件</div>`,
        created: function () {
            this.$root.bus.$on('haha', function (value) {
                alert(value)
            })
        }
    })
    new Vue({
        el: '#app',
        data: {
            bus: new Vue()
        }
    })
</script>
複製程式碼

父鏈

this.$parent

子鏈(利用索引)

<my-component ref='xxx'>
複製程式碼

this.$refs.xxx

相關文章