vue渲染函数使用哪个命令

vue渲染函数使用“render”命令。vue中是使用模板HTML语法组建页面的,使用render函数可以用js语言来构建DOM。因为vue是虚拟DOM,所以在拿到template模板时也要转译成VNode的函数,而用render()函数构建DOM,vue就免去了转译的过程。

vue渲染函数使用哪个命令

本教程操作环境: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<VNode> }   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 (根组件)  <template>   <div id="app">     <myRender></myRender>   </div> </template>  <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>  <style scoped> .child {   background: pink   font-size 24px   letter-spacing 2px } .more {   background: red } </style>
登录后复制

vue渲染函数使用哪个命令

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>  <style scoped> .wrapper    background: pink   letter-spacing 2px   .content      margin 0 auto      background: red     color #ffffff     font-size 24px  </style>
登录后复制

vue渲染函数使用哪个命令

2.3 使用 JAVAScript 代替模板功能

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

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

<ul v-if="items.length">   <li v-for="item in items">{{ item.name }}</li> </ul> <p v-else>No items found.</p>  <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>  <style scoped> .showContent   font-size 32px   letter-spacing 2px .content    margin 10px auto    color blue   font-size 24px </style>
登录后复制

vue渲染函数使用哪个命令

2.4 静态插槽

this.$slots的用法

1、父组件

<template>   <div id="app">     <myRender>       <template v-slot:header>         <div >           头部         </div>       </template>       <template #footer>         <div >           脚部         </div>       </template>     </myRender>   </div> </template>  <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>  <style scoped> .showContent   letter-spacing 2px   background-color red   .childHeader      color blue     font-size 24px </style>
登录后复制

vue渲染函数使用哪个命令

2.5 作用域插槽

this.$scopedSlots的用法

1、父组件

<template>   <div id="app">     <myRender :myLayout="layout">       <template slot-scope="childMsg">         <div >           {{childMsg.text}}         </div>       </template>     </myRender>   </div> </template>  <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>
登录后复制

vue渲染函数使用哪个命令

© 版权声明
THE END
喜欢就支持一下吧
点赞8 分享
评论 抢沙发