Vue.js 源码分析(十一) 基础篇 过滤器 filters属性详解
程序员文章站
2022-04-11 07:50:59
用法 Vue.js 允许你自定义过滤器,可被用于一些常见的文本格式化。过滤器可以用在两个地方:双花括号插值和 v-bind 表达式 (后者从 2.1.0+ 开始支持)。过滤器应该被添加在 JavaScript 表达式的尾部,例如: 渲染结果为: 当我们在页面里输出某些数据,需要进行格式转换的时候可以 ......
用法
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>
渲染结果为:
当我们在页面里输出某些数据,需要进行格式转换的时候可以用这个过滤器
源码分析
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过滤器对应的函数了
上一篇: 《唐朝历史的教训》写了唐朝的什么时期?从另一面看唐朝历史!
下一篇: MUI下拉菜单样式
推荐阅读
-
Vue.js 源码分析(十四) 基础篇 组件 自定义事件详解
-
Vue.js 源码分析(十二) 基础篇 组件详解
-
Vue.js 源码分析(十一) 基础篇 过滤器 filters属性详解
-
Vue.js 源码分析(十三) 基础篇 组件 props属性详解
-
Vue 2.0 深入源码分析(七) 基础篇 侦听器 watch属性详解
-
Vue 2.0 深入源码分析(五) 基础篇 methods属性详解
-
Vue 2.0 深入源码分析(六) 基础篇 computed 属性详解
-
Vue 2.0 深入源码分析(三) 基础篇 模板渲染 el、emplate、render属性详解
-
Vue.js 源码分析(二十一) 指令篇 v-pre指令详解
-
Vue.js 源码分析(十四) 基础篇 组件 自定义事件详解