父组件向子组件传递数据 props
父组件:
<template>
<div class="container">
<Child :msg="msgTxt"/>
</div>
</template>
<script>
import Child from './child.vue';
export default {
// 注册
components: {
Child
},
data() {
return {
msgTxt: "父组件文字:英雄联盟"
}
},
created(){
},
computed:{
},
methods:{
},
}
</script>
<style scoped>
.container{
background: #fff;
}
</style>
子组件
<template>
<div>
<p class="txt">{{msg}}</p>
</div>
</template>
<script>
export default {
// 父组件传过来的值
props: ['msg'],
data() {
return {
}
},
created(){
},
computed:{
},
methods:{
},
}
</script>
<style scoped>
.txt{
font-size: 16px;
}
</style>
子组件向父组件传递数据($emit的用法)
父组件
<template>
<div class="container">
<Child :list="txtArr" @emitTxt="emitTxt"/>
<div class="select">选中的游戏名称:{{selectTxt}}</div>
</div>
</template>
<script>
import Child from './child.vue';
export default {
components: {
Child
},
data() {
return {
txtArr: ['王者荣耀', '英雄联盟', '真三无双'],
selectTxt: ''
}
},
created(){
},
computed:{
},
methods:{
emitTxt(txt) {
this.selectTxt = txt;
}
},
}
</script>
<style scoped>
.container{
background: #fff;
}
.select{
margin-top: 20px;
color: #000;
font-weight: 600;
}
</style>
子组件
<template>
<div>
<p class="txt" v-for="(item, index) in list" :key="index" @click="emitClick(item)">{{item}}</p>
</div>
</template>
<script>
export default {
props: ['list'],
data() {
return {
}
},
created(){
},
computed:{
},
methods:{
emitClick(item) {
this.$emit('emitTxt', item);
}
},
}
</script>
<style scoped>
.txt{
font-size: 16px;
margin-bottom: 10px;
cursor: pointer;
}
</style>
兄弟组件之间的通信
A组件 B组件
A组件数据传递给共同的父组件 再有父组件接受后传递给B组件
另一种就是使用EventBus(事件总线),它允许两个子组件之间直接通讯,而不需要涉及父组件
方法1需要采用子传父相同,就不再赘言
方法2:
main.js
// mian.js
import Vue from 'vue'
import App from './App'
import router from './router'
Vue.prototype.$bus = new Vue(); // 设置 挂载至 vue 的原型上
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
父组件:
<template>
<div class="container">
<Child1 :list="txtArr"/>
<Child2 />
</div>
</template>
<script>
import Child1 from './child1.vue';
import Child2 from './child2.vue';
export default {
components: {
Child1,
Child2
},
data() {
return {
txtArr: ['王者荣耀', '英雄联盟', '真三无双'],
}
},
}
</script>
<style scoped>
.container{
background: #fff;
}
.select{
margin-top: 20px;
color: #000;
font-weight: 600;
}
</style>
子组件1:
<template>
<div>
<p class="txt" v-for="(item, index) in list" :key="index" @click="txtClick(item)">{{item}}</p>
</div>
</template>
<script>
export default {
props: ['list'],
data() {
return {
}
},
methods:{
txtClick(item) {
this.$bus.$emit('nameUpdate', item);
}
},
}
</script>
<style scoped>
.txt{
font-size: 16px;
margin-bottom: 10px;
cursor: pointer;
}
</style>
子组件2:
<template>
<div>
<p class="txt">兄弟组件传来的游戏名称:{{gameTitle}}</p>
</div>
</template>
<script>
export default {
data() {
return {
gameTitle: ''
}
},
mounted() {
this.$bus.$on('nameUpdate', (value)=>{
this.gameTitle = value;
})
}
}
</script>
<style scoped>
.txt{
font-size: 16px;
margin-bottom: 10px;
cursor: pointer;
}
</style>
eventBus事件总线($emit / $on)
兄弟组件已经展示$emit / $on的使用。在此就不在赘言。
通过 ref ,$refs实现通信(父、子组件)
父组件:
<template>
<div class="container">
<Child1 :list="txtArr" ref="child"/>
<el-button type="primary" @click="getGameName">获取子组件选中的游戏名称</el-button>
<p class="select">{{gameTitle}}</p>
</div>
</template>
<script>
import Child1 from './child1.vue';
export default {
components: {
Child1,
},
data() {
return {
txtArr: ['王者荣耀', '英雄联盟', '真三无双'],
gameTitle: ''
}
},
methods:{
getGameName() {
this.gameTitle = this.$refs.child.gameTitle;
}
},
}
</script>
<style scoped>
.container{
background: #fff;
}
.select{
margin-top: 20px;
color: #000;
font-weight: 600;
}
</style>
子组件:
<template>
<div>
<p class="txt" v-for="(item, index) in list" :key="index" @click="txtClick(item)">{{item}}</p>
</div>
</template>
<script>
export default {
props: ['list'],
data() {
return {
gameTitle: ''
}
},
created(){
},
computed:{
},
methods:{
txtClick(item) {
this.gameTitle = item;
},
},
}
</script>
<style scoped>
.txt{
font-size: 16px;
margin-bottom: 10px;
cursor: pointer;
}
</style>
通过 this.$parent 调用 父组件方法/参数
父组件:
<template>
<div class="container">
<div>我是父组件</div>
<p class="select">{{ name }}</p>
<Child1/>
</div>
</template>
<script>
import Child1 from './child1.vue';
export default {
components: {
Child1,
},
data() {
return {
name: ''
}
},
created(){
},
computed:{
},
methods:{
getParentName(name) {
this.name = name;
console.log("父组件方法getParentName被调用:",name);
}
},
}
</script>
<style scoped>
.container{
background: #fff;
}
.select{
margin-top: 20px;
color: #000;
font-weight: 600;
}
</style>
子组件:
<template>
<div>
<p class="txt">我是子组件</p>
<el-input v-model="value" placeholder="请输入内容" @change="nameChange"></el-input>
<el-button type="primary" @click="txtClick">调用父组件事件</el-button>
</div>
</template>
<script>
export default {
props: ['list'],
data() {
return {
value: ''
}
},
created(){
},
computed:{
},
methods:{
txtClick() {
this.$parent.getParentName(this.value);
},
nameChange(value) {
this.value = value;
}
},
}
</script>
<style scoped>
.txt{
font-size: 16px;
margin-bottom: 10px;
cursor: pointer;
}
</style>
provide和inject 实现通信
成对出现:provide和inject是成对出现的
作用:用于父组件向子孙组件传递数据
使用场景:由于vue有$parent属性可以让子组件访问父组件。但孙组件想要访问祖先组件就比较困难。通过provide/inject可以轻松实现跨级访问父组件的数据
provider/inject:简单的来说就是在父组件中通过provider来提供变量,然后在子组件中通过inject来注入变量,需要注意的是这里不论子组件有多深,只要调用了inject那么就可以注入provider中的数据。而不是局限于只能从当前父组件的prop属性来获取数据。
父组件:
<template>
<div class="container">
<div>我是父组件</div>
<Child1/>
<el-button type="primary" @click="changeValue">主要按钮</el-button>
</div>
</template>
<script>
import Child1 from './child1.vue';
export default {
components: {
Child1,
},
data() {
return {
parentValue: '我是父组件的值啊'
}
},
provide() {
return {
parentValue: this.parentValue
}
},
methods: {
changeValue() {
this.parentValue = '修改父组件值';
this.$nextTick(()=>{
console.log("修改的值:",this.parentValue);
});
}
}
}
</script>
<style scoped>
.container{
background: #fff;
}
.select{
margin-top: 20px;
color: #000;
font-weight: 600;
}
</style>
子组件:
<template>
<div>
<p class="txt">我是子组件</p>
<p class="txt">{{parentValue}}</p>
<Grandson />
</div>
</template>
<script>
import Grandson from './grandson.vue';
export default {
components: {
Grandson,
},
// inject:["parentValue"], // 使用一个注入的值作为数据入口:
inject: {
// 使用一个默认值使其变成可选项
parentValue: { // 健名
from: 'parentValue', // 来源
default: 'parentValue' // 默认值
}
}
}
</script>
<style scoped>
.txt{
font-size: 16px;
margin-bottom: 10px;
cursor: pointer;
}
</style>
更深层的组件:
<template>
<div>
<p class="txt">我是孙子组件</p>
<p class="txt">{{parentValue}}</p>
</div>
</template>
<script>
export default {
// inject:["parentValue"], // 使用一个注入的值作为数据入口:
inject: {
// 使用一个默认值使其变成可选项
parentValue: { // 健名
from: 'parentValue', // 来源
default: 'parentValue' // 默认值
}
}
}
</script>
<style scoped>
.txt{
font-size: 16px;
margin-bottom: 10px;
cursor: pointer;
}
</style>
从父组件日志可以看到,此时的parentValue不是响应式的值。
修改为响应式provide提供一个函数:
父组件修改为:
<template>
<div class="container">
<div>我是父组件</div>
<Child1/>
<el-button type="primary" @click="changeValue">主要按钮</el-button>
</div>
</template>
<script>
import Child1 from './child1.vue';
export default {
components: {
Child1,
},
data() {
return {
parentValue: 1
}
},
provide() {
return {
getParentValue: () => ({
value: this.parentValue
}),
};
},
methods: {
changeValue() {
this.parentValue = this.parentValue + 1;
}
}
}
</script>
<style scoped>
.container{
background: #fff;
}
.select{
margin-top: 20px;
color: #000;
font-weight: 600;
}
</style>
子组件修改为:
<template>
<div>
<p class="txt">我是子组件</p>
<p class="txt">{{parentValue}}</p>
</div>
</template>
<script>
export default {
inject:["getParentValue"],
data() {
return{
parentValue: ''
}
},
computed: {
actParantValue() {
return this.getParentValue()
}
},
watch: {
actParantValue(val) {
this.parentValue = val.value
}
}
}
</script>
<style scoped>
.txt{
font-size: 16px;
margin-bottom: 10px;
cursor: pointer;
}
</style>
如果有助你们,麻烦点赞,转发,收藏
谢谢