经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » HTML/CSS » HTML5 » 查看文章
Vue.js 源码分析(十一) 过滤器 filters属性详解
来源:cnblogs  作者:大沙漠  时间:2019/6/25 11:11:44  对本文有异议

  用法


 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>

渲染结果为:

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

 

源码分析


 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过滤器对应的函数了

原文链接:http://www.cnblogs.com/greatdesert/p/11081321.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号