vue2.x学习笔记(二十)
接着前面的内容: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学习笔记(二十)的更多相关文章
- python3.4学习笔记(二十六) Python 输出json到文件,让json.dumps输出中文 实例代码
python3.4学习笔记(二十六) Python 输出json到文件,让json.dumps输出中文 实例代码 python的json.dumps方法默认会输出成这种格式"\u535a\u ...
- python3.4学习笔记(二十五) Python 调用mysql redis实例代码
python3.4学习笔记(二十五) Python 调用mysql redis实例代码 #coding: utf-8 __author__ = 'zdz8207' #python2.7 import ...
- python3.4学习笔记(二十四) Python pycharm window安装redis MySQL-python相关方法
python3.4学习笔记(二十四) Python pycharm window安装redis MySQL-python相关方法window安装redis,下载Redis的压缩包https://git ...
- python3.4学习笔记(二十二) python 在字符串里面插入指定分割符,将list中的字符转为数字
python3.4学习笔记(二十二) python 在字符串里面插入指定分割符,将list中的字符转为数字在字符串里面插入指定分割符的方法,先把字符串变成list然后用join方法变成字符串str=' ...
- python3.4学习笔记(二十) python strip()函数 去空格\n\r\t函数的用法
python3.4学习笔记(二十) python strip()函数 去空格\n\r\t函数的用法 在Python中字符串处理函数里有三个去空格(包括'\n', '\r', '\t', ' ')的函数 ...
- (C/C++学习笔记) 二十四. 知识补充
二十四. 知识补充 ● 子类调用父类构造函数 ※ 为什么子类要调用父类的构造函数? 因为子类继承父类,会继承到父类中的数据,所以子类在进行对象初始化时,先调用父类的构造函数,这就是子类的实例化过程. ...
- (C/C++学习笔记) 二十二. 标准模板库
二十二. 标准模板库 ● STL基本介绍 标准模板库(STL, standard template library): C++提供的大量的函数模板(通用算法)和类模板. ※ 为什么我们一般不需要自己写 ...
- (C/C++学习笔记) 二十. 文件和流
二十. 文件和流 ● 文件的概念 文件(file) 一. C/C++语言将文件作为字节序列(sequence of characters)来对待,但从编码角度,或说从对字节信息的解释来看,文件分为:文 ...
- vue2.x学习笔记(十二)
接着前面的内容:https://www.cnblogs.com/yanggb/p/12592256.html. 组件基础 组件化是vue的一个重要特性,也是vue学习中非常重要的一个知识点. 基础示例 ...
- Java基础学习笔记二十五 MySQL
MySQL 在dos中操作mysql 连接mysql命令: mysql -uroot -p密码 ,连接OK,会出现mysql> 对数据库的操作 创建一个库 create database 库名 ...
随机推荐
- “GANs”与“ODEs”:数学建模的终结?
在本文中,我想将经典数学建模和机器学习之间建立联系,它们以完全不同的方式模拟身边的对象和过程.虽然数学家基于他们的专业知识和对世界的理解来创建模型,而机器学习算法以某种隐蔽的不完全理解的方式描述世界, ...
- nodejs使用express中静态资源托管(express.static())时遇到的bug
如下:将test.html的页面挂载在服务器上, const express= require('express') const fs= require('fs') let app = express ...
- SimpleITK中术语
在SimpleITK中,各术语对应如下: Width: 宽度,X轴,矢状面Height: 高度,Y轴,冠状面Depth: 深度, Z轴,横断面 引用自:https://blog.csdn.net/Ji ...
- win10 系统中vscode 的终端 shell 设置
今天,打算开始搞一个个人博客小项目. 主力台式电脑在实验室,于是重新配了一下自己的小破笔记本.系统是之前自己捣鼓的 win10 .在打开终端调试 node 时,发现报了这么一个错. 我刚开始以为是自己 ...
- SSM随笔
1.搭建基本web项目2.在WEB-INF下面添加lib和classes包,并修改路径3.拷贝jar包 主要包括spring包+spring依赖包+myBatis包+mysql驱动包4.编辑sprin ...
- 7.Metasploit后渗透
Metasploit 高阶之后渗透 01信息收集 应用场景: 后渗透的第一步,更多地了解靶机信息,为后续攻击做准备. 02进程迁移 应用场景: 如果反弹的meterpreter会话是对方打开了一个你预 ...
- 2019NYIST计科第七次周赛总结
2019NYIST计科第七次周赛总结 文章目录 2019NYIST计科第七次周赛总结 [秤取物体重量( 二进制枚举法)](https://blog.csdn.net/qq_34261446/artic ...
- stm32:extern关键字
参考:http://c.biancheng.net/view/404.html 1.在一个文件中: #include <stdio.h> int max(int x,int y); int ...
- 1042 Shuffling Machine (20分)(水)
Shuffling is a procedure used to randomize a deck of playing cards. Because standard shuffling techn ...
- PTA | 1010 一元多项式求导 (25分)
设计函数求一元多项式的导数.(注:xn(n为整数)的一阶导数为n*xn-1.) 输入格式: 以指数递降方式输入多项式非零项系数和指数(绝对值均为不超过1000的整数).数字间以空格分隔. 输出格式: ...