文章目录
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、Vuex
与localStorage
结合实现本地永久存储,刷新页面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进行引入
注意2:params传值一刷新就没了,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