vue: 从组件通讯到vuex (上)

关于vue之间的组件通讯

1: prop,refs 父组件 => 子组件

1) prop

// 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) refs

// 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 子组件 => 父组件

// 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。

3: vue bus 独立组件 => 独立组件 (父 => 子 子 => 父)

// 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事件获取消失时,得在组件注销时解除监听。

这个的缺点时当你的应用比较大时,这个触发和监听信息的代码需要在多处使用,这样我们就需要统一管理了,既便于维护,也方便理解

这个时候就可以用到vuex ,详情下级分解

 

posted @ 2018-03-02 21:00  t_evening  阅读(184)  评论(0编辑  收藏  举报