我转过几个弯 绕过那个小雨楼
拿着蒲扇摆着衣衫渡着紧箍咒
不问天涯不停留 喝过几壶酒
不过年少白头道义放胸口
倘若明天之后 遥看前尘剑封侯
似那天上神仙无所求
朝朝暮暮君如梦醒十分不为何理由
是真是假是惶恐是无休
路过这风雨花满楼 片刻都不停留
我本这书生进京赶考留下许多愁
你问有没有时候 我叹这天道默悠悠
能否与我一醉方休
又过了几个弯 算尽天量道莫慌
踏这田园闻这芳草香
跌跌撞撞仗剑天涯折煞不枉无笔良
是梦是幻是温柔是家乡
路过这风雨花满楼 片刻都不停留
我本这书生进京赶考留下许多愁
你问有没有时候 我叹这天道默悠悠
能否与我一醉方休
路过这风雨花满楼 片刻都不停留
我本这书生进京赶考留下许多愁
你问有没有时候 我叹这天道默悠悠
能否与我一醉方休
谁能与我一醉方休
provide inject 跨组件传参 + 响应式数据
父组件与子组件的传参,使用的是props,如果是父组件与孙子组件传参,大部分可能会采用递归的方式,也就是子组件props接收,然后再props传给孙子组件。或者使用vuex。
但如果是迭代的方式,组件的层级越深,不断迭代的props会是代码越来越无法维护,冗余。
于是官方出了provide inject。
provide有父组件设置,inject由子组件接收,他们的特性:
- 祖先组件不需要知道哪些后代组件使用它提供的属性
- 后代组件不需要知道被注入的属性来自哪里
例子:
父组件
<script>
export default {
provide: {
foo: 'bar'
},
}
</script>
孙子组件
<script>
export default {
inject: ['foo'],
}
</script>
用法和props差不多,inject也有default属性
<script>
export default {
inject: {
foo:{
default:"默认值"
}
}
}
</script>
如果默认的是一个引用类型,也要像props一样,用一个工厂函数抛出
<script>
export default {
inject: {
foo:{
default: ()=> [1,2,3]
}
}
}
</script>
如果inject里的key和其他属性发生了冲突,我们可以像model那样,有一个声明
<script>
export default {
inject: {
foo1:{
from: "foo",
default: ()=> [1,2,3]
}
}
}
</script>
from表示其源。
提示:
provide
和inject
绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的 property 还是可响应的。
也就是说,如果传入的是非引用类型的值,父组件修改provide中的属性值,孙子组件并不会响应其变化。
如果是一个引用类型,那么是可以响应到父组件的变化,我们甚至可以使用一个函数来达到响应变化的效果
响应式
函数方式
父组件
<script>
export default {
data(){
return {
color:"blue"
}
},
provide() {
return {
color: this.getColor
}
},
methods:{
getColor() {
return this.color;
},
}
}
</script>
孙子组件
<template>
<span>{{color()}}</span>
</template>
<script>
export default {
inject: ['color'],
}
</script>
通过函数的方式,当父组件中data的color的值发生了变化,子组件依旧可以响应到。
注意一点,如果是传string,可以使用provide为一个对象的形式,如果你要在provide的里面通过this,来获取上下文数据,那么就要如上,使用方法的形式,return出一个对象才行。
性能上估计不太好。
引用类型{}
<script>
export default {
data(){
return {
color:{
get:"blue"
}
}
},
provide() {
return {
color: this.color
}
},
}
</script>
孙子组件
<template>
<span>{{color.get}}</span>
</template>
<script>
export default {
inject: ['color'],
}
</script>
这样依旧可以响应到变化,但是不怎么建议使用。
Vue.observable()
这是vue 2.6版本新增的一个api,用于创建一个可监控的对象,大概用起来和vuex相差不了多少,感觉就是一个小型vuex的快速建成方式。
父组件
<script>
import Vue from "vue";
export default {
provide() {
this.theme = Vue.observable({
color: "blue",
});
return {
theme: this.theme,
};
},
}
</script>
孙子组件
<template>
<span>{{theme.color}}</span>
</template>
<script>
export default {
inject: ['theme'],
}
</script>
这样也可以响应到父组件的color值变化。
但是必须是vue 2.6版本,vue-template-compiler也要同步
//升级vue版本npm
update vue -S
//或者
yarn add vue -Snpm update vue-template-compiler -D
//或者
yarn add vue-template-compiler -D
Vue.observable如何更新数据
你可以直接this.theme.color="xxx"
来更新,也可以封装一个类似于vuex的mutation方法对象集合。
import vue from 'vue';
export const store = vue.observable({count: 0});
export const mutation = {
setCount( count ){
store.count = count;
}
}
这种方式可以单独做个js文件,也可以改动一下丢在组件内。
评论(0)