Vue 組件間傳值

前言

Vue 作爲現在比較火的框架之一,相信您在使用的過程中,也會遇到組件間傳值的情況,本文將講解幾種 Vue 組件間傳值的幾種方法,跟着小編一起來學習一下吧!

實現

注意: 學習本文,需要您對 Vue 有一定的瞭解。

爲了便於講解,以下方法均假設父組件是 FatherComponent,子組件是 ChildComponent,兄弟組件是:BrotherComponent。我們來假定一種場景:點擊父組件“傳遞給子組件”按鈕,向子組件傳遞一條消息“I am your father.”;點擊子組件“傳遞給父組件”按鈕,向父組件傳遞一條消息“I am your child.”;點擊子組件“傳遞給兄弟組件”按鈕,向兄弟組件傳遞一條消息“I am your brother.”

方法一

關鍵詞: props、$emit

父組件 FatherComponent 代碼:

<template>
  <div>
    <div>{{toFatherInfo}}</div>
    <ChildComponent :toChildInfo="toChildInfo" @toFather="toFather" @toBrother="toBrother"/>
    <BrotherComponent :toBrotherInfo="toBrotherInfo"/>
    <button @click="toChild">傳遞給子組件</button>
  </div>
</template>

<script>
  import ChildComponent from 'components/test/child-component'
  import BrotherComponent from 'components/test/brother-component'

  export default {
    components: {
      ChildComponent,
      BrotherComponent
    },
    data () {
      return {
        toFatherInfo: '',
        toChildInfo: '',
        toBrotherInfo: ''
      }
    },
    methods: {
      toFather (res) {
        this.toFatherInfo = res
      },
      toBrother (res) {
        this.toBrotherInfo = res
      },
      toChild () {
        this.toChildInfo = 'I am your father.'
      }
    }
  }
</script>

<style lang="less">
  button {
    font-size: 36px;
    border: none;
    padding: 20px;
    background-color: #999;
    color: #fff;
    width: 100%;
    margin-top: 30px;
  }
</style>

子組件 ChildComponent 代碼:

<template>
  <div>
    <div>{{toChildInfo}}</div>
    <button @click="toFather">傳遞給父組件</button>
    <button @click="toBrother">傳遞給兄弟組件</button>
  </div>
</template>

<script>
  export default {
    props: {
      toChildInfo: {
        type: String
      }
    },
    methods: {
      toFather () {
        this.$emit('toFather', 'I am your child.')
      },
      toBrother () {
        this.$emit('toBrother', 'I am your brother.')
      }
    }
  }
</script>

<style lang="less">
</style>

兄弟組件 BrotherComponent 代碼:

<template>
  <div>{{toBrotherInfo}}</div>
</template>

<script>
  export default {
    props: {
      toBrotherInfo: {
        type: String
      }
    }
  }
</script>

<style lang="less">
</style>

通過上面代碼,不難發現,我們通過使用 props 來實現父組件給子組件傳值;子組件向父組件傳值時,藉助 $emit 來實現;而子組件向兄弟組件傳值時,將兩者結合起來使用。

方法二

關鍵詞:獨立的事件中心 eventHub

首先需要先創建 eventHub.js 文件,代碼如下:

// 將在各處使用該事件中心
// 組件通過它來通信
import Vue from 'vue'
export default new Vue()

然後在組件中,可以使用 $emit, $on, $off 分別來分發、監聽、取消監聽事件。

父組件 FatherComponent 代碼:

<template>
  <div>
    <div>{{info}}</div>
    <ChildComponent />
    <BrotherComponent />
    <button @click="toChild">傳遞給子組件</button>
  </div>
</template>

<script>
  import eventHub from '../../components/test/eventHub'
  import ChildComponent from 'components/test/child-component'
  import BrotherComponent from 'components/test/brother-component'

  export default {
    components: {
      ChildComponent,
      BrotherComponent
    },
    data () {
      return {
        info: ''
      }
    },
    created: function () {
      eventHub.$on('toFather', this.toFather)
    },
    // 最好在組件銷燬前
    // 清除事件監聽
    beforeDestroy: function () {
      eventHub.$off('toFather', this.toFather)
    },
    methods: {
      toFather (res) {
        this.info = res
      },
      toChild () {
        eventHub.$emit('toChild', 'I am your father.')
      }
    }
  }
</script>

<style lang="less">
  button {
    font-size: 36px;
    border: none;
    padding: 20px;
    background-color: #999;
    color: #fff;
    width: 100%;
    margin-top: 30px;
  }
</style>

子組件 ChildComponent 代碼:

<template>
  <div>
    <div>{{info}}</div>
    <button @click="toFather">傳遞給父組件</button>
    <button @click="toBrother">傳遞給兄弟組件</button>
  </div>
</template>

<script>
  import eventHub from './eventHub'
  export default {
    data () {
      return {
        info: ''
      }
    },
    created: function () {
      eventHub.$on('toChild', this.toChild)
    },
    // 最好在組件銷燬前
    // 清除事件監聽
    beforeDestroy: function () {
      eventHub.$off('toChild', this.toChild)
    },
    methods: {
      toChild (res) {
        this.info = res
      },
      toFather () {
        eventHub.$emit('toFather', 'I am your child.')
      },
      toBrother () {
        eventHub.$emit('toBrother', 'I am your brother.')
      }
    }
  }
</script>

<style lang="less">
</style>

兄弟組件 BrotherComponent 代碼:

<template>
  <div>{{info}}</div>
</template>

<script>
  import eventHub from './eventHub'
  export default {
    data () {
      return {
        info: ''
      }
    },
    created: function () {
      eventHub.$on('toBrother', this.toBrother)
    },
    // 最好在組件銷燬前
    // 清除事件監聽
    beforeDestroy: function () {
      eventHub.$off('toBrother', this.toBrother)
    },
    methods: {
      toBrother (res) {
        this.info = res
      }
    }
  }
</script>

<style lang="less">
</style>

方法三

關鍵詞:Vuex

我們需要創建 store.js 來存放數據:

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    fromFatherInfo: '',
    fromChildInfo: '',
    fromBrotherInfo: ''
  },
  mutations: {
    changeFromFatherInfo (state, fromFatherInfo) {
      state.fromFatherInfo = fromFatherInfo
    },
    changeFromChildInfo (state, fromChildInfo) {
      state.fromChildInfo = fromChildInfo
    },
    changeFromBrotherInfo (state, fromBrotherInfo) {
      state.fromBrotherInfo = fromBrotherInfo
    }
  }
})

實例化:

import Vue from 'vue'
import App from './App'
import store from './store'

new Vue({
  el: '#app',
  store,
  template: '<App/>',
  components: { App }
})

父組件 FatherComponent 代碼:

<template>
  <div>
    <div>{{fromChildInfo}}</div>
    <ChildComponent />
    <BrotherComponent />
    <button @click="toChild">傳遞給子組件</button>
  </div>
</template>

<script>
  import ChildComponent from 'components/test/child-component'
  import BrotherComponent from 'components/test/brother-component'

  export default {
    components: {
      ChildComponent,
      BrotherComponent
    },
    computed: {
      fromChildInfo () {
        return this.$store.state.fromChildInfo
      }
    },
    methods: {
      toChild () {
        this.$store.commit('changeFromFatherInfo', 'I am your father.')
      }
    }
  }
</script>

<style lang="less">
  button {
    font-size: 36px;
    border: none;
    padding: 20px;
    background-color: #999;
    color: #fff;
    width: 100%;
    margin-top: 30px;
  }
</style>

子組件 ChildComponent 代碼:

<template>
  <div>
    <div>{{fromFatherInfo}}</div>
    <button @click="toFather">傳遞給父組件</button>
    <button @click="toBrother">傳遞給兄弟組件</button>
  </div>
</template>

<script>
  export default {
    computed: {
      fromFatherInfo () {
        return this.$store.state.fromFatherInfo
      }
    },
    methods: {
      toFather () {
        this.$store.commit('changeFromChildInfo', 'I am your child.')
      },
      toBrother () {
        this.$store.commit('changeFromBrotherInfo', 'I am your brother.')
      }
    }
  }
</script>

<style lang="less">
</style>

兄弟組件 BrotherComponent 代碼:

<template>
  <div>{{fromBrotherInfo}}</div>
</template>

<script>
  export default {
    computed: {
      fromBrotherInfo () {
        return this.$store.state.fromBrotherInfo
      }
    }
  }
</script>

<style lang="less">
</style>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章