父子组件间的数据传递及方法调用
- 父组件通过ref使用子组件的方法并修改子组件数据
- 子组件通过.$parent使用父组件的方法动态修改父组件信息
- 子组件通过watch监听父组件数据变化
parent.vue
<template>
<div class="container">
<input
v-model="childrenValue"
placeholder="parent"
@change="changeChildData"
>
<hr />
<input
v-model="obj.name"
placeholder="parent"
>
<hr />
<children
ref="children"
:parentData="childrenValue"
:ObjData="obj"
/>
我是祖先的值: {{grandsonValue}}
<hr />
<brother :ObjData="obj" />
</div>
</template>
<script>
import children from "./children";
import brother from "./brother";
export default {
data() {
return {
grandsonValue: {
grandsonValueName: "",
grandsonValueValue: ""
},
childrenValue: "",
obj: {
name: "name",
age: 18
}
};
},
watch: {
childrenValue: function(newValue) {
console.log("后代值发生了改变");
}
},
provide() {
// 祖先注册
return {
appmy: this
};
},
components: { children, brother },
mounted() {
this.getChildMethod();
},
methods: {
changeChildData() {
this.$refs.children.childrenData.name = this.childrenValue;
},
getChildMethod() {
this.$refs.children.childrenMethod("我在父组件使用"); // 在父组件中调用
console.log(this);
console.log(
"我在父组件拿到了子组件的数据:" + this.$refs.children.childrenData.name
);
},
ancestorMethod(info) {
console.log("我是祖先组件方法," + info);
},
parentMethod(info) {
console.log("我是父组件方法," + info);
}
}
};
</script>
children.vue
<template>
<div class="container">
我是子组件的数据(被父组件使用):{{childrenData}}
<hr />
我是子组件的数据(对象):{{ObjData}}
<hr />
我在子组件,下面是孙子组件:
<grandson ref="grandson" />
</div>
</template>
<script>
import grandson from "./grandson";
export default {
props: ["parentData", "ObjData"],
data() {
return {
childrenData: {
name: "children"
}
};
},
watch: {
parentData: function(newValue) {
console.log(
"父组件传给子组件的值发生了改变,如果传入值为对象,改变对象的属性值并不会触发watch"
);
},
ObjData: function(newValue) {
console.log("改变对象的属性值并不会触发watch");
}
},
components: { grandson },
mounted() {
this.getParentMethod();
},
methods: {
getParentMethod() {
this.$parent.parentMethod("我在子组件中使用");
console.log("我在子组件拿到了父组件的数据:" + this.$parent.obj.name);
},
childrenMethod(info) {
console.log("我是子组件方法," + info);
}
}
};
</script>
<style scoped lang="scss">
</style>
- 兄弟组件获取数据和方法
brother.vue
<template>
<div class="container">
我是children 的 brother , 我通过修改parant 传入childen的对象,改变childen的值
<input
v-model="ObjData.name"
placeholder="brother"
>
</div>
</template>
<script>
export default {
props: ["ObjData"],
data() {
return {};
},
components: {},
mounted() {
this.getBrotherMethod();
},
methods: {
getBrotherMethod() {
this.$parent.$refs.children.childrenMethod("我在兄弟组件使用");
}
}
};
</script>
<style scoped lang="less">
</style>
-
provide/inject实现后代组件获取祖先组件的数据和使用祖先组件的方法
grandson.vue
<template> <div> 我拿到了祖先的值: {{appmy.obj}} <hr /> 我使用了祖先的方法:{{appmy.ancestorMethod("我在后代组件使用")}} 我是后代组件的输入框, 我改变祖先组件的数据: <input v-model="appmy.grandsonValue.grandsonValueValue" placeholder="grandson" > </div> </template> <script> export default { // 后代使用 inject: ["appmy"], data() { return {}; }, components: {} }; </script> <style scoped lang="less"> </style>
-
通过$refs 层层获取
-
使用eventBus 共用方法
对象的深度克隆
JSON.parse(JSON.stringify(obj)) //得到存储地址改变的对象
ref获取不到指定的DOM节点问题
this.$nextTick(function() {
console.log(this.$refs.mysql);
}); // 等dom组件加载完毕再调用
eg:
async conn(data) {
let preData = JSON.parse(JSON.stringify(data));
await this.$nextTick(function() {
preData.password = this.$refs.mysql.checkPwd(preData.password);
});
console.log(preData.password);
const url = "/v1/api/data/connect";
axios.request(url, "get", preData, true).then(res => {
this.tableSource = res;
this.$emit("connResp", res);
});
}