世界要闻:vue渲染函数使用哪个命令

时间:2022-12-20 21:06:24       来源:PHP中文网

本教程操作环境:windows7系统、vue3版,DELL G3电脑。

在绝大多数情况下,Vue 推荐使用模板语法来创建应用。然而在某些使用场景下,我们真的需要用到 JavaScript 完全的编程能力。这时渲染函数--render就派上用场了。

1. render函数的介绍

简单的说,在vue中我们使用模板HTML语法组建页面的,使用render函数我们可以用js语言来构建DOM。因为vue是虚拟DOM,所以在拿到template模板时也要转译成VNode的函数,而用render函数构建DOM,vue就免去了转译的过程。


(资料图片仅供参考)

当使用render函数描述虚拟DOM时,vue提供一个函数,这个函数是就构建虚拟DOM所需要的工具。官网上给它起了个名字叫createElement。还有约定的简写叫h。

1.1 虚拟 DOM

Vue 通过建立一个虚拟 DOM 来追踪自己要如何改变真实 DOM。请仔细看这行代码:

return createElement("h1", this.blogTitle)
登录后复制

createElement 到底会返回什么呢?其实不是一个实际的 DOM 元素。它更准确的名字可能是createNodeDescription,因为它所包含的信息会告诉 Vue 页面上需要渲染什么样的节点,包括及其子节点的描述信息。我们把这样的节点描述为“虚拟节点 (virtual node)”,也常简写它为“VNode”。“虚拟 DOM”是我们对由 Vue 组件树建立起来的整个 VNode 树的称呼。

1.2 createElement 接受的参数
// @returns {VNode}createElement(  // {String | Object | Function}  // 一个 HTML 标签名、组件选项对象,或者  // resolve 了上述任何一种的一个 async 函数。必填项。  "div",  // {Object}  // 一个与模板中属性对应的数据对象。可选。  {    // (详情见1.3)  },  // {String | Array}  // 子级虚拟节点 (VNodes),由 `createElement()` 构建而成,  // 也可以使用字符串来生成“文本虚拟节点”。可选。  [    "先写一些文字",    createElement("h1", "一则头条"),    createElement(MyComponent, {      props: {        someProp: "foobar"      }    })  ])
登录后复制
1.3 render函数的使用
render:(h) => {  return h("div",{    // 给div绑定class属性    class: {      child: true,      more: false    },  // 给div绑定样式  style:{    width:"200px",      height:"200px",  },   // 给div绑定点击事件      on: {      click: () => {        console.log("点击事件")      }    },  })}
登录后复制
1.4 深入render函数数据对象

正如 v-bind:class 和 v-bind:style 在模板语法中会被特别对待一样,它们在 VNode 数据对象中也有对应的顶层字段。该对象也允许你绑定普通的 HTML attribute,也允许绑定如 innerHTML 这样的 DOM 属性 (这会覆盖 v-html 指令)

{  // 与 `v-bind:class` 的 API 相同,  // 接受一个字符串、对象或字符串和对象组成的数组  "class": {    foo: true,    bar: false  },  // 与 `v-bind:style` 的 API 相同,  // 接受一个字符串、对象,或对象组成的数组  style: {    color: "red",    fontSize: "14px"  },  // 普通的 HTML attribute  attrs: {    id: "foo"  },  // 组件 prop  props: {    myProp: "bar"  },  // DOM 属性  domProps: {    innerHTML: "baz"  },  // 事件监听器在 `on` 属性内,  // 但不再支持如 `v-on:keyup.enter` 这样的修饰器。  // 需要在处理函数中手动检查 keyCode。  on: {    click: this.clickHandler  },  // 仅用于组件,用于监听原生事件,而不是组件内部使用  // `vm.$emit` 触发的事件。  nativeOn: {    click: this.nativeClickHandler  },  // 自定义指令。注意,你无法对 `binding` 中的 `oldValue`  // 赋值,因为 Vue 已经自动为你进行了同步。  directives: [    {      name: "my-custom-directive",      value: "2",      expression: "1 + 1",      arg: "foo",      modifiers: {        bar: true      }    }  ],  // 作用域插槽的格式为  // { name: props => VNode | Array }  scopedSlots: {    default: props => createElement("span", props.text)  },  // 如果组件是其它组件的子组件,需为插槽指定名称  slot: "name-of-slot",  // 其它特殊顶层属性  key: "myKey",  ref: "myRef",  // 如果你在渲染函数中给多个元素都应用了相同的 ref 名,  // 那么 `$refs.myRef` 会变成一个数组。  refInFor: true}
登录后复制
1.5 约束

组件树中的所有 VNode 必须是唯一的。

这意味着,下面的渲染函数是不合法的:

render: function (createElement) {  var myParagraphVNode = createElement("p", "hi")  return createElement("div", [    // 错误 - 重复的 VNode    myParagraphVNode, myParagraphVNode  ])}
登录后复制

如果你真的需要重复很多次的元素/组件,你可以使用工厂函数来实现。

例如,下面这渲染函数用完全合法的方式渲染了 20 个相同的段落:

render: function (createElement) {  return createElement("div",    Array.apply(null, { length: 20 }).map(function () {      return createElement("p", "hi")    })  )}
登录后复制

2. render函数的应用

2.1 渲染一个简单的元素
// app.vue (根组件)<script>import myRender from "./components/myRender"export default {  components:{    myRender  }}</script>
登录后复制
// myRender.vue<script>export default {  render:(h) => {    return h("div",{      class: {        child: true,        more: false      },      attrs: {        id: "foo",        name: "child"      },    style: {      width:"100%",        height:"200px",    },      domProps: {        innerHTML: "我是render渲染的子组件"      }    })  }}</script>
登录后复制
2.2 添加子标签
<script>export default {  render:(h) => {    return h("div",      {        class: "wrapper",        attrs: {          id: "wrapper",        },      style: {        width:"100%",          height:"250px"      },      },[        h("h2","标题"),        h("div",{          class: "content",          attrs: {            id: "content",          },          style:{            width:"800px",            height:"100px"          },          domProps:{            innerHTML:"我是内容"          }        })      ]    )  }}</script>
登录后复制
2.3 使用 JavaScript 代替模板功能

只要在原生的 JavaScript 中可以轻松完成的操作,Vue 的渲染函数就不会提供专有的替代方法。

1、v-if 和 v-for 模板语法中:

  • {{ item.name }}

No items found.

<script>export default { data(){ return{ items:[1,2,3] } }}</script>
登录后复制

render函数实现:

<script>export default {  render: function (createElement) {    if (this.items.length) {      return createElement("ul", this.items.map(function (item) {        return createElement("li", item.name)      }))    } else {      return createElement("p", "No items found.")    }  },  data(){    return{      items:[1,2,3]    }  }}</script>
登录后复制

2、v-model

<script>export default {  render:function(createElement) {    var self = this    return createElement("div",[        createElement("div",{class: "showContent"},self.inputValue),        createElement("input",{          class: "content",          domProps:{            value:self.inputValue          },          on:{            input:function(event){              self.inputValue = event.target.value            }          }        })      ]    )  },  data(){    return{      inputValue:""    }  },  watch:{    inputValue:function(){      console.log(this.inputValue)    }  },}</script>
登录后复制
2.4 静态插槽

this.$slots的用法

1、父组件

<script>import myRender from "./components/myRender"export default {  components:{    myRender  }}</script>
登录后复制

2、子组件

<script>export default {  render:function(createElement) {    let childHeader = this.$slots.header    let childFooter = this.$slots.footer    return createElement(      "div",      {        class: "showContent",        style:{          width:"100%"        }      },      [        createElement("div",{class:"childHeader"},childHeader),        createElement("div",childFooter),      ]    )  },}</script>
登录后复制
2.5 作用域插槽

this.$scopedSlots的用法

1、父组件

<script>import myRender from "./components/myRender"export default {   data(){    return{      layout:{        header:"头部",        footer:"脚部"      }    }  },  components:{    myRender  }}</script>
登录后复制

2、子组件

<script>export default {  render:function(createElement) {    let self = this    return createElement(      "div",      {        style:{          width:"100%"        },      },[        self.$scopedSlots.default({          text: this.myLayout.header        })      ]    )  },  props:{    myLayout:Object  }}</script>
登录后复制

【相关推荐:vuejs视频教程、web前端开发】

以上就是vue渲染函数使用哪个命令的详细内容,更多请关注php中文网其它相关文章!

关键词: 数据对象 相关文章