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属性详解的更多相关文章

  1. Vue.js 源码分析(十三) 基础篇 组件 props属性详解

    父组件通过props属性向子组件传递数据,定义组件的时候可以定义一个props属性,值可以是一个字符串数组或一个对象. 例如: <!DOCTYPE html> <html lang= ...

  2. Vue.js 源码分析(五) 基础篇 方法 methods属性详解

    methods中定义了Vue实例的方法,官网是这样介绍的: 例如:: <!DOCTYPE html> <html lang="en"> <head&g ...

  3. Vue.js 源码分析(四) 基础篇 响应式原理 data属性

    官网对data属性的介绍如下: 意思就是:data保存着Vue实例里用到的数据,Vue会修改data里的每个属性的访问控制器属性,当访问每个属性时会访问对应的get方法,修改属性时会执行对应的set方 ...

  4. Vue.js 源码分析(三) 基础篇 模板渲染 el、emplate、render属性详解

    Vue有三个属性和模板有关,官网上是这样解释的: el ;提供一个在页面上已存在的 DOM 元素作为 Vue 实例的挂载目标 template ;一个字符串模板作为 Vue 实例的标识使用.模板将会 ...

  5. Vue.js 源码分析(二) 基础篇 全局配置

    Vue.config是一个对象,包含Vue的全局配置,可以在启动应用之前修改下列属性,如下: ptionMergeStrategies        ;自定义合并策略的选项silent         ...

  6. Vue.js 源码分析(九) 基础篇 生命周期详解

    先来看看官网的介绍: 主要有八个生命周期,分别是: beforeCreate.created.beforeMount.mounted.beforeupdate.updated   .beforeDes ...

  7. Vue.js 源码分析(八) 基础篇 依赖注入 provide/inject组合详解

    先来看看官网的介绍: 简单的说,当组件的引入层次过多,我们的子孙组件想要获取祖先组件的资源,那么怎么办呢,总不能一直取父级往上吧,而且这样代码结构容易混乱.这个就是这对选项要干的事情 provide和 ...

  8. Vue.js 源码分析(七) 基础篇 侦听器 watch属性详解

    先来看看官网的介绍: 官网介绍的很好理解了,也就是监听一个数据的变化,当该数据变化时执行我们的watch方法,watch选项是一个对象,键为需要观察的数据名,值为一个表达式(函数),还可以是一个对象, ...

  9. Vue.js 源码分析(十) 基础篇 ref属性详解

    ref 被用来给元素或子组件注册引用信息.引用信息将会注册在父组件的 $refs 对象上.如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素:如果用在子组件上,引用就指向组件实例,例如: ...

随机推荐

  1. js和C#互相调用

    快速上手 js和C#互相调用. C#调用js比较容易.JS调用C#代码,现有两种方法.老方法的缺点是只支持单页,如果切换页面,原有创建的变量就失效了.新方法没有这些问题. 老方法: Cefsharp ...

  2. word转html预览

    #region Index页面 /// <summary> /// Index页面 /// </summary> /// <paramname="url&quo ...

  3. 深入浅出《设计模式》之简单工厂模式(C++)

    前言 模式介绍 简单工厂模式其实并不属于GoF23(23种设计模式),更类似工厂模式的一种变型.其定义是可以根据参数的不同返回不同类的实例.简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实 ...

  4. 记一次CTF出题WP

    笔者有幸参与一次CTF入门级的出题,在此记录一下WP 1.测试你得手速 1.用IDA打开程序 找到单击次数, 获取全局变量地址. 打开程序 打开OllyDbg attcach后在左下角按CTRL+N ...

  5. npm和cnpm命令后无响应

    问题: 1.把前端环境配制完毕之后,打开项目,输入cnpm install之后,光标一直在另起一行的位置闪,但是丝毫没有在安装的迹象. 2.打开cmd,在窗体中输入node -v 可以显示版本,但是输 ...

  6. 使用 docker-compose 运行 MySQL

    使用 docker-compose 运行 MySQL 目录结构 . │ .env │ docker-compose.yml │ └─mysql ├─config │ my.cnf │ └─data m ...

  7. Struts2 : action跳转时带参数跳转

    在实现action跳转到另一个action时,需要携带参数,可以直接在struts.xml配置文件中对应的跳转action的地方加上,参数的配置,用ognl表达式,可以从session中取值. 如果要 ...

  8. tp5中使用原生sql查询总结【转】

    注意事项: 1.先在database.php中配置好数据库 2.只要是数据库操作必须引用 use/think/Db;严格区分大小写. 下面是方法: public function hello5() { ...

  9. go-torch安装和使用

    go-torch安装 1.安装FlameGraph脚本 git clone https://github.com/brendangregg/FlameGraph.git cp FlameGraph/f ...

  10. Qt 之 qwt 和 qwtpolar 的编译配置

    1  Qwt Qwt 全称为 Qt Widgets for Technical Applications,用于专业技术领域的可视化显示,如下所示: 左图为二阶系统的频率响应:中图为德国小城 Fried ...