Vue.js 源码分析(十一) 基础篇 过滤器 filters属性详解
Vue.js 允许你自定义过滤器,可被用于一些常见的文本格式化。过滤器可以用在两个地方:双花括号插值和 v-bind 表达式 (后者从 2.1.0+ 开始支持)。过滤器应该被添加在 JavaScript 表达式的尾部,例如:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="vue.js"></script>
</head>
<body>
<div id="app"><p>{{no | add(100) }}</p></div>
<script>
debugger
var app = new Vue({
el:"#app",
data:{no:123},
filters:{
add:function(val,i){return val+i}
}
})
</script>
</body>
</html>
渲染结果为:

当我们在页面里输出某些数据,需要进行格式转换的时候可以用这个过滤器
writer by:大沙漠 QQ:22969969
源码分析
parse()解析模板时遇到文本时会执行parseText()函数,如下:
function parseText ( //第8575行 解析模板时用于解析文本
text,
delimiters
) {
var tagRE = delimiters ? buildRegex(delimiters) : defaultTagRE;
if (!tagRE.test(text)) { //匹配是否有表达式,比如:{{message}} 如果没有,则表示是纯文本节点,则直接返回不做处理
return
}
var tokens = [];
var rawTokens = [];
var lastIndex = tagRE.lastIndex = 0;
var match, index, tokenValue;
while ((match = tagRE.exec(text))) { //用正则tagRE去匹配text,此时match就是text里的每个值,对于:{{item}}:{{index}}来说,match等于Array["{{item}}","item"] 、 Array["{{index}}","index"]
index = match.index; //该数据的起始索引
// push text token
if (index > lastIndex) { //如果index大于lastIndex,表明中间还有一段文本,比如:{{item}}:{{index}},中间的:就是文本
rawTokens.push(tokenValue = text.slice(lastIndex, index));
tokens.push(JSON.stringify(tokenValue));
}
// tag token
var exp = parseFilters(match[1].trim()); //调用parseFilters对match[1做解析] ;例如{{no | add(100) }},解析后的格式为:_f("add")(no,100)
tokens.push(("_s(" + exp + ")"));
rawTokens.push({ '@binding': exp });
lastIndex = index + match[0].length; //设置下一次开始匹配的位置
}
if (lastIndex < text.length) {
rawTokens.push(tokenValue = text.slice(lastIndex));
tokens.push(JSON.stringify(tokenValue));
}
return {
expression: tokens.join('+'), //拼凑成一个 表达式,例如:"_s(item)+":"+_s(index)"
tokens: rawTokens //模板信息,例如[{@binding: "item"},":",{@binding: "index"}]
}
}
parseFilters定义在6436行,就是解析每个字符,最后拼凑出一个_f的字符,例子中执行完后等于

最后执行render函数的时候会执行_f函数,也就是Vue内部的resolveFilter函数,如下:
function resolveFilter (id) { //第3774行 过滤器对应的函数
return resolveAsset(this.$options, 'filters', id, true) || identity //执行resolveAsset函数
}
resolveAsset会获取对应资源(过滤器、组件、指令等),返回对应函数,如下:
function resolveAsset ( //第1498行 options:Vue实例的$options对象 type:类型,比如:components、filters id:获取的ID
options,
type,
id,
warnMissing
) {
/* istanbul ignore if */
if (typeof id !== 'string') {
return
}
var assets = options[type];
// check local registration variations first
if (hasOwn(assets, id)) { return assets[id] } //先从当前实例上找id
var camelizedId = camelize(id);
if (hasOwn(assets, camelizedId)) { return assets[camelizedId] } //将id转化为驼峰式后再找
var PascalCaseId = capitalize(camelizedId);
if (hasOwn(assets, PascalCaseId)) { return assets[PascalCaseId] } //如果还没找到则尝试将首字母大写查找
// fallback to prototype chain
var res = assets[id] || assets[camelizedId] || assets[PascalCaseId]; //最后通过原型来查找
if ("development" !== 'production' && warnMissing && !res) {
warn(
'Failed to resolve ' + type.slice(0, -1) + ': ' + id,
options
);
}
return res
}
执行完后_f("add")(no,100)里的_f("add")就会变成app实例里的add过滤器对应的函数了
Vue.js 源码分析(十一) 基础篇 过滤器 filters属性详解的更多相关文章
- Vue.js 源码分析(十三) 基础篇 组件 props属性详解
父组件通过props属性向子组件传递数据,定义组件的时候可以定义一个props属性,值可以是一个字符串数组或一个对象. 例如: <!DOCTYPE html> <html lang= ...
- Vue.js 源码分析(五) 基础篇 方法 methods属性详解
methods中定义了Vue实例的方法,官网是这样介绍的: 例如:: <!DOCTYPE html> <html lang="en"> <head&g ...
- Vue.js 源码分析(四) 基础篇 响应式原理 data属性
官网对data属性的介绍如下: 意思就是:data保存着Vue实例里用到的数据,Vue会修改data里的每个属性的访问控制器属性,当访问每个属性时会访问对应的get方法,修改属性时会执行对应的set方 ...
- Vue.js 源码分析(三) 基础篇 模板渲染 el、emplate、render属性详解
Vue有三个属性和模板有关,官网上是这样解释的: el ;提供一个在页面上已存在的 DOM 元素作为 Vue 实例的挂载目标 template ;一个字符串模板作为 Vue 实例的标识使用.模板将会 ...
- Vue.js 源码分析(二) 基础篇 全局配置
Vue.config是一个对象,包含Vue的全局配置,可以在启动应用之前修改下列属性,如下: ptionMergeStrategies ;自定义合并策略的选项silent ...
- Vue.js 源码分析(九) 基础篇 生命周期详解
先来看看官网的介绍: 主要有八个生命周期,分别是: beforeCreate.created.beforeMount.mounted.beforeupdate.updated .beforeDes ...
- Vue.js 源码分析(八) 基础篇 依赖注入 provide/inject组合详解
先来看看官网的介绍: 简单的说,当组件的引入层次过多,我们的子孙组件想要获取祖先组件的资源,那么怎么办呢,总不能一直取父级往上吧,而且这样代码结构容易混乱.这个就是这对选项要干的事情 provide和 ...
- Vue.js 源码分析(七) 基础篇 侦听器 watch属性详解
先来看看官网的介绍: 官网介绍的很好理解了,也就是监听一个数据的变化,当该数据变化时执行我们的watch方法,watch选项是一个对象,键为需要观察的数据名,值为一个表达式(函数),还可以是一个对象, ...
- Vue.js 源码分析(十) 基础篇 ref属性详解
ref 被用来给元素或子组件注册引用信息.引用信息将会注册在父组件的 $refs 对象上.如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素:如果用在子组件上,引用就指向组件实例,例如: ...
随机推荐
- 基于WEB的网上购物系统-ssh源码
基于WEB的网上购物系统主要功能包括:前台用户登录退出.注册.在线购物.修改个人信息.后台商品管理等等.本系统结构如下:(1)商品浏览模块: 实现浏览最新商品 实现按商品名 ...
- Spring循环依赖原因及如何解决
浅谈Spring解决循环依赖的三种方式 SpringBoot构造器注入循环依赖及解决 原文:https://www.baeldung.com/circular-dependencies-in-spri ...
- Struts2 常量配置
除了action的配置,struts还有其他的一些配置,比如编码方式. 这些配置用键值对来表示,键是固定的,是常量,所以也叫做常量配置. 常量配置有5种方式,Struts会按以下顺序依次搜索加载常量( ...
- SQL中的视图(极客时间)
视图 视图也就是虚拟表, 本身不具备数据, 是SQL中的一个变红要概念. 如图 视图可以帮助我们使用表的一部分, 而不是所有的表, 另一方面可以针对不同的用户制定不同的查询视图. 创建, 更新与删除视 ...
- xshell5运行hadoop集群
---恢复内容开始--- 1.CentOS主机配置 在配置Hadoop过程中,防火墙必须优先关闭SELinux,否则将影响后续Hadoop配置与使用,命令如下: # 查看 “系统防火墙” 状态命令 s ...
- python使用ftplib模块实现FTP文件的上传下载
python已经默认安装了ftplib模块,用其中的FTP类可以实现FTP文件的上传下载 FTP文件上传下载 # coding:utf8 from ftplib import FTP def uplo ...
- springboot项目打成jar包后台运行在linux上
背景:springboot2为为主体搭建的项目,直接打成jar包,上传到linux上面 启动项目:java -jar xx.jar 这样很方便,但是不能关闭窗口,否则项目就停了 后台启动: nohup ...
- 2019CCPC网络赛 C - K-th occurrence HDU - 6704(后缀数组+ST表+二分+主席树)
题意 求区间l,r的子串在原串中第k次出现的位置. 链接:https://vjudge.net/contest/322094#problem/C 思路 比赛的时候用后缀自动机写的,TLE到比赛结束. ...
- 关于Apache本地能访问外网不能访问的问题
title: 关于Apache本地能访问外网不能访问的问题 date: 2018-08-05 19:22:12 tags: web --- 在配置apache和tomcat时,把它们都配置好,放到服务 ...
- HBuilder创建app 3
一.Audio 模块实现开启手机摄像头 基于html5 plus http://www.html5plus.org/doc/zh_cn/audio.html 栗子: <!DOCTYPE html ...