一、Vue组件:父传子
1.子组件获取父组件的数据
子组件通过prop获取父组件的数据。注:input 中的v-model自动监听数据的变化
<body>
<div id="app">
<father></father>
</div>
</body>
<!-- 父组件 -->
<template id="father">
<div>
<h1>父组件</h1>
<input type="text" v-model="message" />
<hr />
<son :getmoney="money" :flow="num" :msg="message"></son>
</div>
</template>
<!-- 子组件 -->
<template id="son">
<div>
<h1>子组件</h1>
<h3>{{getmoney}}</h3>
<h3>{{msg}}</h3>
<button @click="func(msg)">点击</button>
</div>
</template>
<script>
// 父组件用prop传值
var son = {
template: "#son",
props: ["getmoney", "flow", "msg"],
methods: {
func(val) {
console.log(val);
},
},
};
Vue.component("father", {
template: "#father",
data() {
return {
money: "爸爸给你10万块",
num: 10,
message: "",
};
},
components: {
son,
},
});
var vue = new Vue({
el: "#app",
data: {},
methods: {},
});
</script>

分页面展示
<template>
<div id="app">
<h1>父组件</h1>
<input type="text" v-model="message" />
<hr />
<child :getmoney="money" :flow="num" :msg="message" />
</div>
</template>
<script>
import child from "./components/child.vue";
export default {
name: "App",
components: {
child,
},
data() {
return {
money: "爸爸给你10万块",
num: 10,
message: "",
};
},
};
</script>
<template>
<div class="child">
<h1>子组件</h1>
<h3>{{getmoney}}</h3>
<h3>{{msg}}</h3>
<button @click="func(msg)">点击</button>
</div>
</template>
<script>
export default {
name: "child",
props: ["getmoney", "flow", "msg"],
methods: {
func(val) {
console.log(val);
},
},
};
</script>
2.子组件调用父组件的方法
Vue中子组件调用父组件的方法,这里有三种方法提供参考
第一种方法是直接在子组件中通过this.$parent.event来调用父组件的方法
父组件
<template>
<div>
<child></child>
</div>
</template>
<script>
import child from "~/components/child";
export default {
components: {
child,
},
methods: {
fatherMethod() {
console.log("测试");
},
},
};
</script>
子组件
<template>
<div>
<button @click="childMethod()">点击</button>
</div>
</template>
<script>
export default {
methods: {
childMethod() {
this.$parent.fatherMethod();
},
},
};
</script>
第二种方法是在子组件里用$emit向父组件触发一个事件
父组件监听这个事件就行了,相当于子组件给父组件传值。如tree中暴露出接口,父组件直接使用。
父组件
<template>
<div>
<child @fatherMethod="fatherMethod"></child>
</div>
</template>
<script>
import child from "~/components/dam/child";
export default {
components: {
child,
},
methods: {
fatherMethod() {
console.log("测试");
},
},
};
</script>
子组件
<template>
<div>
<button @click="childMethod()">点击</button>
</div>
</template>
<script>
export default {
methods: {
childMethod() {
this.$emit("fatherMethod");
},
},
};
</script>
第三种是父组件把方法传入子组件中,在子组件里直接调用这个方法
父组件
<template>
<div>
<child :fatherMethod="fatherMethod"></child>
</div>
</template>
<script>
import child from "~/components/dam/child";
export default {
components: {
child,
},
methods: {
fatherMethod() {
console.log("测试");
},
},
};
</script>
子组件
<template>
<div>
<button @click="childMethod()">点击</button>
</div>
</template>
<script>
export default {
props: {
fatherMethod: {
type: Function,
default: null,
},
},
methods: {
childMethod() {
if (this.fatherMethod) {
this.fatherMethod();
}
},
},
};
</script>
三种都可以实现子组件调用父组件的方法,但是效率有所不同,根据实际需求选择合适的方法。
二、Vue组件:子传父
1.父组件获取子组件的数据
方法1:给相应的子组件标签上加 ref ="child",使用this.$refs.child.msg获取msg的内容
<template>
<div id="app">
<h1>父组件</h1>
<button @click="getmsg">点击</button>
<div>{{msg}}</div>
<hr />
<child ref="child" />
</div>
</template>
<script>
import child from "./components/child.vue";
export default {
name: "App",
components: {
child,
},
data() {
return {
msg: "",
};
},
methods: {
getmsg() {
this.msg = this.$refs.child.msg;
},
},
};
</script>
<template>
<div class="child">
<h1>子组件</h1>
</div>
</template>
<script>
export default {
name: "child",
data() {
return {
msg: "这是子组件传给父组件的数据",
};
},
};
</script>
通过ref绑定,使用
this.$refs.child.msg获取msg的内容。该方法父组件可以获取到子组件的方法,并调用。
方法2:通过$emit()
<body>
<div id="app">
<father></father>
</div>
</body>
<!-- 父组件 -->
<template id="father">
<div>
<h1>父组件</h1>
{{message}}
<hr />
<son @sendmsg="getmsg"></son>
</div>
</template>
<!-- 子组件 -->
<template id="son">
<div>
<h2>子组件</h2>
<button @click="click">点击</button>
</div>
</template>
<script>
// 子组件
var son = {
template: "#son",
data() {
return {
msg: "这是子组件传给父组件的数据",
};
},
methods: {
click() {
this.$emit("sendmsg", this.msg); //触发事件,用方法接收
},
},
};
// 父组件
Vue.component("father", {
template: "#father",
components: {
son,
},
data() {
return {
message: "",
};
},
methods: {
getmsg(val) {
console.log(val);
this.message = val;
},
},
});
var vue = new Vue({
el: "#app",
data: {},
methods: {},
});
</script>
分页面展示
<!-- 父组件 -->
<template>
<div id="app">
<h1>父组件</h1>
{{msg}}
<hr />
<child @sendmsg="getmsg" />
</div>
</template>
<script>
import child from "./components/child.vue";
export default {
name: "App",
components: {
child,
},
data() {
return {
msg: "",
};
},
methods: {
getmsg(val) {
console.log(val);
this.msg = val;
},
},
};
</script>
<!-- 子组件 -->
<template>
<div class="child">
<h1>子组件</h1>
<button @click="func">点击</button>
</div>
</template>
<script>
export default {
name: "child",
data() {
return {
msg: "这是子组件传给父组件的数据",
};
},
methods: {
func() {
this.$emit("sendmsg", this.msg); //触发事件,用方法接收
},
},
};
</script>
从上面可以看出,当
this.$emit()携带参数时,可以传参到父组件,同时可以调用父组件的方法;
2.父组件调用子组件的方法
给相应的子组件标签上加 ref ="child",然后通过this.$refs.child.func()获取func()的方法。
三、Vue的$on,$emit的使用
vue中使用 $emit(eventName) 触发事件,使用 $on(eventName) 监听事件,为同级事件。
$emit(eventName)触发当前实例上的事件,附加参数都会传给监听器回调。
$on(eventName)监听当前实例上的自定义事件。事件可以由 vm.$emit 触发。回调函数会接收所有传入事件触发函数的额外参数。
下面通过几个实例来演示一下怎么使用
实例1 本页面单个事件
<template>
<div>
<el-button type="primary" @click="isClick">点击</el-button>
</div>
</template>
<script>
export default {
methods: {
isClick() {
this.$emit("isLeft", "点击事件!"); //与this.$on 同级使用
},
},
mounted() {
this.$on("isLeft", val => {
console.log(val);
});
},
};
</script>
以上代码,是通过按钮的点击事件,然后this.$emit传递事件,然后this.$on捕获本页面的事件
实例2 本页面多个事件
<template>
<div>
<el-button type="primary" @click="isClick">点击</el-button>
<el-button type="primary" @click="isClickOther">点击</el-button>
</div>
</template>
<script>
export default {
methods: {
isClick() {
this.$emit("isLeft", "点击事件!");
},
isClickOther() {
this.$emit("isRight", ["点击1", "点击2"]);
},
},
mounted() {
this.$on("isLeft", val => {
console.log(val);
});
this.$on("isRight", (...val) => {
console.log(val);
});
this.$on(["isLeft", "isRight"], () => {
console.log(666);
});
},
};
</script>
以上例子,是本页面的两个点击事件,可以同时监听两个事件,也可以同时传多个参数
实例3 非父子组件传值(通过bus传值)
子组件1
<template>
<div>
<div>left</div>
<el-button type="primary" @click="isClick">点击</el-button>
</div>
</template>
<script>
import eventBus from "./js/eventBus";
export default {
methods: {
isClick() {
eventBus.$emit("isLeft", "点击事件!");
},
},
};
</script>
子组件2
<template>
<div>
<div>right</div>
{{ name }}
</div>
</template>
<script>
import eventBus from "./js/eventBus";
export default {
data() {
return {
name: "right默认值",
};
},
mounted() {
eventBus.$on("isLeft", info => {
this.name = info;
});
},
};
</script>
父组件
<template>
<div>
<el-row>
<el-col :span="12">
<leftChlid></leftChlid>
</el-col>
<el-col :span="12">
<rightChild></rightChild>
</el-col>
</el-row>
</div>
</template>
<script>
import leftChlid from "./components/leftChlid";
import rightChild from "./components/rightChild";
export default {
components: {
leftChlid,
rightChild,
},
};
</script>
以上例子就是 left组件传值给bus,然后right组件监听 bus的isLest事件,当left组件触发事件的时候,right组件就会触发方法,替换页面的值
小结
1.使用 $emit 传递事件
2.使用 $on 监听事件
3.可以本页面使用,也可以父子组件使用,也可以非关联组件使用
四、总结
1:父组件向子组件传值:使用 prop 向子组件传值;
2:子组件实时监听父组件传来的值的变化:使用 watch 去监听父组件传来的值;
3:父组件可以通过 this.$refs.name. 去访问子组件的值或方法;
4:子组件可以通过 this.$parent. 去访问父组件的值或方法;
5:父组件可以通过 this.$store.dispatch 去监听子组件的值;
下次我们说说$attrs和$listeners。