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 元素:如果用在子组件上,引用就指向组件实例,例如: ...
随机推荐
- WPF数据模板(7)
数据模板常用在3种类型的控件, 下图形式: 1.Grid这种列表表格中修改Cell的数据格式, CellTemplate可以修改单元格的展示数据的方式. 2.针对列表类型的控件, 例如树形控件,下拉列 ...
- Python对csv排序
#/usr/bin/evn python # -*- coding: utf-8 -*- import sys from operator import itemgetter # input_file ...
- CentOS7 vsftp 安装与配置(视频教程)
(双击全屏播放) 1.安装vsftpd yum install -y vsftpd 2.编辑ftp配置文件 vi /etc/vsftpd/vsftpd.conf anonymous_enable=NO ...
- PHP 数组函数大全
PHP数组函数是核心的一部分.无需安装即可使用这些函数 函数名称 描述 array_change_key_case 将数组中的所有键名修改为全大写或小写 array_chunk 将一个数组分割成多个 ...
- flask uwsgi和nginx配置信息
1. 安装 pip3 install uwsgi 2. uwsgi配置信息 创建一个uwsgi.ini文件 [uwsgi] socket=/opt/script/uwsgi.sock #启动程序时所使 ...
- jmeter压测学习6-HTTP Cookie管理器
前言 web网站的请求大部分都有cookies,jmeter的HTTP Cookie管理器可以很好的管理cookies. 我用的 jmeter5.1 版本,直接加一个HTTP Cookie管理器放到请 ...
- flask的request如何获取参数
1.request.form.get("key", type=str, default=None) 获取表单数据 2.request.args.get("key" ...
- vue-router路由传参之query和params
首先简单来说明一下$router和$route的区别 //$router : 是路由操作对象,只写对象 //$route : 路由信息对象,只读对象 //操作 路由跳转 this.$router.pu ...
- android主流开源自动化框架(monkeyrunner,robotium,uiautomator)转载
摘要: android自动化框架小结:monkey,monkeyrunner,cts,robotium,uiautomator android自动化框架: Uiautomator: 优点:可以对所有操 ...
- LeetCode 153. Find Minimum in Rotated Sorted Array寻找旋转排序数组中的最小值 (C++)
题目: Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. ( ...