源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

关于Vue.js一些问题和思考学习笔记(2)

  • 时间:2021-11-02 05:24 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:关于Vue.js一些问题和思考学习笔记(2)
[b]前言[/b] 本文非vue教程,仅为学习vue过程中的个人理解与笔记,有说的不正确的地方欢迎指正讨论 [b]1、computed计算属性函数中不能使用vm变量[/b] 在计算属性的函数中,不能使用Vue构造函数返回的vm变量,因为此时vm还未返回,依然处于Vue内部构造函数过程中,遂只能使用this来代替vm。 若要使用[b]typescript[/b],可使用以下方法来实现代码智能感知 vm = vm || this; 另:其他不能用vm变量,只能使用this变量的地方,都可以通过此方法来获得Typescript的智能感知和代码语法检查,比如[b]mounted[/b]生命周期系列函数等。 不过模板里的vm引用Typescript无能为力,只能等待ts支持vue的jsx语法了╮(╯_╰)╭ [b]2、计算属性中不能引用其他计算属性?[/b] 官方教程中没有找到相关说明(应该是我没找到),从使用角度而言大致可以总结出以下结论: [list] [*]计算属性必须引用(依赖)非计算属性或固定值。(见demo1)[/*] [*]计算属性若引用(依赖)其他计算属性,则被引用的计算属性必须引用非计算属性或固定值(见demo2)[/*] [*]计算属性可循环依赖,但最终依赖链上的最上游的计算属性,必须引用非计算属性或固定值。 [/*] [/list] 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
 }
 }
});
原因很容易理解,如果最终没有引用或依赖任何非计算属性,那么计算属性在计算时会陷入死循环。 [b]3、vue2.0中若使用组件嵌套,则在父组件执行\$forceUpdate()之前模板中\$children为空数组[/b] 触发这个问题有以下几个前提: [list] [*]vue版本为2.0版本,1.0无此问题。[/*] [*]使用组件嵌套,在父组件的模板中访问$children变量[/*] [*]在渲染完成后没有再将$children变量写入过父组件的data变量(或其他vm数据)就会触发此问题。 [/*] [/list]
<!--父组件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",
});

如下图: [img]http://files.jb51.net/file_images/article/201612/2016122111005080.jpg?2016112111013[/img] [b]解决方案1:[/b]使用\$forceUpdate() 注册父组件的[b]mounted[/b]方法,执行[b]$forceUpdate()[/b]
<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正确了: [img]http://files.jb51.net/file_images/article/201612/2016122111052104.jpg?201611211114[/img] [b]解决方案2:[/b]使用vm的变量代替\$children 注册父组件的[b]mounted[/b]方法,将[b]$children[/b]赋值给自定义的vm的变量。 同时模板中使用自定义的变量来代替默认的[b]$children[/b]
<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变量
 }
});

[img]http://files.jb51.net/file_images/article/201612/2016122111216366.jpg?2016112111230[/img] 至于导致此问题的原因只能通过阅读vue2.0版本的源码才能了解了。 [b]4、若父组件的template或render函数中无引用slot元素,则\$children恒等于空数组[/b] 此问题关联上面第3个问题。 触发此问题的前提: [list] [*]vue2.0版本[/*] [*]父组件和子组件都直接写在调用方模板中[/*] [*]在模板中访问$children变量[/*] [*]已经解决在上述问题3中强制刷新的问题 [/*] [/list]
<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"
});

[img]http://files.jb51.net/file_images/article/201612/2016122111322522.jpg?2016112111357[/img] [b]解决方案1:[/b]父组件模板包含slot元素 在父组件的模板中加入slot元素。或在render函数中引用了this.$slots.default变量
Vue.component("parent", {
 template: "<p>parent child:{{$children.length}} <slot></slot></p>",
 mounted(){
 this.$forceUpdate();
 }
});
[img]http://files.jb51.net/file_images/article/201612/2016122111507869.jpg?2016112111521[/img] [b]解决方案2:[/b]在父组件模板中编写子组件定义 此解决方案要修改此问题的复现第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: []
 }
});

[img]http://files.jb51.net/file_images/article/201612/2016122111557967.jpg?201611211165[/img] 此方法虽然可以解决问题,但是有时我们直接把子组件写在调用方会更方便更利于理解,比如Tab与TabPage组件。 如下Tab组件代码,可能更符合一般人的使用思维:
<div id="app">
 <tab>
 <tab-page>Page1</tab-page>
 <tab-page>Page2</tab-page>
 <tab-page>Page3</tab-page>
 </tab>
</div>
[b]相关笔记[/b] Vue学习笔记-1([url=http://www.1sucai.cn/article/98869.htm]http://www.1sucai.cn/article/98869.htm[/url]) Vue学习笔记-2([url=http://www.1sucai.cn/article/98878.htm]http://www.1sucai.cn/article/98878.htm[/url]) 本文已被整理到了《[url=http://www.1sucai.cn/Special/874.htm]Vue.js前端组件学习教程[/url]》,欢迎大家学习阅读。 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程素材网。
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部