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 元素:如果用在子组件上,引用就指向组件实例,例如: ...
随机推荐
- Linux链接文件——软连接和硬链接
Linux链接文件——软连接和硬链接 摘要:本文主要介绍了Linux系统中的链接文件. 文件系统 在Linux系统中,将文件分为两个部分:用户数据和元数据. 元数据(inode) 元数据即文件的索引节 ...
- IOS疯狂基础之观察者模式
转自:http://blog.csdn.net/wudizhukk/article/details/8981535 一.KVO Key-Value Observing,它提供一种机制,当指定的对象的属 ...
- 绕过基于签名的XSS筛选器:修改HTML
绕过基于签名的XSS筛选器:修改HTML 在很多情况下,您可能会发现基于签名的过滤器只需切换到一个不太熟悉的执行脚本的方法即可.如果失败了,您需要查看混淆攻击的方法. 本文提供了HTML语法可以被混淆 ...
- MES系统如何帮助烟草行业管理生产流程
与很多其他行业一样,烟草MES系统可以帮助卷烟企业实现智能生产.精益制造.快速实现烟草企业数字化车间的创建,助力企业实现改造升级,从而提升企业生产效率,降低生产成产.烟草行业得MES者得天下. 烟草行 ...
- ucoreOS_lab1 实验报告
由于我个人不太懂 AT&T 语法,在完成实验的过程中遇到了相当大的阻碍,甚至有点怀疑人生,我是否心太大了,妄想在短时间内学懂大清的课程.ucoreOS_lab1 这个实验前前后后做到了现在才勉 ...
- 多线程学习笔记(二) BackgroundWorker 和 ProgressChanged
BackgroundWorker是在内部使用了线程池的技术:同时,在Winform 或WPF编码中,它还给工作线程和UI线程提供了交互的能力. Thread和ThreadPool默认都没有提供这种交互 ...
- 在VideoFileClip函数中获取“OSError:[WinError 6]句柄无效”
我正在使用python通过导入moviepy库创建一个程序,但收到以下错误: from moviepy.editor import VideoFileClip white_output = 'vide ...
- java查看进程:jps命令
java查看进程:jps命令 jps(Java Virtual Machine Process Status Tool) 是JDK .5提供的一个显示当前所有java进程pid的命令,简单实用,非常适 ...
- python 类 专有方法
__init__ : 构造函数,在生成对象时调用 __del__ : 析构函数,释放对象时使用 __repr__ : 打印,转换 __setitem__ : 按照索引赋值 __getitem__: 按 ...
- 关于UE4音效的一些小问题
前言 前几天实在忍受不了StarterContent默认音效的折磨,去网上翻罗了一下初中时很着迷的游戏<Bounce-Tales>的音效,在导入音效时出了点问题,特此说明一下解决方案,希望 ...