VUE引擎如何评估属性代码?

问题描述

在VUE中,可以在属性内编写完整的JS表达式。例如,下面的<div>

var app = new Vue({ el: '#app',data: { message: 'Hello Vue!',num: 3 } })
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <input v-model="message"/>
  <div v-html="'abc' + ' ' + message + ' ' + 2 * num"></div>
</div>

结果为abc Hellovue! 6


VUE如何计算此结果?某种沙盒eval

此计算在VUE's repo中的何处进行?

解决方法

整个模板被编译为JavaScript中的大型渲染函数。呈现该元素的vnode时,将内联评估属性和prop绑定。

此模板:

<div v-html="'abc' + ' ' + message + ' ' + 2 * num"></div>

被编译成类似这样的东西:

vnode = _c('div',{
  domProps: {
    "innerHTML": _s('abc' + ' ' + message + ' ' + 2 * num)
  }
})

整个渲染函数都包装在with(this) { ... }语句中,因此可以像message而不是this.message那样编写组件实例的属性。

没有eval()发生,它像您手动编写了render函数一样直接执行。模板编译器代码可以在编译时使用new Function() 来检查语法是否有效,但是在应用程序执行期间不会执行此类沙箱操作。

This online Vue 2 template compiler显示了如何将模板编译为渲染函数。

Vue 3对模板的编译方式有所不同,并且进行了优化。使用Vue Template Explorer进行试验。