vue2在子组件的data中获取不到props中的值,或者一直是默认值(父组件的值来自异步)
文章结构复现问题分析原因解决方案使用watch使用v-if复现问题为了方便我直接在main.js中使用mockjs模拟一个接口请求并为其设置了2秒的响应时间mian.jsimport Vue from "vue";import App from "./App.vue";const Mock = require("mockjs");// 请求的响应时间2秒Mock.setup({timeout: "
·
复现问题
为了方便我直接在main.js中使用mockjs模拟一个接口请求并为其设置了2秒的响应时间
mian.js
import Vue from "vue";
import App from "./App.vue";
const Mock = require("mockjs");
// 请求的响应时间2秒
Mock.setup({
timeout: "2000",
});
// 请求方式要使用小写
Mock.mock("/test", "get", {
"msg|1-10": "★",
});
Vue.config.productionTip = false;
new Vue({
render: (h) => h(App),
}).$mount("#app");
父组件中将自己的msg传递给子组件,父组件中的msg来自于接口异步任务。
父组件
<template>
<div>
<HelloWorld :msg="msg" />
</div>
</template>
<script>
import HelloWorld from "./components/HelloWorld.vue";
import axios from "axios";
export default {
name: "App",
data() {
return {
msg: "默认值",
};
},
components: {
HelloWorld,
},
created() {
axios({
method: "get",
url: "/test",
}).then(response => {
console.log(response, "response");
this.msg = response.data.msg;
});
},
};
</script>
<style></style>
子组件接收msg并展示
子组件
<template>
<div>{{ msg }}</div>
</template>
<script>
export default {
name: "HelloWorld",
props: {
msg: String,
},
data() {
return {
msgSon: this.msg,
};
},
mounted(){
setInterval(() =>{
console.log(this.msgSon)
},1000)
}
};
</script>
<style scoped></style>
运行效果
一开始输出“默认值”没错,但是我们发现接口返回之后,父组件的msg已经修改了,但是
子组件还是一直输出“默认值”。
分析原因
因为把props的值赋值给data不是响应式的,props中的值改变了,data中的值不会
响应式更改。回到我们的文章标题:data中获取不到props中的值,可能大家在父组件
中设置的值为undefined,但是大家又觉得我明明在接口响应中给它赋值了,所以大家
觉得是子组件props没有获取到值什么的,其实只是因为在子组件渲染的时候,props
会去父组件中获取值,但是父组件此时的值在接口中还没有返回,所以只是默认值。
解决方案
使用watch
站在子组件的角度思考:不就是父组件值改了,但是我子组件不知道嘛,没关系,vue为
我们提供了watch,可以监听一个值是否变化,我用watch监听你父组件传给我的值,你一
旦改了值,我就把我的data中复制出来的值也改了不就行了。
<template>
<div>{{ msg }}</div>
</template>
<script>
export default {
name: "HelloWorld",
props: {
msg: String,
},
data() {
return {
msgSon: this.msg,
};
},
mounted() {
setInterval(() => {
console.log(this.msgSon);
}, 1000);
},
watch: {
msg: function (newVal) {
this.msgSon = newVal;
},
},
};
</script>
<style scoped></style>
运行效果
使用v-if
站在子组件的角度思考:我渲染的时候需要拿值,但是你父组件还没有拿到真正的值,那
我就先不渲染呗,等你拿到真正的值了,再让我渲染,此时我拿到的值不就是真正的值了。
<template>
<div>
<HelloWorld :msg="msg" v-if="lock"/>
</div>
</template>
<script>
import HelloWorld from "./components/HelloWorld.vue";
import axios from "axios";
export default {
name: "App",
data() {
return {
msg: "默认值",
lock: false,
};
},
components: {
HelloWorld,
},
created() {
axios({
method: "get",
url: "/test",
}).then(response => {
console.log(response, "response");
this.msg = response.data.msg;
this.lock = true;
});
},
};
</script>
<style></style>
运行效果
更多推荐
已为社区贡献2条内容
所有评论(0)