vue-router路由之间传递数据、父子组件传递数据、任意组件之间传递数据、全局事件栈、本地化存储

本文全面解析了Vue中各种组件间的通信方式,包括provide/inject、$attrs/$listeners、props、.sync、$refs/$children/$parent、全局事件总线、Vuex、Vuex与localStorage结合、vue-router参数传递等,提供了丰富的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、祖孙组件之间的数据传递provide与inject

//祖组件
export default {
  provide() {     // provide是一个匿名函数,返回一个对象
    return {
      reload: this.reload,
      msg:this.msg      
    };
  },
  data(){
    return {
      msg:'hello world!' 
    }
  },
  methods: {
    reload() { console.log("C调用A的方法!"); },
  },
},

// 子、孙组件
export default {
  inject: ["reload","msg"],  
  mounted() {
    this.reload();
  },
}

2、父子/祖孙组件之间通信 $attrs/$listeners

5.1、$attrs/$listeners

  • $attrs:包含了父组件中除 class 、 style外的所有绑定的属性;
  • $listeners:包含了父作用域中的v-on所绑定的事件;

5.2、代码示例

  • 父组件
<div>
	<child :money="total"  :name="name"  @changeName="changeName" />
</div>
  • 子组件
<button> {{$attrs.money}}</button>
<child2 v-bind="$attrs"  v-on="$listeners"></child2>    // 孙组件

// this.$attrs    输出 { money:xxx, name:xxxx }
// this.$listeners   输出 {changeName:function(){}  }
  • 孙组件
<h4>{{$attrs.name}}</h4>

// this.$attrs    输出 { money:xxx, name:xxxx }
// this.$listeners   输出 {changeName:function(){}  }

3、父子组件之间传递props

分析如下

  • 实际上等同于父子组件之间,数据的传递;
  • 父传子 ---------> 父绑定属性,子props接受属性值
  • 子传父 ---------> 触发自定义事件,子触发$emit,父接收
  • 父组件触发子事件 -------> 在父组件中获取子组件的实例(可以通过在父组件中给子组件绑定ref,在父组件中获取子组件的实例,再调用子组件中相应事件即可),

编码

  • 父组件
<Child :money="total"  @calculate="calculate" />
data () {
  return {
    total: 1000
  }
},
methods:{
   calculate(num){
       //任意操作,可操作性比sync要灵活
   }
}
  • 子组件
<button @click="$emit('calculate', 900)">花钱</button>

props: ['money']

4、父子组件之间传递----.sync简略写法

  • 父组件
<child :money.sync="total"/>
<!-- 等价于 
<Child :money="total" @update:money="total=$event"/> -->
data () {
  return {
    total: 1000
  }
}
  • 子组件
<button @click="$emit('update:money', money-100)">花钱</button>

props: ['money']

5、父子组件通信 $refs, $children, $parent获取父子组件的实例来实现父子组件之间的通信

1) $refs: 父向指定子组件通信

  • $refs是包含所有有ref属性的标签对象或组件对象的容器对象
  • 通过 this.$refs.child 得到子组件对象, 从而可以直接更新其数据或调用其方法更新数据

2) $children: 父向多个子组件通信,

  • $children是所有直接子组件对象的数组
  • 通过this.$children 遍历子组件对象, 从而可以更新多个子组件的数据

3) $parent: 子组件向父组件通信

  • $parent是当前组件的父组件对象
  • 通过this.$parent 得到父组件对象, 从而可以更新父组件的数据

6、任意组件之间通信----全局事件总线

4.1、作用: 实现任意组件间通信

4.2、编码

  • 在入口main.js中,初始化Vue实例的时候,将Vue实例对象vm作为全局事件总线对象

    beforeCreate() {
        Vue.prototype.$bus = this
    }
    
  • 在某个组件中定义事件

    this.$bus.$on('eventName', (data) => { })
    
  • 在其它组件中触发事件

    this.$bus.$emit('eventName',参数data )
    

7、任意组件之间通信----Vuex状态管理器

1). 实现任意组件间通信

2). Vuex 是一个专为 Vue 应用程序设计的管理多组件共享状态数据的 Vue 插件

  • 任意组件都可以读取到Vuex中store的state对象中的数据
  • 任意组件都可以通过dispatch()或commit()来触发store去更新state中的数据
  • 一旦state中的数据发生变化, 依赖于这些数据的组件就会自动更新

3)如何引入

  • 第一步,安装vuex

    npm install vuex
    
  • 第二步,创建并导出仓库

    1、创建vuex目录,并在其下新建store.js

    2、store.js中创建仓库并导出,如下:

    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex)     //挂载到vue原型对象上
    
    var store = new Vuex.Store({    //创建仓库
         state:{},
         action:{},
         mutations:{}
    })
    export default store		//导出
    
  • 第三步,在main.js中引入并挂载仓库

    import store from './store/store.js'     //全局中引入仓库
    
    new Vue({
      el: '#app',
      store,                 // 挂载到根实例上
      template: '<App/>',
      components: { App }
    })
    
  • 第四步,访问
    this.$store

vuex的参考链接:https://blog.youkuaiyun.com/yiyueqinghui/article/details/108108602

8、VuexlocalStorage结合实现本地永久存储,刷新页面Vuex状态不变

8.1、自主修改Vuex,在相关操作中新增对localStorage的操作

1、vuex中在getters中新增localStorage.getItem()的操作。
在mutations中新增对localStorage.setItem()的设置值的操作

state:{
  catalog_id: '',
},

mutations:{
  setCatalog_id: (state, catalog_id) => {
    localStorage.setItem('catalog_id',catalog_id);
    state.catalog_id = catalog_id;
  }
},

const getters = {
  getCatalog_id: (state) => {
    state.user.catalog_id = localStorage.getItem('catalog_id');
    return state.user.catalog_id;
  }
}

2.其中一个组件中改变数据:

changeCatelogId(id){
  //触发相应的mutation事件
  this.$store.commit('setCatalog_id',id);
}

3.其他组件中监听数据的改变,并做出其他操作:

computed: {
  catalog_id(){
    return this.$store.getters.getCatalog_id;
  }
},
watch: {
  catalog_id: function(){
    this.getFileInfo();
  }
},

注意:
1、在监听数据catalog_id变化时,需要先使用computed计算出该数据在state中的值,然后再使用watch监听数据的变化,做其他操作。

2、将catalog_id直接在data中赋值,数据改变时,通过watch是监听不到的,因为data里的数据在组件加载完成后就初始化完了,只能被动改变,不能自动做出更新。

8.2、结合第三方插件 vuex-persist
//引入vuex-persist并配置
import VuexPersistence from 'vuex-persist';
const vuexLocal = new VuexPersistence({
    storage: window.localStorage
})

//引入vuex并进行配置
import Vuex from 'Vuex';
const store = new Vuex.Store({
  state: { ... },
  mutations: { ... },
  actions: { ... },
  plugins: [vuexLocal.plugin]    // 作为插件加入
}) 

vuex-persist参考链接:https://www.jianshu.com/p/a4faae6a3184

9、vue-router路由之间传递数据

9.1、query传递参数
//query传参,使用name跳转
<router-link :to="{name:'second',query:{queryId:'123'}}">跳转</router-link>
等同于
this.$router.push({
    name:'second',
    query: {
        queryId:'123'
    }
})

//query传参,使用path跳转
<router-link :to="{path:'second',query:{queryId:'123'}}">跳转</router-link>
//等同于
this.$router.push({
    path:'/second',
    query: {
       queryId:'123'
    }
})

//query传参接收
this.queryId = this.$route.query.queryId;

//路由配制
export default new Router({
  routes: [
    {
      name:'second',
	  path:'/second',
      component: HelloWorld
    }
 ]
}) 
    

query传参,类似于get方法,参数会在页面链接中显示,eg:http://localhost:8080/#/cell/merge?id=123

9.2、params传递参数

注意1使用params传参只能使用name进行引入
注意2params传值一刷新就没了,query传值刷新还存在

//params传参 使用name
 <router-link :to="{name:'second',params:{id:'123'}}"> 跳转 </router-link>
 等同于
this.$router.push({
  name:'second',
  params: {
    id:'123'
  }
})

//params接收参数
this.id = this.$route.params.id ;

//路由配制
export default new Router({
  routes: [
    {
      name:'second',
	  path:'/second',
      component: HelloWorld
    }
 ]
}) 

params传参,类似于post方法,一刷新就会消失!

9.3、动态路由传参(其实就是params传递参数,只不过参数指定了是路由器中配制的参数)
//params传参 
//使用name,同时params中必须配制动态路由中指定的参数,这里是id,也可以新增其它参数
 <router-link :to="{name:'second',params:{id:'123',age:70}}"> 动态路由 </router-link>
 //简化写法,直接写路径,等同于上面用name的写法,不过无法新增其它参数
 <router-link to="/second/123" >动态路由</router-link>  
 
 等同于
this.$router.push({
  name:'second',
  params: {
    id:'123',
    age:70
  }
})

//params接收参数
this.id = this.$route.params.id ;

//路由配制
export default new Router({
  routes: [
    {
      name:'second',
	  path:'/second/:id',   //动态路由
      component: HelloWorld
    }
 ]
}) 

注意刷新页面,动态路由配制的参数不会消失,但是新增的参数会消失,例子中是age字段。

更多案例请参考:https://blog.youkuaiyun.com/yiyueqinghui/article/details/109354984

参考链接:https://blog.youkuaiyun.com/mf_717714/article/details/81945218
参考链接:https://www.cnblogs.com/czh64/p/12066921.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值