vue: 從組件通信到vuex (上)

關於vue之間的組件通信vue

1: prop,refs 父組件 => 子組件vuex

1) propapp

// app.vue

<template>
  <div id="app">
    <childTest1 :msg="msg"/>
  </div>
</template>

<script>
import childTest1 from './components/childTest1'

export default {
  name: 'App',
  data () {
    return {
      msg: 'data from parent'
    }
  },
  methods: {
  },
  components: {
    childTest1
  }
}
</script>

// childTest1.vue
<template>
  <div class="hello">
    {{msg}}
  </div>
</template>

<script>
export default {
  name: 'childTest1',
  props: ['msg'],
  data () {
    return {
      msgTest2: null
    }
  },
  methods: {
  }
}
</script>

2) refsthis

// app.vue
<template>
  <div id="app">
    <childTest1 :msg="msg" ref="childTest1"/>
  </div>
</template>

<script>
import childTest1 from './components/childTest1'

export default {
  name: 'App',
  data () {
    return {
      msg: 'data from parent'
    }
  },
  created () {
    // 無效
    this.$refs.childTest1.setMsgTest2('refs set msg test')
  },
  mounted () {
    this.$refs.childTest1.setMsgTest2('refs set msg test')
  },
  methods: {

  },
  components: {
    childTest1
  }
}
</script>
// childTest1.vue

<template>
  <div class="hello">
    <p>{{msg}}</p>
    <p style="color: #f80000">{{msgTest2}}</p>
  </div>
</template>

<script>
export default {
  name: 'childTest1',
  props: ['msg'],
  data () {
    return {
      msgTest2: null
    }
  },
  methods: {
    setMsgTest2 (val) {
      this.msgTest2 = val
    }
  }
}
</script>

2 : $emit 子組件 => 父組件spa

// App.vue

<template>
  <div id="app">

    <childTest1 :msg="msg" ref="childTest1" @changeMsg="setMsg"/>
  </div>
</template>

<script>
import childTest1 from './components/childTest1'

export default {
  name: 'App',
  data () {
    return {
      msg: 'data from parent'
    }
  },
  created () {
    // 無效
    this.$refs.childTest1.setMsgTest2('refs set msg test')
  },
  mounted () {
    this.$refs.childTest1.setMsgTest2('refs set msg test')
  },
  methods: {
    setMsg (val) {
      this.msg = val
    }

  },
  components: {
    childTest1
  }
}
</script>
// childTest1.vue
<template>
  <div class="hello">
    <p>{{msg}}</p>
    <p style="color: #f80000">{{msgTest2}}</p>
    <button @click="changeMsg">changeMsg</button>
  </div>
</template>

<script>
export default {
  name: 'childTest1',
  props: ['msg'],
  data () {
    return {
      msgTest2: null
    }
  },
  methods: {
    setMsgTest2 (val) {
      this.msgTest2 = val
    },
    changeMsg () {
      this.$emit('changeMsg', 'child change test msg')
    }
  }
}
</script>

上面是簡單的組件通信,簡單的父子組件傳遞能夠使用上述形式,當比較複雜的狀況下, 或者組件是相互獨立,並且中間一個發生變化另外一個變化的時候能夠使用vue bus。code

3: vue bus 獨立組件 => 獨立組件 (父 => 子 子 => 父)component

// app.Vue

<template>
  <div id="app">
    {{parentMsg}}
    <childTest1 :msg="msg" ref="childTest1" @changeMsg="setMsg"/>
    <ChildTest2 />
  </div>
</template>

<script>
import ChildTest1 from './components/ChildTest1'
import ChildTest2 from './components/ChildTest2'
import ChildTestBus from './bus/ChildTest'

export default {
  name: 'App',
  data () {
    return {
      parentMsg: 'parent init msg',
      msg: 'data from parent'
    }
  },
  created () {
    ChildTestBus.$on('changeMsg', val => this.setParentMsg(val))
    // 無效
    this.$refs.childTest1.setMsgTest2('refs set msg test')
  },
  mounted () {
    this.$refs.childTest1.setMsgTest2('refs set msg test')
  },
  destrory () {
    ChildTestBus.$off('changeMsg')
  },
  methods: {
    setParentMsg (val) {
      this.parentMsg = val
    },
    setMsg (val) {
      this.msg = val
    }

  },
  components: {
    ChildTest1,
    ChildTest2
  }
}
</script>
// ChildTest1.vue

<template>
  <div class="hello">
    <p>{{msg}}</p>
    <p style="color: #f80000">{{msgTest2}}</p>
    <button @click="changeMsg">changeMsg</button>
    <button @click="changeParentMsg" style="background: #ddd">changeMsgFromTest1</button>
  </div>
</template>

<script>
import ChildTestBus from '../bus/ChildTest'
export default {
  name: 'ChildTest1',
  props: ['msg'],
  data () {
    return {
      msgTest2: null
    }
  },
  methods: {
    setMsgTest2 (val) {
      this.msgTest2 = val
    },
    changeMsg () {
      this.$emit('changeMsg', 'child change test msg')
    },
    changeParentMsg () {
      ChildTestBus.$emit('changeMsg', 'change msg from childTest1')
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
// ChildTest2.vue

<template>
  <div class="hello">
    <p style="color: blue">{{msgTest2}}</p>
    <button @click="changeMsg">changeMsgFromTest2</button>
  </div>
</template>

<script>
import ChildTestBus from '../bus/ChildTest'
export default {
  name: 'ChildTest2',
  props: ['msg'],
  data () {
    return {
      msgTest2: 'msg in childTest2'
    }
  },
  methods: {
    changeMsg () {
      ChildTestBus.$emit('changeMsg', 'change msg from childTest2')
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
// ChildTest.js

import Vue from 'Vue'
export default new Vue()

上述就能夠實現複雜點的組件通信了,這裏有着注意點,當你使用bus時,經過$on事件獲取消失時,得在組件註銷時解除監聽。blog

這個的缺點時當你的應用比較大時,這個觸發和監聽信息的代碼須要在多處使用,這樣咱們就須要統一管理了,既便於維護,也方便理解事件

這個時候就能夠用到vuex ,詳情下級分解ip