首页 > 其他分享 >vue基础6种通信方式

vue基础6种通信方式

时间:2023-02-20 23:26:11浏览次数:28  
标签:vue 方式 数据 通信 state props 组件 testData store

1 props

父组件 Father 子组件 Son

//父组件给子组件传递参数
<Son name="何世蟒" sex="男" :age="22" />
//子组件接收参数
//方式一
props:['name','sex','age']
//方式二 限制接受数据的数据类型
props:{
	name:String,
    age:Number,
    sex:String,
}
//方式三 限定参数 默认值 以及必要性
props:{
   	name:{
        type:String, //限定数据类型
        required:true, //是否必须
    },
    age:{
        type:Number,
        default:18,	//默认值18
    }
}
///////////////////////////////////////////////////
//注意:props 子组件给父组件传递参数
   // 1.在父组件中定义一个函数
   methods:{
       getSonData(testData){
           console.log("父组件接收到子组件数据",testData)
       }
   }
   //2.函数传给子组件
    <Son :getSonData="getSonData"/>
   //3.子组件接收函数
     props:['getSonData']
   //4.子组件通过任意方式调用该函数并传递参数
    data(){
        return{
            testData:'我是子组件数据'
        }
    }
    mounted(){
        this.getSonData(this.testData)
    }
/////////////////////////////////////////////////////////////////////////////
//注意路由也可以props传递参数
//路由luYou1给luYou2传递参数
//原始方法
    {	
        name:'luYou1'
        path:'/luyou1',
        component:LuYou1,
    }
    {
        name:'luYou2'
        path:'/luyou2',
        component:LuYou2,
    }
//  在luYou1中
    <router-link
		:to="{
  		name:'luYou2',
  		query: {wo:dataList.wo , shuju:dataList.shuju },
	}"
    >点击我给路由2传递参数</router-link>
    
    data(){
        return{
            dataList:{
                wo:'我是'
                shuju:'数据'
            }
        }
    }
 //在luYou2中 
	<template>
		<h2> {{$route.query.wo}} {{$route.query.shuju}} </h2>
	</template>
////////////////////////////////////////////////////////////
//路由luYou1给luYou2传递参数
//路由写法
    {
        name:'luYou2'
        path:'/luyou2',
        component:LuYou2,
		//第一种写法
		props:{wo:'我是写死',shuju:'的数据'}//此时wo和shuju中的数据为死数据
    }
//在luYou2中 
	<template>
		<h2> {{wo}} {{shuju}} </h2>
	</template>
	props['wo','shuju']
//	props第二种写法////////////////////////////////////////////////
    {
        name:'luYou2'
        path:'/luyou2/:wo/:shuju',
        component:LuYou2,
		//第二种
		props:true//若props为真,则会将路由所接收的所有params参数以props形式传给luYou2
    }
//luYou1中
    <router-link
		:to="{
  		name:'luYou2',
  		params: {wo:dataList.wo , shuju:dataList.shuju },
	}"  
    >点击我给路由2传递参数</router-link>
//luYou2中
	<template>
		<h2> {{wo}} {{shuju}} </h2>
	</template>
	props['wo','shuju']
//props第三种写法////////////////////////////////////////////////////
    {
        name:'luYou2'
        path:'/luyou2',
        component:LuYou2,
		//第三种
		props($route){
			return{ wo:$route.query.wo , shuju:$route.query.shuju }
		}
    }
//luYou1中
    <router-link
		:to="{
  		name:'luYou2',
  		query: {wo:dataList.wo , shuju:dataList.shuju },
	}"  
    >点击我给路由2传递参数</router-link>
//luYou2中
	<template>
		<h2> {{wo}} {{shuju}} </h2>
	</template>
	props['wo','shuju']

2 自定义事件

//一 子组件给父组件传信
//1.在父组件中给子组件绑定一个自定义事件,事件名ziDingYiShiJIan
//绑定的方法名 getSonData
<Son  v-on:ziDingYiShiJIan="getSonData"  />
<Son  @ziDingYiShiJIan="getSonData"  />
<script>
//2.编写方法 getSonData
methods:{
	getSonData(testData){
		console.log('我是Son组件传来的数据',testData)
	}
}
//3.在子组件中通过任意方式触发自定义事件
data(){
	return{
	testData:'我是子组件数据'
	}
}
mounted(){
	//$emit 调用自定义事件 第一个参数为事件名,后面跟参数
	this.$emit('ziDingYiShiJIan',this.testData)
}
/////////////////////////////////////////////////////////
// 一 父组件给子组件绑定自定义事件 可以通过ref绑定
//1.它通过ref绑定
<Son  ref="son">
//2.在生命周期mounted中拿到ref的Son
mounted(){
    //this.$refs.son  拿到子组件Son的实例对象 
    //$on 在实例对象上绑定自定义事件
    //事件名ziDingYiShiJIan  回调函数  getSonData
    this.$refs.son.$on('ziDingYiShiJIan',getSonData)
}
//3.在Son组件中触发该自定义事件触发方式如上一致
</script>

3 全局事件总线 $bus

<script>
//理解式	    甲方给第三方绑定自定义事件       乙触发甲方给第三方绑定的自定义事件
//1. 在main.js中定义第三方组件  Demo
const Demo = Vue.extend({})
//2.将Demo组件进行使用 因没办法<Demo/>标签式使用,此处实例化一个Demo
const d =new Demo()
//3.给vue原型对象Vue.prototype添加x属性 
//将实例化的Demo组件d放在vue的原型对象上prototype的x属性上
Vue.prototype.x=d
//4.组件甲发送数据
//		在组建甲中触发第三方绑定的事件
data(){
	return{
	testData:'我是组件甲中的数据'
	}
}
this.x.$emit('fangFa',this.testData)
//5.组件乙接收数据
//		在组建乙中给第三方绑定一个自定义事件,并调用一个函数
this.x.$on('fangFa',(testData)=>{
	console.log('我是组件乙,我接收到数据',testData)
})
///////////////////////////////////////////////////////////////
//正规格式
new Vue({
  el: '#app',
  components: { App },
  template: '<App/>',
  beforeCreate(){//生命周期钩子 组件数据代理之前
    Vue.prototype.$bus=this//全局事件总线 此处的$bus为上方的x
  },
  beforeDestroy(){//生命周期钩子组件销毁前
      this.$bus.$off('事件名'),//销毁指定自定义事件
      this.$bus.$off(),//销毁全部自定义事件  
  }
})
 
</script>

4 发布与订阅 pubsub-js

pubsub.js ------ publish 发布 subscribe 订阅

<script>
//1. 安装pubsub-js   
//	npm i pubsub-js
//2.在使用的组件中引入pubsub-js
	import pubsub from 'pubsub-js'
//3.订阅消息  收到数据  相当于绑定事件
	mounted(){
		pubsub.subscribe('xiaoxi',(msgName,testData)=>{
            //此时函数的第一个参数msgName为消息名xiaoxi,第二个参数才是数据
			console.log('有人发布了xiaoxi,xiaoxi的回调执行了',testData)
		})
	}
 //4.发布消息
    data(){
        return{
            testData:"我发布了消息"
        }
    }
    pubsub.publish('xiaoxi',this.testData) 
 //5.取消订阅的消息
    beforeDestroy(){
        //消息订阅时每一个订阅的消息有一个id
        //将订阅消息的id赋给pubId
        //this.pubId= pubsub.subscribe('xiaoxi',(msgName,testData)=>{     
		//console.log('有人发布了xiaoxi,xiaoxi的回调执行了',testData)
		//})
        pubsub.unsubscribe(this.pubId)//取消订阅参数为每个订阅的返回值id
    }
</script>

5 Vuex

1 vuex的安装及创建

<script>
//1.安装vuex 
//	npm i vuex@3
//2.在src目录下创建store文件夹 并创建index.js文件
	import Vue from 'vue'  	//在index文件中引入vue 
	import Vuex from 'Vuex'	//在index文件中引入vuex
	Vue.use(Vuex)			//使用Vuex插件
	
	const state={}				//储存vuex中的数据
	const mutation={}				//用于操作state 中的数据
	const actions={}				//响应组件中的动作
	const getters{}				//对state中的数据进行处理
//	创建store对象并对外暴露
	export default new Vuex.Store({
		state,
		mutation,
		actions,
        getters,
	})
//3.在main.js中引入文件夹store
    import store from './store'
//4.在vue实例化中添加$store
    new Vue({
  		el: '#app',
  		components: { App },
 		template: '<App/>',
		store,	//添加$store
	})
</script>

2 vuex的使用

<script>
//store文件夹index.js 中
    const state={		//储存vuex中的数据
      	testData:'我是vuex中的数据',
        num:20
    }				
	const mutation={	//用于操作state 中的数据
        //第一个参数为对象包含state中的全部数据
        //第二个为传过来的值
        SETSTATEDATA(state,value){
            state.testData=value//③给state中的的数据data赋值
        }
    }				
	const actions={	//响应组件中的动作
        //第一个参数是一个对象,第二个参数是传来的数据
        setStateData(context,value){
            //② 将调用mutation中的SETSTATEDATA,将数据传过去
            context.commit('SETSTATEDATA',value)
        }
    }
    const getters={
        updata(state){//对data中的数据进行操作
            state.num=state.num-1
        }
    }
//组件中修改vuex的数据
    data(){
        return{
            setData:'把我赋值给state中的testData'
        }
    },
    mounted(){
        fuZhi(){
            //① 调用Vuex中的actions中的方法
     		this.$store.dispatch('setStateData',this.setData)
            //因为只是单纯的修改数据可以不经过actions进行响应动作
            //可以略过setStateData的调用直接写为跳过②直接③
            this.$store.commit('SETSTATEDATA',this.setData)  
        }
    },
//组件中读取state中的数据   读取getters中的数据
    this.$store.state.testData 	this.$store.getters.updata
-----------------------------------------------------------------
	//组件中读取vuex中的数据进行简写
    computed:{
        testData(){
        	return this.$store.state.testData
    	},
        updata(){
            return this.$store.getters.updata
        }
    },
    //此时读取时只需要读取 this.testData()
    //再次简写在读取数据的vue组件中引入
    import { mapState,mapGetters,mapMutations,mapActions} from 'vuex'
    computed:{
        //第一个testData指组件计算方法中定义的函数名
        //第二个testData vuex state中的变量testData的名子
        //... 表示将mapState中的对象中的属性添加到computed中
		...mapState({testData:'testData'}),  //第一种对象写法
        //此时生成的计算属性明在与读取的属性名一致都为testData
        ...mapState(['testData']),			 //第二种数组写法
       	//读取getters中的数据简写
        ...mapGetters({updata:'updata'})      //第一种对象写法
        ...mapGetters(['updata']),			 //第二种数组写法
    }
    //此时读取时只需要读取 this.testData()  this.updata()
 --------------------------------------------------------------------
 //修改vuex中数据简写 引入mapMutations
 //原来写法
        //fuZhi(){
     	//	 this.$store.commit('SETSTATEDATA',this.setData)  
        //}  
 //修改后
    methods:{
        ...mapMutations({fuZhi:'SETSTATEDATA'}) //第一种对象写法
        //此时按原代码走仍会报错因为原代码函数不含参数
        //没有传递参数,mapMutations不知道传的参数为this.setData,则报错
        //将函数出发改为传参函数,并通过事件触发
        //methods:{
        //   fuZhi(setData){
     	//		 this.$store.commit('SETSTATEDATA',this.setData)  
        //	} 
        //},
        //mounted(){ fuZhi(this.setData) }
        //此时即可 
        ...mapMutations(['SETSTATEDATA'])		//第二种数组写法
        //数组写法时组件中生成的函数名也为	SETSTATEDATA
        //mounted(){ SETSTATEDATA(this.setData) } 
    }
 -----------------------------------------------------------------------
//原来写法
       	//fuZhi(){
     	//	this.$store.dispatch('setStateData',this.setData)
 		//}  
//修改后
    methods:{
        ...mapActions({fuZhi:'setStateData'}) 	//第一种对象写法
       	//此时仍会出现传参问题 需要改为传参函数
        //mounted(){ fuZhi(this.setData) } 
        ...mapActions(['setStateData'])		//第二种数组写法
        //mounted(){ setStateData(this.setData) } 
    }
</script>

6 插槽

1 默认插槽

//父组件中
<Son>
	<h1> 让我在Son组件中显示1 </h1>
</Son>
//子组件中
<template>
  <div class="category">
    <slot> 我是默认数据,父组件中没有数据过来时默认显示我 </slot>
  </div>
</template>

2 具名插槽

//父组件中
<Son>
	<h1 slot="filst">让我在Son组件中显示1 </h1>
</Son>
<Son>
	<h1 slot="two">让我在Son组件中显示2 </h1>
</Son>
<Son>
    <template v-slot:three>  //相当于外层套了一个div 只不过该标签浏览器解析时不显示
//		v-slot:three 与 slot="three" 一样,但前者只能在template标签中使用
		<h1>让我在Son组件中显示3</h1>
		<h1>让我在Son组件中和3一起显示</h1>
	</template>
</Son>
//
//子组件中
<template>
  <div class="category">
    <slot name="filst"> 我是默认数据,父组件中没有数据过来时默认显示我1 </slot>
    <slot name="two"> 我是默认数据,父组件中没有数据过来时默认显示我2 </slot>
    <slot name="three"> 我是默认数据,父组件中没有数据过来时默认显示我3</slot>
  </div>
</template>

3 作用域插槽

//父组件中
<Son>
    //getTestData是一个对象,含有子组件Son传来的数据testData
    <template :slot-scope="getTestData">
		<h1>{{getTestData.testData}} </h1>
	</template>
</Son>
<Son>
    //getTestData是一个对象,含有子组件Son传来的数据testData
    <template :slot-scope="{testData}">
		//:slot-scope="{testData} 机构赋值,效果和上面一样
		<h1>{{testData}} </h1>
	</template>
</Son>
//子组件中
<template>
  <div class="category">
    <slot testData:="testData"> 我是默认数据,父组件中没有数据过来时默认显示我 </slot>
  </div>
</template>
data(){
	return{
		testData:"我是数据我在Son组件中,请将我传给父组件"
	}
}

标签:vue,方式,数据,通信,state,props,组件,testData,store
From: https://www.cnblogs.com/my-hsm/p/17139379.html

相关文章

  • 组件通信深入
    1.组件通信自定义事件深入父组件给子组件绑定原生DOM事件<template><div><!--此处的Son为组件Father的子组件--><Son@click="Dome"></Son> ......
  • Vue-路由(vue-roter)
    1.路由的使用1.路由的安装vue-routernpmivue-router@3vue3中使用router4版本,vue2中使用router3版本2.应用路由插件①在src目录下创建router文件夹作为路......
  • vue-vue项目创建、es6导入导出语法、scoped使用
    1.vue-cil下载和创建1.1下载安装vue-cli: 我们使用npm(并行)下载是是从国外的网站下载,所以速度会比较慢,建议使用cnpm(串行),cnpm要从淘宝镜像下载。 步骤: 1.安装cnp......
  • vue2,nginx,redis,tomcat,Java的关系
    Java作为一种广泛应用的编程语言,在后端开发中扮演着重要的角色。Java后端开发不仅需要掌握Java语言的基本语法和相关技术,还需要熟悉一些其他的技术和工具,如Vue2、Nginx、Re......
  • Vue 非单文件组件(不常用)3步骤(创建、注册、使用)
    Vue中使用组件的三大步骤:1、定义组件(创建)2、注册组件3、使用组件(写组件标签)一、如何定义一个组件?使用Vue.extend(options)创建,其中options和newVue(options)时传入......
  • Vue-cli
    1.什么是 vue-clivue-cli(俗称:vue 脚手架)是vue官方提供的、快速生成vue工程化项目的工具。特点:①开箱即用,②基于 webpack,③功能丰富且易于扩展,④支持创建v......
  • 组件间通信
    组件其他根组件和组件一些问题 -newVew()--->管理div---》根组件-自己再定义的全局,局部是组件-组件有自己的html,css,js---》数据,事件。。。-在组件中......
  • vue项目
    vue-cli创建项目前端做成项目---》使用工具(vue-cli),创建出vue项目,单页面应用,组件化开发把xx.vue,ts,saa,less---》编译---》在浏览器中执行vue-cli创建项目开发,在......
  • Vue3之v-show不能放置于自定义组件
    控制台警告Runtimedirectiveusedoncomponentwithnon-elementrootnode.Thedirectiveswillnotfunctionasintended.原因意思是自定义指令不能放到组件上,而......
  • vue day06
    上节回顾#1组件使用 -局部-全局#2组件间通信 -一旦组件化开发----》组件间通信-父传子:自定义属性-子传父:自定义事件-ref属性: ......