Vue.js,computed,组件前言 本文非vue教程,仅为学习vue过程中的个人理解与笔记,有说的不正确的地方欢迎指正讨论 1、computed计算属性函数中不能使用vm变量 在计算属性的函数中,不能使用Vue构造函数返回的vm变量,因为此时vm还未返回,依然处于Vue内部构造函数过程中,遂只能使用this来代替vm。 若要使用typescript,可使用以下方法来实现代码智能感知 vm = vm || this;
另:其他不能用vm变量,只能使用this变量的地方,都可以通过此方法来获得Typescript的智能感知和代码语法检查,比如mounted生命周期系列函数等。 不过模板里的vm引用Typescript无能为力,只能等待ts支持vue的jsx语法了╮(╯_╰)╭ 2、计算属性中不能引用其他计算属性? 官方教程中没有找到相关说明(应该是我没找到),从使用角度而言大致可以总结出以下结论: - 计算属性必须引用(依赖)非计算属性或固定值。(见demo1)
- 计算属性若引用(依赖)其他计算属性,则被引用的计算属性必须引用非计算属性或固定值(见demo2)
- 计算属性可循环依赖,但最终依赖链上的最上游的计算属性,必须引用非计算属性或固定值。
DEMO1:官方标准用法,计算属性引用非计算属性: var vm = new Vue({ el: "#app", data: { dataVal: "xxcanghai" }, computed: { computedVal1: function () { //标准用法,计算属性引用非计算属性 return this.dataVal + "_1";//输出 xxcanghai_1 } }}); DEMO2:计算属性链式依赖其他计算属性,则依赖链头必须引用非计算属性或固定值 var vm = new Vue({ el: "#app", data: { dataVal: "xxcanghai" }, computed: { computedVal1: function () { return this.dataVal + "_1"; }, computedVal2: function () { //合法,计算属性computedVal2引用computedVal1,computedVal1再引用dataVal return this.computedVal1 + "_2";//输出 xxcanghai_1_2 } }}); 原因很容易理解,如果最终没有引用或依赖任何非计算属性,那么计算属性在计算时会陷入死循环。 3、vue2.0中若使用组件嵌套,则在父组件执行/$forceUpdate()之前模板中/$children为空数组 触发这个问题有以下几个前提: - vue版本为2.0版本,1.0无此问题。
- 使用组件嵌套,在父组件的模板中访问$children变量
- 在渲染完成后没有再将$children变量写入过父组件的data变量(或其他vm数据)就会触发此问题。
<!--父组件HTML模板--><div id="app"> <div>{{$children.length}}</div> <!--此处显示0,应该为3--> <child></child> <child></child> <child></child></div>//子组件代码Vue.component("child", { template: "<div>child</div>",});//父组件声明new Vue({ el: "#app",}); 如下图:

解决方案1:使用/$forceUpdate() 注册父组件的mounted方法,执行$forceUpdate() <div id="app"> <div>{{$children.length}}</div> <child></child> <child></child> <child></child></div>Vue.component("child", { template: "<div>child</div>",});new Vue({ el: "#app", mounted: function () { this.$forceUpdate();//强制重新绘制 }}); $children正确了:

解决方案2:使用vm的变量代替/$children 注册父组件的mounted方法,将$children赋值给自定义的vm的变量。 同时模板中使用自定义的变量来代替默认的$children <div id="app"> <div>{{child.length}}</div> <!--使用自定义的child对象--> <child></child> <child></child> <child></child></div>Vue.component("child", { template: "<div>child</div>",});var vm = new Vue({ el: "#app", data: { child: [] }, mounted: function () { this.child = this.$children;//手动将$children对象赋值给自定义child变量 }}); 
至于导致此问题的原因只能通过阅读vue2.0版本的源码才能了解了。 4、若父组件的template或render函数中无引用slot元素,则/$children恒等于空数组 此问题关联上面第3个问题。 触发此问题的前提: - vue2.0版本
- 父组件和子组件都直接写在调用方模板中
- 在模板中访问$children变量
- 已经解决在上述问题3中强制刷新的问题
<div id="app"> <!--子组件直接写在调用方的模板中--> <parent> <child></child> <child></child> <child></child> </parent></div>//父组件Vue.component("parent", { template: "<p>parent child:{{$children.length}} </p>",//模板中无slot元素 mounted(){ this.$forceUpdate(); }});Vue.component("child", { template: "<div>child</div>"});var vm = new Vue({ el: "#app"}); 
解决方案1:父组件模板包含slot元素 在父组件的模板中加入slot元素。或在render函数中引用了this.$slots.default变量 Vue.component("parent", { template: "<p>parent child:{{$children.length}} <slot></slot></p>", mounted(){ this.$forceUpdate(); }}); 
解决方案2:在父组件模板中编写子组件定义 此解决方案要修改此问题的复现第2要素,即子组件定义从调用方改为写到父组件的模板中也可解决此问题。 <div id="app"> <parent> </parent></div>Vue.component("parent", { //直接在父组件中写明调用子组件标签 template: "<p>parent child:{{$children.length}}/ <child></child>/ <child></child>/ </p>", mounted(){ this.$forceUpdate(); }});Vue.component("child", { template: "<div>child</div>",});var vm = new Vue({ el: "#app", data: { child: [] }}); 
此方法虽然可以解决问题,但是有时我们直接把子组件写在调用方会更方便更利于理解,比如Tab与TabPage组件。 如下Tab组件代码,可能更符合一般人的使用思维: <div id="app"> <tab> <tab-page>Page1</tab-page> <tab-page>Page2</tab-page> <tab-page>Page3</tab-page> </tab></div> 相关笔记 Vue学习笔记-1(/article/98869.htm) Vue学习笔记-2(/article/98878.htm) 本文已被整理到了《Vue.js前端组件学习教程》,欢迎大家学习阅读。 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持wanshiok.com。 Vue.js,computed,组件
|