Vue -> 组件通信
组件通信
:v-bind (props) $emit
在父组件中定义一个数据 父->子
data(){
return {
message: 'hello world';
}
}
template中
<child :message="message" />
通过prop属性的方式把message绑定到变量message里面
在子组件里就可以接受这个prop
props:['message']然后进行使用
template:
{{message}}
在子组件中: 子->父
methods:{
xxx(){
this.$emit('aaa','bbb')
// bbb是携带的值 当事件触发时 就会把bbb带入到$event这个变量中 赋值给message
// 所以当事件触发时最终会把message设置为bbb
}
}
在父组件中就可以监听aaa事件
<child :message="message" @aaa="message = $event" />
当事件触发最终会把message设置为bbb
回调函数(callback)
也是props + $emit
父组件中: 父->子
data(){
return {
message: '';
}
},
methods:{
changeMessage(){
this.message = 'aaa'
}
}
template:
<child :message="message" :changeMessageFn="changeMessage" /> 把changeMessage作为另外一个prop传给child
所以此时child就接收message和changeMessageFn两个prop
在子组件中:
props:['message','changeMessageFn']然后进行使用
template:
<button @click="changeMessageFn">按钮</button>
在点击时就可以执行changeMessageFn
$root $parent $children
访问根组件
this.$root.foo
// 获取根组件的数据/计算属性/方法
// 所有的子组件都可以将这个实例作为一个全局 store 来访问或使用。
在子组件中访问父组件
this.$parent.message
在父组件中访问子组件
this.$children[0].number
// [0]是因为一个父组件可以有很多子组件
// 当前实例的直接子组件。需要注意 $children 并不保证顺序,也不是响应式的。
- 对于 demo 或非常小型的有少量组件的应用来说这是很方便的。
不过这个模式扩展到中大型应用来说就不然了。因此在绝大多数情况下,我们强烈推荐使用 Vuex 来管理应用的状态。 - Vue官方文档
provide + inject 依赖注入
这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在其上下游关系成立的时间里始终生效。
provide
选项应该是一个对象或返回一个对象的函数。该对象包含可注入其子孙的 property。在该对象中你可以使用 ES2015 Symbols 作为 key,但是只在原生支持 Symbol
和 Reflect.ownKeys
的环境下可工作。
inject
一个字符串数组 或
一个对象,对象的 key 是本地的绑定名,value 是:
- 在可用的注入内容中搜索用的 key (字符串或 Symbol),或
- 一个对象,该对象的:
from
property 是在可用的注入内容中搜索用的 key (字符串或 Symbol)default
property 是降级情况下使用的 value
提示:
provide
和inject
绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的 property 还是可响应的。 - Vue官方文档
// 父级组件提供 'foo'
var Provider = {
provide: {
foo: 'bar'
},
// ...
}
// 子组件注入 'foo'
var Child = {
inject: ['foo'],
created () {
console.log(this.foo) // => "bar"
}
// ...
}
// 利用 ES2015 Symbols、函数 provide 和对象 inject:
const s = Symbol()
const Provider = {
provide () {
return {
[s]: 'foo'
}
}
}
const Child = {
inject: { s },
// ...
}
父组件中:
export default{
provide:{
message:'aaaa'
}
}
子组件中:
export default{
inject:['message']
}
template:
{{message}}
依赖注入还是有负面影响的。它将你应用程序中的组件与它们当前的组织方式耦合起来,使重构变得更加困难。同时所提供的 property 是非响应式的。这是出于设计的考虑,因为使用它们来创建一个中心化规模化的数据跟使用
$root
做这件事都是不够好的。如果你想要共享的这个 property 是你的应用特有的,而不是通用化的,或者如果你想在祖先组件中更新所提供的数据,那么这意味着你可能需要换用一个像 Vuex这样真正的状态管理方案了。 - Vue官方文档
$attrs + $listeners
三级组件: parent child grandchild
$attrs:
parent中:
定义message 并在child中:message="message"
child中:
给grandchild组件绑定
<grandchild v-bind="$attrs"> //$attrs属性包括了parent中传过来的message
grandchild中:
template:
{{$attrs.message}}
$listeners:
parent:
methods:{
aaa(){
this.message='aaa'
}
}
在child标签上定义了一个事件监听器
<child @aaa="aaa">
在child中就可以通过:
<button @click="$listeners.aaa">按钮</button> 访问到
此时就可以执行绑定的事件处理函数aaa 把name改为aaa 在点击按钮的时候就会修改
ref refs
ref
被用来给元素或子组件注册引用信息。引用信息将会注册在父组件的 $refs
对象上。
父组件中:
<child ref="childaaa">
methods:{
aaa(){
使用:
this.$refs.childaaa可以获取到这个组件实例child 就可以访问属性 执行方法
this.$refs.childaaa.xxx
this.$refs.childaaa.xxx()
}
}
// $refs 只会在组件渲染完成之后生效,并且它们不是响应式的。
// 应该避免在模板或计算属性中访问 $refs。
兄弟组件通信
需求:child1点击按钮可以修改数据传到child2中
props + $emit 经过父亲
child1:
使用$emit方式 在父组件中监听发射的事件 然后就可以修改数据值
父组件中的值修改了 就会传递给child1和child2 所以child2就可以接收数据了
EventBus = new Vue 不经过父亲 一:$emit 二:监听
main.js中:
export const eventBus = new Vue() //eventBus实际上就是vue的实例 所以可以在main.js创建并导出
然后就可以在child1中使用eventBus
child1:
eventBus.$emit('aaa','bbb') //因为eventBus是vue实例 所以存在$emit方法 并携带bbb
child2:
created(){
eventBus.$on('aaa',(name)=>{
this.name=name // name为携带的bbb
})
}
具体的总线学习内容可参见 Vue-EventBus
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· DeepSeek 解答了困扰我五年的技术问题。时代确实变了!
· 本地部署DeepSeek后,没有好看的交互界面怎么行!
· 趁着过年的时候手搓了一个低代码框架
· 推荐一个DeepSeek 大模型的免费 API 项目!兼容OpenAI接口!