vue、angular、react等框架源码中是如何计算{{}}中的表达式的?

Twinkle
  • 71

例如{{a+b}},已知a=10,b=20,此时如何输出30?

个人想到的方法是通过eval方法:

function fn(){
 const str = "{{a+b}}";
 const reg = /\{\{(.*)\}\}/;
 reg.test(str)
 const a = 10;
 const b = 20;
 return eval(RegExp.$1.trim())
}

但实际上在vue等源码中均未发现使用eval,请问他们是怎么实现的?
本人实力有限无法通读源码进行理解,希望各位大佬可以提供帮助(●'◡'●)

回复
阅读 182
2 个回答

结论:不管在vue还是react像 a + b这种expression都是都是应普通的表达式求值的

在vue中(带runtime编译的版本):

(1) 编译前
<div>
  <p>{{name}}</p>
</div>
(2) 编译后
function createFunction (code) {
  try {
    return new Function(code)
  } catch (err) {
    return noop
  }
}
const compiled = {
  render: `with(this){return _c('div',[_c('p',[_v(_s(name))])])}`
}
const res = {};
res.render = createFunction(compiled.render);

关键点就在这createFunction他用函数体的字符串用new Function(body)构造出了render函数,之后该函数中代码都是以普通javascript正常执行的,只不过用with绑定了一个上下文变量,会在this上自动寻找相关属性

在react中:

(1)编译前
const App = () => {
  const a = 1
  const b = 2
  return (
    <div>
      <p>ppp</p>
      {a + b}
    </div>
  );
};
(2)编译后
const App = function App() {
  var a = 1;
  var b = 2;
  return React.createElement(
    "div", 
    null, 
    React.createElement("p", null, "ppp"),
    a + b
  );
};

react中就更直白了,jsx就是javascript的语法糖,你自己手写React.createElement也是一样的效果不过比较麻烦

React JSX是通过babel转换器实现的,JSX源码 -> babel transform -> JS代码
Angular和vue都是有自己的一套compiler,

vue的可以看这部分
https://github.com/vuejs/vue/...

你知道吗?

宣传栏