首页 > 其他分享 >Vue的六种基本通信方式

Vue的六种基本通信方式

时间:2023-02-20 07:55:05浏览次数:40  
标签:Vue 六种 通信 shuju wo state 组件 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,六种,通信,shuju,wo,state,组件,testData,store
From: https://www.cnblogs.com/my-hsm/p/17136106.html

相关文章