九段刀客:vue组件通讯

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_35958891/article/details/102487325

组件通信的方法:

1、props和emit
2、vuex
3、bus
4、children和parent
5、ref

props和emit()

  • 说明:props和emit用于父子组件通讯,props父组件向子组件中传值,emit方法用于子组件向父组件中传值。
  • 使用场景:一般用于父子组件通讯,封装公用组件中使用。
    父组件
<e-test title="标题" @change="getValue"></e-test>
<script>
	export default {
		name:'parent',
		methods:{
			getValue(value){
				console.log(value)
			}
		}
	}
</script>

子组件

<template>
	<div>
		<p>{{title}}</p>
		<button @click="toClick">点击</button>
	</div>
</template>

<script>
	export default {
		name:'test',
		props:['title'],
		methods:{
			toClick(){
				this.$emit('change','你要传入的值')
			}
		}
	}
</script>

vuex

  • 说明:一个公共的仓库,数据改变视图也可以改变,f5刷新页面时数据会丢失
  • 使用场景:用于存放用户信息、token、公用组件的数据等公用数据
    vuex有5个属性,state、modules、getters、mutations、actions
  • state:类似data用于存储数据
  • modules:用于区分不同的模块,每个模块中有除modules外的属性
  • getters:类似于computed计算属性
  • mutations:用于存放同步的方法
  • actions:用于存放异步的方法

示例

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use( Vuex )
import components from './modules/components'
const store = new Vuex.Store( {
  modules: {
    components
  }
} )
export default store

模块中

// 所有公用组件的请求,避免组件多次重复请求统一处理
import { initData } from '@/api/data';
const components = {
  state: {
    params: { page: 0, size: 10 },
    baseURL: process.env.VUE_APP_BASE_API,
    // 物料列表
    materialList: [],
    materialTotal: 0
  },
  mutations: {
    // 设置物料列表的值
    setMaterialList( state, val ) {
      state.materialList = val
    },
    setMaterialTotal( state, val ) {
      state.materialTotal = val
    }
  },
  actions: {
    // 获取物料列表
    getMaterialList( { commit, state } ) {
      let url = 'api/material'
      return new Promise( resolve => {
        initData( url, state.params, state.baseURL )
          .then( res => {
            commit( 'setMaterialList', res.content )
            commit( 'setMaterialTotal', res.totalElements )
            resolve()
          } )
      } )
    }
}
export default components

使用vuex
需要注意:mutations和actions中的方法默认是全局的,没有模块作用域限制。

import { mapState, mapActions } from "vuex";
computed: {
    ...mapState({
      materialList(state) {
        return state.components.materialList;
      },
      materialTotal(state) {
        return state.components.materialTotal;
      }
    })
  },
  methods: {
    ...mapActions(["getMaterialList"]),
    // 避免在table组件中使用初始化时多次请求
    initComponent() {
      this.$nextTick(() => {
        if (this.materialTotal) {
          this.total = this.materialTotal;
          this.data = this.materialList;
        } else {
          this.getMaterialList().then(() => {
            this.total = this.materialTotal;
            this.data = this.materialList;
          });
        }
      });
    }
    }

bus通讯

  • 说明: 可以实现非父子组件通讯
  • 使用场景:相对于vuex,bus通讯方式更加方便、灵活、简单、多用于单个模块内的非父子组件通信。
  • 举例:B组件和C组件都在A组件中,要实现B组件和C组件之间的通讯,用bus来实现比用vuex要简单得多。
    注意事项:需要在离开页面前将绑定的bus监听销毁掉
    使用方法:
    bus.js
import Vue from 'vue'
const bus = new Vue();
export default bus;

B组件中

import Bus from './bus.js'
export default{
	beforeDestory(){
		Bus.$off('test')
	},
	methods:{
		toClick(){
			Bus.$emit('test','传递的值')
		}
	}
}

C组件中

import Bus from './bus.js'
export default{
	mounted(){
		Bus.$on('test',val=>{
			console.log(val)
		})
	}
}

parent、children通讯

  • 说明:可以直接获取一级父子组件的属性和方法并且可以修改
  • 使用场景:用于父子组件的通讯

子组件中

<template>
	<div>{{name}}</div>
</template>
export default{
	data(){
		return{
			name:'测试数据'
		}
	},
	mounted(){
		this.$nextTick(()=>{
			console.log(this.$parent.age)
		})
	}
}

父组件中

<template>
	<e-test ref="test"></e-test>
</template>
export default{
data(){
		return{
			age:23
		}
	},
	mounted(){
		this.$nextTick(()=>{
			console.log(this.$children.name)
		})
	}
}

ref通讯

  • 说明:可以获取并修改子组件中的属性和方法
  • 使用场景:用于父子组件的通讯

子组件中

<template>
	<div>{{name}}</div>
</template>
export default{
	data(){
		return{
			name:'测试数据'
		}
	}
}

父组件中

<template>
	<e-test ref="test"></e-test>
</template>
export default{
	mounted(){
		this.$nextTick(()=>{
			console.log(this.$refs.test.name)
		})
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_35958891/article/details/102487325
今日推荐