Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

如何解析运算表达式 #3

Open
tianma630 opened this issue Apr 17, 2020 · 0 comments
Open

如何解析运算表达式 #3

tianma630 opened this issue Apr 17, 2020 · 0 comments
Labels
javascript javascript

Comments

@tianma630
Copy link
Owner

vue的template是支持表达式赋值的,比如

{{'hello ' + name}}{{age}}

解析表达式之前,我们先解析出{{}}的内容

let data = {
  abc: 2,
  efg: 3
}

let expr = '{{1 + abc / 2}} - {{efg * 2 }} + \'abc\'';

const exprReg1 = /{{([^{{}}]+)}}/g;

expr.replace(exprReg1, (r, $1) => {
    console.log($1);
})

我们可以看到打印出来的结果

1 + abc / 2
efg * 2 

然后再对上面解析出来的结果做表达式解析

const exprReg2 = /[\s|\+|-|\*|/]?([^\s|\+|-|\*|/]+)[\s|\+|-|\*|/]?/g;

let expr = '1 + abc / 2';

expr.replace(exprReg2, (r, $1) => {
  if (/^[a-zA-Z\$].*/.test($1)) { // 
    console.log($1);
  }
})

查看结果

abc

汇总成一个方法

function renderExpr(expr) {
  function renderParam(expr) {
    return expr.replace(exprReg2, (r, $1) => {
      if (/^[a-zA-Z\$].*/.test($1)) {
        return 'data.' + $1
      }
      return $1;
    })
  } 

  return expr.replace(exprReg1, (r, $1) => {
    return renderParam($1)
  })
}

但是还有个问题,我们每次调用renderExpr方法的时候都会新创建renderParam方法,我们可以用闭包缓存下

function createRenderExpr() {
  function renderParam(expr) {
    return expr.replace(exprReg2, (r, $1) => {
      if (/^[a-zA-Z\$].*/.test($1)) {
        return 'data.' + $1
      }
      return $1;
    })
  }

  return function renderExpr(expr) {
    return expr.replace(exprReg1, (r, $1) => {
      return renderParam($1)
    })
  }
}

const renderExpr = createRenderExpr();

let data = {
  abc: 2,
  efg: 3
}

let expr = '{{ 1 + abc / 2}} - {{efg * 2 }} + \'abc\'';

console.log(renderExpr(expr));

执行结果

1+data.abc/2 - data.efg*2 + 'abc'
@tianma630 tianma630 added the javascript javascript label Apr 17, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
javascript javascript
Projects
None yet
Development

No branches or pull requests

1 participant