接着前面的内容:https://www.cnblogs.com/yanggb/p/12631279.html

循环引用

递归组件

组件是可以在它们自己的模板中调用自身的,不过它们只能通过【name】选项来做这件事。

name: 'unique-name-of-my-component'

当你使用【Vue.component】全局注册一个组件的时候,这个全局的id就会自动设置为该组件的【name】选项。

Vue.component('unique-name-of-my-component', {
// ...
})

但是稍有不慎,递归组件就可能会导致无限循环,进而导致页面渲染引擎奔溃的情况:

name: 'stack-overflow',
template: '<div><stack-overflow></stack-overflow></div>'

类似上述的组件将会导致【max stack size exceeded】错误,所以请确保递归调用是有条件的(例如使用一个最终会得到false的【v-if】指令)。

组件之间的循环引用

假设你需要构建一个文件目录树,像资源管理器那样的,你可能就会有一个<tree-folder>组件,模板是这样的:

<p>
<span>{{ folder.name }}</span>
<tree-folder-contents :children="folder.children"/>
</p>

还会有一个<tree-folder-contents>组件,模板是这样的:

<ul>
<li v-for="child in children">
<tree-folder v-if="child.children" :folder="child"/>
<span v-else>{{ child.name }}</span>
</li>
</ul>

当你仔细观察的时候,会发现这些组件在渲染树中互为对方的后代和祖先——一个悖论!当通过【Vue.component】全局注册组件的时候,这个悖论会被自动解开。当时如果你使用的是一个模块系统依赖/导入组件,例如通过webpack或browserify,你就会遇到一个错误:

Failed to mount component: template or render function not defined.

为了解释这里发生了什么,我们先把这两个组件称为A和B。模块系统发现它需要A,但是首先A依赖B,但是B又依赖A,但是A又依赖B,如此反复,就变成了一个死循环,解析器不知道如何不经过其中一个组件而完全解析出另一个组件。因此,为了解决这个问题,我们需要给模块系统一个点,告诉模块系统:A反正是需要B的,但是我们不需要先解析B。

在上面的例子中,我们可以把<tree-folder>组件设为那个点。我们知道,那个产生悖论的子组件是<tree-folder-contents>组件,所以我们会等到生命周期钩子函数【beforeCreate】时去注册它:

beforeCreate: function () {
this.$options.components.TreeFolderContents = require('./tree-folder-contents.vue').default
}

或者,在本地注册组件的时候,你可以使用webpack的异步import(推荐):

components: {
TreeFolderContents: () => import('./tree-folder-contents.vue')
}

这样问题就解决了!

模板定义的替代品

内联模板

当【inline-template】这个特殊的属性出现在一个子组件上的时候,这个组件将会使用其里面的内容作为模板,而不是将其作为被分发的内容。这使得模板的撰写工作更加灵活:

<my-component inline-template>
<div>
<p>These are compiled as the component's own template.</p>
<p>Not parent's transclusion content.</p>
</div>
</my-component>

内联模板需要定义在vue所属的dom元素内。

但是要注意的是,【inline-template】属性会让模板的作用域变得更加难以理解。所以,作为最佳实践,请在组件内优先选择【template】选项或在【.vue】文件里的一个<template>元素来定义模板。

x-template

另一个定义模板的方式是在一个<script>元素中,并为其带上【text/x-template】的类型,然后通过一个id将模板引用过去,例如:

<script type="text/x-template" id="hello-world-template">
<p>Hello hello hello</p>
</script>
Vue.component('hello-world', {
template: '#hello-world-template'
})

要特别注意的是,x-template需要定义在vue所属的dom元素外。

上面的这两种方式可以用于模板特别大的demo或者极小型的应用,但是在其它的情况下请尽量避免使用,因为这回将模板和该组件的其他定义分离开,不利于后期的维护。

控制更新

vue的响应式系统可以知道何时进行dom更新(如果你用对了的话),不过其终究会存在局限性。因此,在一些边界情况你会想要强制更新,尽管表面上看响应式的数据没有发生改变,也有一些情况你会想要阻止不必要的更新。

强制更新

如果你发现你需要在vue中做一次强制更新,官方文档强调,99.9的情况,是你在某个地方做错了事。

你可能还没有留意到数组或对象的变更检测注意事项,或者你可能依赖了一个未被vue响应式系统追踪的状态。然而,如果你已经做到了上述的事项仍然发现在极少数的情况下需要手动强制更新的话,那么你可以通过【$forceUpdate】全局属性来做这件事。

vm.$forceUpdate()

这样会迫使vue实例重新渲染。注意它仅仅影响实例本身和插入插槽内容的子组件,而不是所有的子组件。

通过【v-once】指令创建低开销的静态组件

渲染普通的html元素在vue中是非常快速的,但有的时候你可能有一个组件,这个组件包含了大量的静态内容。在这种情况下,你可以在根元素上添加【v-once】指令以确保这些内容只计算一次然后缓存起来,就像这样:

Vue.component('terms-of-service', {
template: `
<div v-once>
<h1>Terms of Service</h1>
... a lot of static content ...
</div>
`
})

可能前面已经说过了,但是在这里还是要再说一次:要格外注意不要过度使用这个模式。当你需要渲染大量的静态内容的时候,极少数的情况下它会给你带来便利,除非你非常留意渲染变慢了,不然它完全是没有必要的——再加上它在后期会带来很多的困惑。例如,设想另一个开发者并不熟悉【v-once】指令或漏看了它在模板中,他可能会花费很多个小时去找出模板为什么无法被正确更新的原因。

"我还是很喜欢你,像无缘花了荼靡,小楼寂寂。"

vue2.x学习笔记(二十)的更多相关文章

  1. python3.4学习笔记(二十六) Python 输出json到文件,让json.dumps输出中文 实例代码

    python3.4学习笔记(二十六) Python 输出json到文件,让json.dumps输出中文 实例代码 python的json.dumps方法默认会输出成这种格式"\u535a\u ...

  2. python3.4学习笔记(二十五) Python 调用mysql redis实例代码

    python3.4学习笔记(二十五) Python 调用mysql redis实例代码 #coding: utf-8 __author__ = 'zdz8207' #python2.7 import ...

  3. python3.4学习笔记(二十四) Python pycharm window安装redis MySQL-python相关方法

    python3.4学习笔记(二十四) Python pycharm window安装redis MySQL-python相关方法window安装redis,下载Redis的压缩包https://git ...

  4. python3.4学习笔记(二十二) python 在字符串里面插入指定分割符,将list中的字符转为数字

    python3.4学习笔记(二十二) python 在字符串里面插入指定分割符,将list中的字符转为数字在字符串里面插入指定分割符的方法,先把字符串变成list然后用join方法变成字符串str=' ...

  5. python3.4学习笔记(二十) python strip()函数 去空格\n\r\t函数的用法

    python3.4学习笔记(二十) python strip()函数 去空格\n\r\t函数的用法 在Python中字符串处理函数里有三个去空格(包括'\n', '\r', '\t', ' ')的函数 ...

  6. (C/C++学习笔记) 二十四. 知识补充

    二十四. 知识补充 ● 子类调用父类构造函数 ※ 为什么子类要调用父类的构造函数? 因为子类继承父类,会继承到父类中的数据,所以子类在进行对象初始化时,先调用父类的构造函数,这就是子类的实例化过程. ...

  7. (C/C++学习笔记) 二十二. 标准模板库

    二十二. 标准模板库 ● STL基本介绍 标准模板库(STL, standard template library): C++提供的大量的函数模板(通用算法)和类模板. ※ 为什么我们一般不需要自己写 ...

  8. (C/C++学习笔记) 二十. 文件和流

    二十. 文件和流 ● 文件的概念 文件(file) 一. C/C++语言将文件作为字节序列(sequence of characters)来对待,但从编码角度,或说从对字节信息的解释来看,文件分为:文 ...

  9. vue2.x学习笔记(十二)

    接着前面的内容:https://www.cnblogs.com/yanggb/p/12592256.html. 组件基础 组件化是vue的一个重要特性,也是vue学习中非常重要的一个知识点. 基础示例 ...

  10. Java基础学习笔记二十五 MySQL

    MySQL 在dos中操作mysql 连接mysql命令: mysql -uroot -p密码 ,连接OK,会出现mysql> 对数据库的操作 创建一个库 create database 库名 ...

随机推荐

  1. BZOJ 压力 tarjan 点双联通分量+树上差分+圆方树

    题意 如今,路由器和交换机构建起了互联网的骨架.处在互联网的骨干位置的核心路由器典型的要处理100Gbit/s的网络流量. 他们每天都生活在巨大的压力之下.小强建立了一个模型.这世界上有N个网络设备, ...

  2. java 环境变量配置与第一个程序运行

    从开始下载jdk,到运行出java第一个程序 ,花了5天时间 ,不过我相信万事开头难 ,以后会越来越好的 ,加油! jdk的下载: 在oracle官网上即可下载,jdk安装包,下载完以后运行安装 ,路 ...

  3. Springcloud config + zuul 搭建动态网关

    1,实现的效果,就是zuul 网关的配置路由实现负载均衡,zuul 的配置文件放在springcloud config 上 2,需要的服务如下: 3,其实就是配置下springcloud-zuul 的 ...

  4. iOS 内存管理:从 MRC 到 ARC 实践

    对于 iOS 程序员来说,内存管理是入门的必修课.引用计数.自动释放等概念,都是与 C 语言完全不同的. iOS 内存管理的核心是引用计数. 接触 MRC 时遇到最头疼的问题就是:为什么那么多 rel ...

  5. [noip模拟20170921]模版题

      今天考的是一套很基础的模版题,但是我这种蒟蒻竟然还是没有AK,不得不说,蒟蒻和大佬的差别不是一点点啊 1.暴走的猴子(walk.pas/c/cpp) [题目描述] 从前有一个森林,森林里生活着一群 ...

  6. ES6 class 类的理解(一)

    优点 ES6 的类提供了几点明显的好处: 兼容当前大量的代码. 相对于构造器和构造器继承,类使初学者更容易入门. 子类化在语言层面支持. 可以子类化内置的构造器. 不再需要继承库:框架之间的代码变得更 ...

  7. 版本控制git的简单使用

    0.第一次使用时配置: git config --global user.name "your_name" git config --global user.email " ...

  8. 字符串截取及切割,正则表达式,expect预期交互

                                            字符串截取及切割,正则表达式,expect预期交互 案例1:字符串截取及切割 案例2:字符串初值的处理 案例3:expe ...

  9. php simplexml_load_string 返回的对象print_r后,丢失信息?

    <?php $content = '<dblp> <inproceedings key="conf/aaim/He07" mdate="2007- ...

  10. 家庭记账本app进度之复选框以及相应滚动条的应用

    这次主要是对于android中复选框的相应的操作.以及其中可能应用到的滚动条的相关应用.每一个复选框按钮都要有一个checkBox与之相对应. 推荐使用XML配置,基本语法如下:<CheckBo ...