1.1.2 表达式语法转换

73 阅读1分钟

表达式语法转换

背景

微信小程序支持未声明的变量,只不过未声明的变量取值为undefined

vue2 不支持使用未声明的变量,如果是未声明,则会整段表达式报错。

示例:

<view wx:if="{{!userInfo.name}}">{{userInfo.name}}</view>

解决方案

在寻找解决方案的过程中,我做了不少尝试,一开始将遇到有报错的就返回undefined 就能解决大部分的问题

但是不能解决上面示例的问题

方案一 遇到报错就整个表达式返回undefined

在vue底层源码里面 修改执行逻辑,遇到报错不抛出错误,返回undefined

方案二 将所有的变量取值改为函数取值-参考柯里化

编译前后对比的效果:

<view wx:if="{{!userInfo.name}}">{{userInfo.name}}</view>
<view wx:if="{{!_sz(renderData, 'userInfo', 'name')}}">{{_sz(renderData, 'userInfo', 'name')}}</view>
如何实现

使用语法分析,分析表达式,然后将表达式里面的变量都找出来,然后修改为函数调用。 表达式转换文件路径

需要处理的表达式主要是2种类型

  1. Identifer 标识符类型 标识符,就是我们写 JS 时自定义的名称,如变量名,函数名,属性名,都归为标识符。
isShow
data = {
    isShow
}

相应的类型描述是这样的:

interface Identifier {
    type: 'Identifier';
    name: string;
}
  1. MemberExpression 属性成员表达式 属性成员表达式,简单来讲是带有连接符的,比如一下代码
item.isShow
item["isShow"]
item[1]
item[propKey] // 这里需要注意 propKey 是一个 Identifer 需要递归转换

表达式转换示意图

参考文章

高级前端基础-JavaScript抽象语法树AST