Vue.js 允许你自定义过滤器,可被用于一些常见的文本格式化。过滤器可以用在两个地方:双花括号插值和 v-bind 表达式 (后者从 2.1.0+ 开始支持)。过滤器应该被添加在 JavaScript 表达式的尾部,例如:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Document</title>
  6. <script src="vue.js"></script>
  7. </head>
  8. <body>
  9. <div id="app"><p>{{no | add(100) }}</p></div>
  10. <script>
  11. debugger
  12. var app = new Vue({
  13. el:"#app",
  14. data:{no:123},
  15. filters:{
  16. add:function(val,i){return val+i}
  17. }
  18. })
  19. </script>
  20. </body>
  21. </html>

渲染结果为:

当我们在页面里输出某些数据,需要进行格式转换的时候可以用这个过滤器

writer by:大沙漠 QQ:22969969

源码分析


parse()解析模板时遇到文本时会执行parseText()函数,如下:

  1. function parseText ( //第8575行 解析模板时用于解析文本
  2. text,
  3. delimiters
  4. ) {
  5. var tagRE = delimiters ? buildRegex(delimiters) : defaultTagRE;
  6. if (!tagRE.test(text)) { //匹配是否有表达式,比如:{{message}} 如果没有,则表示是纯文本节点,则直接返回不做处理
  7. return
  8. }
  9. var tokens = [];
  10. var rawTokens = [];
  11. var lastIndex = tagRE.lastIndex = 0;
  12. var match, index, tokenValue;
  13. while ((match = tagRE.exec(text))) { //用正则tagRE去匹配text,此时match就是text里的每个值,对于:{{item}}:{{index}}来说,match等于Array["{{item}}","item"] 、 Array["{{index}}","index"]
  14. index = match.index; //该数据的起始索引
  15. // push text token
  16. if (index > lastIndex) { //如果index大于lastIndex,表明中间还有一段文本,比如:{{item}}:{{index}},中间的:就是文本
  17. rawTokens.push(tokenValue = text.slice(lastIndex, index));
  18. tokens.push(JSON.stringify(tokenValue));
  19. }
  20. // tag token
  21. var exp = parseFilters(match[1].trim()); //调用parseFilters对match[1做解析] ;例如{{no | add(100) }},解析后的格式为:_f("add")(no,100)
  22. tokens.push(("_s(" + exp + ")"));
  23. rawTokens.push({ '@binding': exp });
  24. lastIndex = index + match[0].length; //设置下一次开始匹配的位置
  25. }
  26. if (lastIndex < text.length) {
  27. rawTokens.push(tokenValue = text.slice(lastIndex));
  28. tokens.push(JSON.stringify(tokenValue));
  29. }
  30. return {
  31. expression: tokens.join('+'), //拼凑成一个 表达式,例如:"_s(item)+":"+_s(index)"
  32. tokens: rawTokens //模板信息,例如[{@binding: "item"},":",{@binding: "index"}]
  33. }
  34. }
  1. parseFilters定义在6436行,就是解析每个字符,最后拼凑出一个_f的字符,例子中执行完后等于

最后执行render函数的时候会执行_f函数,也就是Vue内部的resolveFilter函数,如下:

  1. function resolveFilter (id) { //第3774行 过滤器对应的函数
  2. return resolveAsset(this.$options, 'filters', id, true) || identity //执行resolveAsset函数
  3. }

resolveAsset会获取对应资源(过滤器、组件、指令等),返回对应函数,如下:

  1. function resolveAsset ( //第1498行 options:Vue实例的$options对象 type:类型,比如:components、filters id:获取的ID
  2. options,
  3. type,
  4. id,
  5. warnMissing
  6. ) {
  7. /* istanbul ignore if */
  8. if (typeof id !== 'string') {
  9. return
  10. }
  11. var assets = options[type];
  12. // check local registration variations first
  13. if (hasOwn(assets, id)) { return assets[id] } //先从当前实例上找id
  14. var camelizedId = camelize(id);
  15. if (hasOwn(assets, camelizedId)) { return assets[camelizedId] } //将id转化为驼峰式后再找
  16. var PascalCaseId = capitalize(camelizedId);
  17. if (hasOwn(assets, PascalCaseId)) { return assets[PascalCaseId] } //如果还没找到则尝试将首字母大写查找
  18. // fallback to prototype chain
  19. var res = assets[id] || assets[camelizedId] || assets[PascalCaseId]; //最后通过原型来查找
  20. if ("development" !== 'production' && warnMissing && !res) {
  21. warn(
  22. 'Failed to resolve ' + type.slice(0, -1) + ': ' + id,
  23. options
  24. );
  25. }
  26. return res
  27. }

执行完后_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. Jsp和Servlet有什么区别?

    Servlet接口中有哪些方法? Servlet接口定义了5个方法,其中前三个方法与Servlet生命周期相关: void init(ServletConfig config) throws Serv ...

  2. es7之修饰器

    什么是修饰器 修饰器其实就是一个普通的函数,用来修饰类以及类的方法. 比如: @test class DecoratorTest { } function test(target) { target. ...

  3. 关于css中的定位

    关于前端的几种定位方式 近期自己感觉自己对于前端定位的知识还是不是太理解,所以自己就在这里做一个总结 1.元素的定位属性主要包括定位模式和边偏移两部分. 边偏移属性 描述 top       bott ...

  4. python中lambda

    lambda_expr ::= "lambda" [parameter_list]: expression python中lambda可以理解为一个匿名函数,它的要求是函数的运算部 ...

  5. Ubuntu下搭建Kubernetes集群(3)--k8s部署

    1. 关闭swap并关闭防火墙 首先,我们需要先关闭swap和防火墙,否则在安装Kubernetes时会导致不成功: # 临时关闭 swapoff -a # 编辑/etc/fstab,注释掉包含swa ...

  6. 201871010126 王亚涛 《面向对象程序设计(Java)》第十一周学习总结

    项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...

  7. python调用oracle存储过程

    oracle 存储过程 python调用oracle存储过程 -- 通过cx_Oracle连接 import cx_Oracle # 连接数据库 orcl_engine = 'scott/s123@x ...

  8. ubuntu安装dia

    linux下一款不错的流程图工具:dia.安装此工具:1.打开终端(快捷键:ctrl+alt+t).2.输入命令: $sudo apt-get install dia 3.提示“解压缩后会消耗掉 20 ...

  9. 在WEB显示实时视频流

    转载自:https://www.jianshu.com/p/7ef5490fbef7 安装摄像头 这里使用的是树莓派的官方摄像头,使用普通的 USB 摄像头也可以,但前提是你能够搞的定它的驱动. 大概 ...

  10. b站滑动验证码图片的获取-python

    本文仅是获取验证码图片,python+selenium实现 图片的处理,算出偏移位置网上都有现成的:而由于b站的更新,图片的获取则与之前完全不同,不能直接从html中拿到 过程比较曲折所以记录一下,可 ...