为vue中的data赋值computed计算属性后,出现undefined原因及解决
作者:啊啊怪
这篇文章主要介绍了为vue中的data赋值computed计算属性后,出现undefined原因及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
为vue中的data赋值computed计算属性后,出现undefined原因
今天遇到一个问题,当我给data数据初始化一个computed计算属性时,在页面上竟然没有显示,放代码
<template>
<div class="container">
<div>num1:{{num1}}</div>
<div>num2:{{num2}}</div>
<div>data中的数据{{sum}}</div>
</div>
</template>
<script>
export default {
data() {
return {
num1:2,
num2:10,
sum:this.result
};
},
computed:{
result(){
return this.num1+this.num2
}
}
};
</script>
console.log(this.data)一下,结果是undefined

查了一下资料,原来是跟Vue组件数据初始化顺序有关,我们可以看一下源码new Vue的执行顺序

往下找,可以找到在这个initMixin函数里,定义了_init的方法
function initMixin (Vue) {
Vue.prototype._init = function (options) { //在这里定义了_init方法
var vm = this;
// a uid
vm._uid = uid$3++;
var startTag, endTag;
/* istanbul ignore if */
if (config.performance && mark) {
startTag = "vue-perf-start:" + (vm._uid);
endTag = "vue-perf-end:" + (vm._uid);
mark(startTag);
}
// a flag to avoid this being observed
vm._isVue = true;
// merge options
if (options && options._isComponent) {
// optimize internal component instantiation
// since dynamic options merging is pretty slow, and none of the
// internal component options needs special treatment.
initInternalComponent(vm, options);
} else {
vm.$options = mergeOptions(
resolveConstructorOptions(vm.constructor),
options || {},
vm
);
}
/* istanbul ignore else */
{
initProxy(vm);
}
// expose real self
vm._self = vm;
initLifecycle(vm);
initEvents(vm);
initRender(vm);
callHook(vm, 'beforeCreate');
initInjections(vm); // resolve injections before data/props
initState(vm);
initProvide(vm); // resolve provide after data/props
callHook(vm, 'created');
/* istanbul ignore if */
if (config.performance && mark) {
vm._name = formatComponentName(vm, false);
mark(endTag);
measure(("vue " + (vm._name) + " init"), startTag, endTag);
}
if (vm.$options.el) {
vm.$mount(vm.$options.el);
}
};
}其中,聚焦在这里

看来initState(vm)是关键的部分了,在initState函数里
function initState (vm) {
vm._watchers = [];
var opts = vm.$options;
if (opts.props) { initProps(vm, opts.props); }//初始化props
if (opts.methods) { initMethods(vm, opts.methods); }//初始化methods
if (opts.data) {
initData(vm);
} else {
observe(vm._data = {}, true /* asRootData */);
} //初始化data
if (opts.computed) { initComputed(vm, opts.computed); }//初始化computed
if (opts.watch && opts.watch !== nativeWatch) {
initWatch(vm, opts.watch);//初始化watch
}
}从initState(vm)函数可以看出
初始化数据的顺序如下
propsmethodsdatacomputedwatch
computed的初始化在data的后边!
这也就证实了为什么为data赋值计算属性computed时,data打印出来是undefined
回到上边的例子
<template>
<div class="container">
<div>num1:{{num1}}</div>
<div>num2:{{num2}}</div>
<div>data中的数据{{sum}}</div>
</div>
</template>
<script>
export default {
data() {
return {
num1:2,
num2:10,
sum:this.result
};
},
computed:{
result(){
return this.num1+this.num2
}
}
};
</script>因为computed初始化顺序是在data后边。
当sum初始化的时候,result还没有初始化,所以也就输出undefined的结果
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
