3.3.1 基础
优质
小牛编辑
130浏览
2023-12-01
Vue 推荐在绝大多数情况下使用 template 来创建你的 HTML。然而在一些场景中,你真的需要 JavaScript 的完全编程的能力,这就是render 函数,它比 template 更接近编译器。
<h1> <a name="hello-world" href="#hello-world"> Hello world! </a> </h1>
在 HTML 层,我们决定这样定义组件接口:
<anchored-heading :level="1">Hello world!</anchored-heading>
当我们开始写一个通过level
prop 动态生成 heading 标签的组件,你可能很快想到这样实现:
<script type="text/x-template" id="anchored-heading-template"> <h1 v-if="level === 1"> <slot></slot> </h1> <h2 v-else-if="level === 2"> <slot></slot> </h2> <h4 v-else-if="level === 3"> <slot></slot> </h4> <h4 v-else-if="level === 4"> <slot></slot> </h4> <h5 v-else-if="level === 5"> <slot></slot> </h5> <h6 v-else-if="level === 6"> <slot></slot> </h6> </script>
Vue.component('anchored-heading', { template: '#anchored-heading-template', props: { level: { type: Number, required: true } } })
在这种场景中使用 template 并不是最好的选择:首先代码冗长,为了在不同级别的标题中插入锚点元素,我们需要重复地使用<slot></slot>
。
虽然模板在大多数组件中都非常好用,但是在这里它就不是很简洁的了。那么,我们来尝试使用render
函数重写上面的例子:
Vue.component('anchored-heading', { render: function (createElement) { return createElement( 'h' + this.level, // tag name 标签名称 this.$slots.default // 子组件中的阵列 ) }, props: { level: { type: Number, required: true } } })
简单清晰很多!简单来说,这样代码精简很多,但是需要非常熟悉 Vue 的实例属性。在这个例子中,你需要知道当你不使用slot
属性向组件中传递内容时,比如anchored-heading
中的Hello world!
,这些子元素被存储在组件实例中的$slots.default
中。如果你还不了解,在深入 render 函数之前推荐阅读实例属性 API。