Vue2

Vue学习笔记-2

目录

前言

本文非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、计算属性中不能引用其他计算属性?

官方教程中没有找到相关说明(应该是我没找到),从使用角度而言大致可以总结出以下结论:

1、计算属性必须引用(依赖)非计算属性或固定值。(见demo1)
2、计算属性若引用(依赖)其他计算属性,则被引用的计算属性必须引用非计算属性或固定值(见demo2)
3、计算属性可循环依赖,但最终依赖链上的最上游的计算属性,必须引用非计算属性或固定值。

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为空数组

触发这个问题有以下几个前提:
1、vue版本为2.0版本,1.0无此问题。
2、使用组件嵌套,在父组件的模板中访问$children变量
3、在渲染完成后没有再将$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个问题。
触发此问题的前提:
1、vue2.0版本
2、父组件和子组件都直接写在调用方模板中
3、在模板中访问$children变量
4、已经解决在上述问题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(http://www.cnblogs.com/xxcanghai/p/5849038.html)

Vue学习笔记-2(http://www.cnblogs.com/xxcanghai/p/6098663.html)

时间: 2024-10-06 16:27:13

Vue2的相关文章

Vue.js系列之项目搭建(vue2.0 + vue-cli + webpack )

1.安装node node.js环境(npm包管理器) cnpm npm的淘宝镜像 从node.js官网下载并安装node,安装过程很简单,一路"下一步"就可以了(傻瓜式安装).安装完成之后,打开命令行工具,输入 node -v,如果出现相应的版本号,则说明安装成功. npm包管理器,是集成在node中的,所以,直接输入 npm -v就会显示出npm的版本信息. 2.安装cnpm 在命令行中输入 npm install -g cnpm --registry=http://registr

Vue2.0总结———vue使用过程常见的一些问题

Vue目前的的开发模式主要有两种: 1.直接页面级的开发,script直接引入Vue 2.工程性开发,webpack+loader或者直接使用脚手架工具Vue-cli,里面的文件都配置好了 webpack可以进行配置,配置多文件入口,进行多页面开发 第二种Vue开发,结合webpack打包完文件会很大,怎么解决这个问题? 1.webpack代码拆分:code-spliting 2.提取公共(如提取css,js) 3.预渲染:使用prerender-spa-plugin插件 4.后台----开启压

Vue2.0与 [百度地图] 结合使用———vue+webpack+axios+百度地图实现组件之间的通信

Vue2.0与 [百度地图] 结合使用: 1.vue init webpack-simple vue-baidu-map 2.下载axios cnpm install axios; 3.在main.js中引入axios,并使用 import axios from 'axios' /* 把axios对象挂到Vue实例上面,其他组件在使用axios的时候直接 this.$http就可以了 */ Vue.prototype.$http = axios; 4.引入百度地图的js秘钥--->最好在inde

[js高手之路]Vue2.0基于vue-cli+webpack父子组件通信教程

在git命令行下,执行以下命令完成环境的搭建: 1,npm install --global vue-cli  安装vue命令行工具 2,vue init webpack vue-demo   使用vue命令生成一个webpack项目,项目名称为vue-demo 3,cd vue-demo 切入项目 4,npm install安装package.json中的所有依赖包 5,npm run dev运行项目 一.父组件向子组件传递数据 然后删除默认的Hello.vue组件,把App.vue整理成以下

项目总结1(微信+vue2.0)

项目总结(vue2.0) 一.基础知识 1.生命周期(项目到用到的) Created:组件实例化创建完成,属性绑定DOM未完成.($el 属性还不存在). Mounted:组件挂在完成,虚拟DOM渲染到html上,mounted知执行一次(从mounted就可以获取到$refs,进行操作). 一般在created或是mounted进行一些ajax操作. updated:组件更新之后,可以获取到DOM节点. 2.数据渲染 v-if:是否创建DOM.一般用在不是频繁创建DOM元素的情况下,否则可用v

vue2.0版本指令v-if与v-show的区别

v-if: 判断是否加载,可以减轻服务器的压力,在需要时加载. v-show:调整css dispaly属性,可以使客户端操作更加流畅. v-if示例: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <script src="vue2.2.js"></script> </he

Vue2+VueRouter2+webpack 构建项目实战(二):目录以及文件结构

通过上一篇博文<Vue2+VueRouter2+webpack 构建项目实战(一):准备工作>,我们已经新建好了一个基于vue+webpack的项目.本篇文章详细介绍下项目的结构. 项目目录以及文件结构 如图所示: 如上图所示,自动构建的vue项目的结构就是这样. 目录/文件 说明 build 这个是我们最终发布的时候会把代码发布在这里,在开发阶段,我们基本不用管. config 配置目录,默认配置没有问题,所以我们也不用管 node_modules 项目开发依赖的一些模块 src 开发目录(

vue1与vue2的路由 以及vue2项目大概了解

vue1的路由 1.设置根组件  Vue.extend() 2.设置局部组件  Vue.extend({template:"/home"}) 3.实例化路由   var router =new VueRouter() 4.关联路由      router.map({"./",组件名字}) 5.开启路由     router.start("根组件","#box") 6.配置默认选项  router.redirect("

vue2.0 之文本渲染-v-html、v-text

vue2.0 之文本渲染-v-html.v-text 1.index.html代码 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>vuedemo</title> </head> <body> <div id="app"></div> <!-- built files w

vue2.0项目实战(3)生命周期和钩子函数详解

最近的项目都使用vue2.0来开发,不得不说,vue真的非常好用,大大减少了项目的开发周期.在踩坑的过程中,因为对vue的生命周期不是特别了解,所以有时候会在几个钩子函数里做一些事情,什么时候做,在哪个函数里做,我们不清楚. 下面来总结一下vue的生命周期. vue生命周期简介 咱们从上图可以很明显的看出现在vue2.0都包括了哪些生命周期的函数了. 生命周期探究 对于执行顺序和什么时候执行,看上面两个图基本有个了解了.下面我们将结合代码去看看钩子函数的执行. <!DOCTYPE html>