zoukankan      html  css  js  c++  java
  • vue源码探索之过滤器解析过程

    模板编译

    <body>
        <div id="app">
            <span>{{ 1 | test(8) }}</span>
        </div>
    </body>
    <script src="./vue.js"></script>
    <script>
        new Vue({
      el: "#app",
      filters: {
        test (val, b) {
            console.log(this)
            debugger
          return val + b
        }
      }
    });
    

    模板在编译成render函数时候会经过下面一系列流程:
    image

    parseText

    主要在parseText函数解析文本

    function parseText (
        text,
        delimiters
      ) {
        debugger
        var tagRE = delimiters ? buildRegex(delimiters) : defaultTagRE;
        if (!tagRE.test(text)) {
          return
        }
        var tokens = [];
        var rawTokens = [];
        var lastIndex = tagRE.lastIndex = 0;
        var match, index, tokenValue;
        while ((match = tagRE.exec(text))) {
          index = match.index;
          // push text token
          if (index > lastIndex) {
            rawTokens.push(tokenValue = text.slice(lastIndex, index));
            tokens.push(JSON.stringify(tokenValue));
          }
          // tag token
          var exp = parseFilters(match[1].trim());
          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('+'), 
          tokens: rawTokens // 解析成 ["_s(_f("test")(1,8))"]
        }
      }
    

    _f函数就是resolveFilter函数

    function resolveFilter (id) {
        debugger
        return resolveAsset(this.$options, 'filters', id, true) || identity
      }
    
    function resolveAsset (
        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] }
        var camelizedId = camelize(id);
        if (hasOwn(assets, camelizedId)) { return assets[camelizedId] }
        var PascalCaseId = capitalize(camelizedId);
        if (hasOwn(assets, PascalCaseId)) { return assets[PascalCaseId] }
        // fallback to prototype chain
        var res = assets[id] || assets[camelizedId] || assets[PascalCaseId];
        if (warnMissing && !res) {
          warn(
            'Failed to resolve ' + type.slice(0, -1) + ': ' + id,
            options
          );
        }
        return res
      }
    

    resolveAsset就是取出我们在组件中定义在filters里面的test函数,由此可见当我们在定义filter函数中this是不指向当前组件实例的,指向window。如果要想拿到组件实例,可通过调用过滤器的时候,传入this

    最终生成的render函数

    image
    image

  • 相关阅读:
    都为你整理好了,5种Java 随机方式对比!你都知道吗?
    你不知道的,Java代码性能优化的 40+ 细节,赶快收藏!
    大厂技术总监,送给刚毕业和快要毕业的程序员——7点建议
    .NET Core 微服务学习与实践系列文章目录索引(2019版)
    ManagementEventWatcher throws ManagementException with call to Stop()
    postman工具的使用
    java实体类读取属性文件,并赋值
    使用idea创建springboot的maven项目
    手写Promise实现过程
    用Javascript制作随机星星效果图
  • 原文地址:https://www.cnblogs.com/raind/p/12706711.html
Copyright © 2011-2022 走看看