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 库名 ...
随机推荐
- Swagger2在DBA Service中生成RESTful API的实践
目的与背景: 目的:对外暴露DBA Service必要的RESTful API,形成规整的API文档 背景:DBA Service后端采用Spring-boot,属于Spring家族,故生成API的工 ...
- 一文综述python读写csv xml json文件各种骚操作
Python优越的灵活性和易用性使其成为最受欢迎的编程语言之一,尤其是对数据科学家而言.这在很大程度上是因为使用Python处理大型数据集是很简单的一件事情. 如今,每家科技公司都在制定数据战略. ...
- HDU - 1160 最长上升子序列以及记录路径
题意:第一列,给出老鼠的重量,第二列,给出老鼠的速度,要证明老鼠的重量越大,速度越小,给出最多老鼠的数量,并说明第几只. 思路:先将老鼠按照重量从大到小排序,然后速度是从小到大,求最长上升子序列,学习 ...
- Consul+upsync+Nginx 动态负载均衡
1,动态负载均衡 传统的负载均衡,如果修改了nginx.conf 的配置,必须需要重启nginx 服务,效率不高.动态负载均衡,就是可配置化,动态化的去配置负载均衡. 2,实现方案 1. Consul ...
- link与@import区别整理,一个表格带你了解
网上有许多link和@import的文章,不过大多比较零散,个人觉得一个表格的话看起来能够直观的表达. 于是制作了如下表格: 关于权重这个存在着一些争议,这次碰巧看到了一篇的博客很好的解释了这个问题, ...
- [Asp.Net Core] 为什么选择 Blazor Server Side (一) 快速实现图片验证码
关于Blazor 由于在国内, Blazor一点都不普及, 建议读者翻看我之前写的随笔, 了解Blazor Server Side的特点. 在一段时间内, 我会写一些解说分析型的 "为什么选 ...
- Go语言库系列之email
导读 大家好我是平也,今天跟大家介绍一款用来发送邮件的Go语言库email,目前星星1.3k,非常好用. 极速上手 准备工作 初始化项目 go get github.com/jordan-wright ...
- PostgreSql 自定义函数:批量调整某个字段长度
CREATE or replace FUNCTION alterColumn(cloumnName VARCHAR(32), out v_retcode text)AS$BODY$ declare r ...
- 金三银四科学找工作,用python大数据分析一线城市1000多份岗位招聘需求
文章每周持续更新,各位的「三连」是对我最大的肯定.可以微信搜索公众号「 后端技术学堂 」第一时间阅读(一般比博客早更新一到两篇) 每年的三四月份是招聘高峰,也常被大家称为金三银四黄金招聘期,这时候上一 ...
- 使用Shiro+JWT完成的微信小程序的登录(含讲解)
使用Shiro+JWT完成的微信小程序的登录 源码地址https://github.com/Jirath-Liu/shiro-jwt-wx 微信小程序用户登陆,完整流程可参考下面官方地址,本例中是按此 ...