为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)
函数可以看出
初始化数据的顺序如下
props
methods
data
computed
watch
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
的结果
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。