vue 组件相互传值
Part.1 传值几种方式
在写项目时,遇到组件传值问题,特此记录一波~~~
(1) 父传子
(2) 子传父
(2) 兄弟组件传值
Part.2 父传子
顾名思义,就是父组件传值给子组件
子组件:
<template>
<div class="hello">
<h1>{{ msg }}</h1>
</div>
</template>
<script>
export default {
name: "HelloWorld",
props: {
msg: String
}
};
</script>
父组件:
<template>
<div class="home">
<img alt="Vue logo" src="../assets/logo.png" />
<HelloWorld msg="Welcome to Your Vue.js App" />
</div>
</template>
<script>
import HelloWorld from "@/components/HelloWorld.vue";
export default {
name: "home",
components: {
HelloWorld
}
};
</script>
效果:

Part.3 子传父
子组件传值给父组件
子组件:
<template>
<div class="hello">
<h1 @click="goFather">{{ msg }}</h1>
</div>
</template>
<script>
export default {
name: "HelloWorld",
data() {
return{
msg: '我是子组件的值'
}
},
methods: {
goFather() {
this.$emit('goFather', this.msg)
}
}
};
</script>
父组件:
<template>
<div class="home">
<img alt="Vue logo" src="../assets/logo.png" />
<HelloWorld @goFather="getValue"/>
<h1>{{msg}}</h1>
</div>
</template>
<script>
import HelloWorld from "@/components/HelloWorld.vue";
export default {
name: "home",
data() {
return {
msg: '我现在没值'
}
},
methods: {
getValue(data) {
this.msg = data
}
},
components: {
HelloWorld
}
};
</script>
效果:
点击之前

点击之后

Part.3 兄弟组件传值
我把兄弟组件传值分为两种情况:
1. 通过点击事件触发
2. 窗体加载时就触发
首先创建一个供传值使用的媒介 JS 文件, 例如 a.js

内容如下:
import Vue from 'vue' export default new Vue
其次,父组件如下
<template>
<div id="app">
<div id="nav">
<!-- 兄弟组件 Home & About -->
<Home></Home>
<About></About>
</div>
</div>
</template>
<script>
import Home from './views/Home'
import About from './views/About'
export default {
name: "home",
components: {
Home,
About
}
};
</script>
我们开始第一种情况:点击触发
Home 子组件:
<template>
<div class="home">
<h1 @click="goAbout">{{msg}}</h1>
</div>
</template>
<script>
import a from '../assets/a'
export default {
name: "home",
data() {
return {
msg: '我是兄弟组件一'
}
},
methods: {
goAbout: function() {
a.$emit('userDefinedEvent',this.msg)
}
}
};
</script>
About 子组件:
<template>
<div class="about">
<h1>{{msg}}</h1>
<h2>{{msg2}}</h2>
</div>
</template>
<script>
import a from '../assets/a'
export default {
name: "About",
data() {
return {
msg: '我是兄弟组件二',
msg2: '默认值'
}
},
created() {
a.$on('userDefinedEvent',(e)=>{
this.msg2 = e
})
}
};
</script>
效果:
点击之前:

点击之后

OK!再看第二种情况
Home 组件:
<template>
<div class="home">
<h1>{{msg}}</h1>
</div>
</template>
<script>
import a from '../assets/a'
export default {
name: "home",
data() {
return {
msg: '我是兄弟组件一'
}
},
created() {
a.$emit('userDefinedEvent',this.msg)
}
};
</script>
About 组件:
<template>
<div class="about">
<h1>{{msg}}</h1>
<h2>{{msg2}}</h2>
</div>
</template>
<script>
import a from '../assets/a'
export default {
name: "About",
data() {
return {
msg: '我是兄弟组件二',
msg2: '默认值'
}
},
created() {
a.$on('userDefinedEvent',(e)=>{
this.msg2 = e
})
}
};
</script>
搞定,运行!
效果:

蛋疼的结果出现了,一直没值,根本没监听到!😭
冷静,认真分析
$emit 可以理解为抛出
$on 可以理解为监听
如果我先抛出,再去执行监听!肯定监听不到阿,哇!找到问题所在:我们需要 监听 在 抛出 之前
这里就涉及到 vue 的生命周期和钩子函数,感兴趣的小伙伴可以瞅瞅:https://cn.vuejs.org/v2/guide/instance.html#%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E5%9B%BE%E7%A4%BA
我们看到
About 子组件中:
created() { a.$on('userDefinedEvent',(e)=>{ this.msg2 = e }) }
Home 子组件中:
created() { a.$emit('userDefinedEvent',this.msg) }
我们发现他们的生命周期相同,但是我们需要让 Home 子组件滞后执行
将 Home 子组件 created() 钩子函数修改为 mounted() , 因为 mounted 会在 created 之后执行
mounted() { a.$emit('userDefinedEvent',this.msg) }
效果如下:

搞定!!!~

浙公网安备 33010602011771号