Vue组件间传值
1. 父组件向子组件传值 props
父组件
<template>
<div>
<h1>我是父组件</h1>
<!--
title2名称与子组件prop中的名称一致 ="title1" 与父组件中data数据中的title1名称一致
-->
<children :title2="title1" :content2="content1"></children>
</div>
</template>>
<script>
import Children from "./Children";
export default {
data() {
return {
title1: "我是父组件的标题",
content1: "我是内容"
};
},
components: {
Children
}
};
</script>
子组件
<template>
<div>
<h1>children</h1>
<span>{{title2}}</span>
<br />
<span>{{content2}}</span>
</div>
</template>>
<script>
export default {
props: {
title2: String,
content2: String
}
};
</script>>
要点:
- 父组件中引入子组件、注册子组件,template中使用子组件;import、components
- 子组件中props创建一个属性,接收父组件传的值,在template中使用
{{contents}}
- 父组件中的
title
与子组件中prop
添加的属性名称一致;="title
与父组件中data数据的title一致
2. 子组件向父组件传值 $emit
子组件
<template>
<div>
<h1>children</h1>
<button @click="sendTOParent">向父组件传值</button>
</div>
</template>>
<script>
export default {
data() {
return {
data: "子组件中的信息"
};
},
methods:{
sendTOParent(){
this.$emit('listenToChildEvent',this.data)
}
}
};
</script>>
父组件
<template>
<div>
<h1>我是父组件</h1>
<children @listenToChildEvent = 'showMsgfromChild'></children>
</div>
</template>>
<script>
import Children from "./Children";
export default {
data() {
return {
};
},
methods:{
showMsgfromChild(data){
console.log(data)
}
},
components: {
Children
},
};
</script>
要点
- 子组件中需要以某种方式(如点击)来触发一个自定义事件
- 将需要传的值作为
$emit
的第二个参数,该值将作为实参传给响应自定义事件的方法 - 在父组件中注册子组件并在子组件标签上绑定对应自定义事件的监听
- 具体流程
sendTOParent
=>listenToChildEvent
=>showMsgfromChild
3. 总线机制bus
通过一个空的Vue实例作为中央事件总线,用它来触发事件和监听事件,巧妙而轻量的实现了任何组件之间的通信,包括父子、兄弟、跨级等。
公共bus.js文件
import Vue from 'vue'
export default new Vue()
组件A代码
<template>
<div>
A组件:
<span>{{elementValue}}</span>
<input type="button" value="点击触发" @click="elementByValue">
</div>
</template>
<script>
// 引入公共的bus,来做为中间传达的工具
import Bus from './bus.js'
export default {
data () {
return {
elementValue: 4
}
},
methods: {
elementByValue() {
// 使用$emit来传递参数
Bus.$emit('sendVal', this.elementValue)
}
}
}
</script>
组件B代码
<template>
<div>
B组件:
<input type="button" value="点击触发" @click="getData">
<span>{{num}}</span>
</div>
</template>
<script>
import Bus from './bus.js'
export default {
data () {
return {
num: 0
}
},
mounted() {
var vm = this
// 用$on事件来接收参数
Bus.$on('sendVal', (data) => {
console.log(data)
vm.num= data
})
},
methods: {
getData() {
this.num++
}
},
destroyed () {
// 取消对bus事件的监听
// 事件订阅是通过Bus对象完成的 与组件无关
Bus.$off('sendVal')
}
}
</script>
要点
- 在项目中定义
bus.js
文件,并注册一个Vue
实例 - 页面A导入
Vue
实例,并通过Bus.$emit('sendVal', this.elementValue)
方法进行传值 - 页面B导入
Vue
实例,并通过Bus.$on('sendVal', (data) => { })
方法监听其他组件的传值
4. vuex
当前方法写的不够完善,需要进一步的改进 \color{red}当前方法写的不够完善,需要进一步的改进 当前方法写的不够完善,需要进一步的改进
主要方法是使用store空间存储值并进行获取或监测
vuex中的store空间存值
// src/store/modules/home.js
const homeModule: any = {
time: {
change: 0,
},
},
mutations: {},
actions: {},
};
export default homeModule;
页面a修改store空间值
import { useStore } from '/@/store/index';
const store = useStore();
store.state.homeParams.time.change = 1;
页面b监听store空间值的修改并作出响应
import { useStore } from '/@/store/index';
const store = useStore();
<script lang="ts">
export default defineComponent({
setup() {
watch(
() => store.state.homeParams.time.change,
() => {
getTime();
}
)
}
});
<script>
5. $parent
/$children
&& ref
代码待完善
- $parent / $children: 访问父/子实例
- ref: 如果在普通DOM元素上使用,引用指向的时DOM元素;如果在子组件上,引用指向组件实例。
两种都是直接得到组件实例,使用后可以直接调用组件的方法或访问数据
6. $attrs
/ $listeners
代码待实现
7. provide
/ inject
代码待实现
- 成对出现:provide和inject是成对出现的
- 作用:用于父组件向子孙组件传递数据
- 使用方法:provide在父组件中返回要传给下级的数据,inject在需要使用这个数据的子孙辈组件中注入数据
- 使用场景:由于vue有$parent属性可以让子组件访问父组件,但是孙组件想要访问祖先组件比较困难,通过provide/inject可以轻松实现跨级访问父组件的数据
参考:
https://blog.youkuaiyun.com/weixin_44834981/article/details/119797571
https://blog.youkuaiyun.com/weixin_42566993/article/details/127045794