码迷,mamicode.com
首页 > 其他好文 > 详细

vue组件间通信6种方式

时间:2021-05-24 07:49:37      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:使用场景   初始   转换   http   ram   cas   menu   pad   传递数据   

技术图片

 

 

 如上图所示,A和B 、  B和C、B和D都是父子关系,C和D是兄弟关系,A和C 是隔代关系

 针对不同的使用场景,如何选择行之有效的通信方式? 这是我们要探讨的。vue组件间通信的集中方式,如props、$emit/$on、 vuex、$parent/$children

 

方法一、props / $emit 

父组件A通过props的方式向子组件B传递,B to A 通过在B组件中$emit, A 组件中v-on的方式实现。

1. 父组件向子组件传值

 接下来我们通过一个例子,说明父组件如何向子组件传递值: 在子组件Son.vue 中如何获取组件Parent.vue 中的数据 users: [‘xz,‘xp‘,‘mimi‘]

  

// Parent.vue 父组件
<template>
  <div id="app">
    <Children :users="users"></Children>
  </div>
</template>

<script>
  import Children from ‘./Children‘
  export default {
    name: "Parent",
    components: {
      Children
    },
    data() {
      return {
        users: [‘zx‘,‘zt‘,‘zy‘]
      }
    }
  }
</script>

<style scoped>

</style>

 

// 子组件
<template>
  <div class="hello">
    <ul>
      <li v-for="user in users">{{user}} 我问问</li>// 遍历传递过来的值,然后呈现到页面
    </ul>
  </div>
</template>

<script>
  export default {
    name: "children",
    props:{
      users: {
        type: Array,
        required: true
      }
    }
  }
</script>

<style scoped>

</style>

技术图片

总结: 父组件通过props 向下传递数据给子组件。 注:组件中的数据共有三种形式: data、props、computed

 

2. 子组件向父组件传值(通过事件形式)$emit

// 子组件 children.vue
<template>
  <div class="hello">
<!--    <ul>-->
<!--      <li v-for="user in users">{{user}} 我问问</li>// 遍历传递过来的值,然后呈现到页面-->
<!--    </ul>-->

    <button @click="toParamParent">子向父传值</button>
  </div>
</template>

<script>
  export default {
    name: "children",
    // props:{
    //   users: {
    //     type: Array,
    //     required: true
    //   }
    // },
    methods: {
      toParamParent() {
        this.$emit(‘childrenToParent‘,‘ni hao mimi)
      }
    }
  }
</script>

<style scoped>

</style>

 

// 父组件
<style>
  #app { margin: 100px; }
  button {
    padding: 10px;
    background:  blue;
    color: #fff;
    margin:20px;
  }
</style>
<template>
  <div id="app">
<!--    <Children :users="users"></Children>-->
    <Children @childrenToParent="updateHtml"></Children>
    <h1>{{title}}</h1>
    <h2>{{childrenParam}}</h2>

  </div>
</template>

<script>
  import Children from ‘./Children‘
  export default {
    name: "Parent",
    components: {
      Children
    },
    data() {
      return {
        users: [‘zx‘,‘zt‘,‘zy‘],
        title: ‘触发button, 子组件传递数据‘,
        childrenParam: ‘‘
      }
    },
    methods: {
      updateHtml(e){
        // console.log(e)  e是传递过来的数据 ‘ni hao mimi‘
        this.childrenParam = e
      }
    }
  }
</script>

<style scoped>

</style>

技术图片

总结: 子组件通过events给父组件发送消息,实际上就是子组件把自己的数据发送到父组件

 

方法二、 bus组件通信 $emit、$on

这种方法通过一个空的Vue实例作为中央事件总线(事件中心), 用它来出发事件和监听事件,巧妙二轻量的实现了任何组件间的通信,包括父子、兄弟、跨级。  当我们的项目比较大时,可以选择状态更好的解决方法vuex。

实现方式

bus

utils - bus.js

import Vue from ‘vue‘
const bus = new Vue()
export default bus

 

一、传值

发送信息 A.vue

import bus from ‘@/utils/bus‘

第一个参数为标志变量,第二个参数为通信的值

bus.$emit(‘message‘,‘hello‘)

接收信息 B.vue

import bus from ‘@/utils/bus‘

第一个参数为标志变量,第二个参数为通信的值

bus.$on(‘message‘, (e)=> {
   console.log(e);   // 传递过来的值
})

 

demo:

<div id="itany">
    <my-a></my-a>
    <my-b></my-b>
    <my-c></my-c>
</div>
<template id="a">
  <div>
    <h3>A组件:{{name}}</h3>
    <button @click="send">将数据发送给C组件</button>
  </div>
</template>
<template id="b">
  <div>
    <h3>B组件:{{age}}</h3>
    <button @click="send">将数组发送给C组件</button>
  </div>
</template>
<template id="c">
  <div>
    <h3>C组件:{{name}},{{age}}</h3>
  </div>
</template>
<script>
var Event = new Vue();//定义一个空的Vue实例
var A = {
    template: ‘#a‘,
    data() {
      return {
        name: ‘tom‘
      }
    },
    methods: {
      send() {
        Event.$emit(‘data-a‘, this.name);
      }
    }
}
var B = {
    template: ‘#b‘,
    data() {
      return {
        age: 20
      }
    },
    methods: {
      send() {
        Event.$emit(‘data-b‘, this.age);
      }
    }
}
var C = {
    template: ‘#c‘,
    data() {
      return {
        name: ‘‘,
        age: ""
      }
    },
    mounted() {//在模板编译完成后执行
     Event.$on(‘data-a‘,name => {
         this.name = name;//箭头函数内部不会产生新的this,这边如果不用=>,this指代Event
     })
     Event.$on(‘data-b‘,age => {
         this.age = age;
     })
    }
}
var vm = new Vue({
    el: ‘#itany‘,
    components: {
      ‘my-a‘: A,
      ‘my-b‘: B,
      ‘my-c‘: C
    }
});    
</script>

 

二、调用方法

一个组件A调用另一个组件B的方法

B组件的方法

import bus from ‘@/utils/bus‘
mounted(){
  bus.$on(‘testA‘, this.testA)  
}
testA() {
  console.log(‘B组价的方法,由A组件调用‘)
}

 

A组件调用

import bus from ‘@/utils/bus‘
mounted() {
  bus.$emit(‘testA‘)
}

 

 

方法三、vuex

技术图片

 

1. 简要介绍Vuex原理

Vuex实现了一个单向数据流,在全局拥有一个State存放数据,当组件要更改State中的数据时,必须通过Mutation进行。Mutation同时提供了订阅者模式供外部插件调用获取State数据的更新。而当所有异步操作(常见于调用后端接口异步获取更新数据)或批量的同步操作需要走Action, 但Action也是无法直接修改State的,还是需要通过Mutation来修改State的数据,最后,根据State的变化,渲染到视图上。

 

2. vuex中有五种默认的基本属性

1.  state:   vuex 的基本数据,用来存储变量, 相当于vue中的data

2.  mutations: 更改vuex中state的状态唯一方法, 是同步的, 在组件中使用this.$store.commit(‘‘,parmas).  这个和我们组件中的自定义事件类似

3.  actions:   actions提交的就是mutations,而不是直接变更状态,异步操作。  在组件中使用this.$store.dispath("")

4.  getters:   对数据获取之前的再次编译,可以理解为store的计算属性。我们在组件中使用$store.getters.fun()

5.  module

 

3. Vuex与locastorage

vuex是vue的状态管理器,存储的数据是响应式的,但是并不会保存起来,刷新之后就回到了初始状态,具体做法应该在vuex里数据改变的时候,把数据拷贝一份保存到localStorage里面,刷新之后,如果localStorage里面有保存的数据,取出来再替换store里的state。

let defaultCity = "上海"
try {  // 用户关闭了本地存储功能,此时在外层加个try...catch
    
  if(!defaultCity) {
     defaultCity = JSON.parse(localStorage.getItem(‘defaultCity‘))
   }
} catch(e){}

export default new Vuex.Store({
   state: {
      city: defaultCity
   },
   mutations: {
     changeCity(state,city) {
        state.city = city
    }

      try{
        localStorage.setItem(‘defaultCity‘, JSON.stringify(state.city));
      // 数据改变的时候把数据拷贝一份保存到localStorage中
      } catch(e) {

      }
   }
 
})

这里需要注意的是: 由于vuex里,我们保存的状态,都是数组,而localStorage只支持字符串,所以需要JSON转换:

JSON.stringify(state.menuList);      // array -> string
JSON.parse(window.localStorage.getItem(‘menuList‘));     // string --> array

 

vue组件间通信6种方式

标签:使用场景   初始   转换   http   ram   cas   menu   pad   传递数据   

原文地址:https://www.cnblogs.com/yongzhu/p/14764265.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!