赞
踩
我们得知道有些特定的场景下 我们是需要去用到render函数去渲染vue模板的,那么何种场景呢?
在这里我可以找两个例子
当然我们也可一看一下element的源码 package.json中是否存在这两个依赖
以下是官网采用的两个依赖(其实两者是一样的 只不过由于版本问题)
当然这两个依赖也同样是我们在vue中书写jsx必不可少的两个依赖
回到render函数上面来,首先我们要了解的是什么是render函数,那么我们必须要知道的是什么?什么是虚拟dom,那么什么是虚拟dom呢?
其实这是一个屡见不鲜的面试题,用一句话来概括,用javascript的方式书写出来的dom节点就是虚拟dom,在vue中虚拟dom也就是我们所说的vnode等同于虚拟dom。
官网给出的我们使用render书写渲染函数,其实我们要理解的是什么?
因为vue是虚拟dom,所以在拿到template模板时也要转译成vnode的函数,而用render函数构建dom,vue就免去了转译的过程,我们在一些特定场景下去使用render书写起来性能方面能得到更进一步的提升。
看一下官网使用render函数书写虚拟dom
// template 模板写法 <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> <h3 v-else-if="level === 3"> <slot></slot> </h3> <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> <script> Vue.component('anchored-heading', { template: '#anchored-heading-template', props: { level: { type: Number, required: true } } }) </script> // createElement 虚拟dom写法 <script> Vue.component('anchored-heading', { render: function (createElement) { return createElement( 'h' + this.level, // 标签名称 this.$slots.default // 子节点数组 ) }, props: { level: { type: Number, required: true } } }) </script>
这样看起来的话好像反而要比template模板写法来的更简洁些,但是如果数据量一旦多起来呢?我们不免要考虑的一个问题就是不如标签写法来的直观。
当然有了解react的同学就会说了 那react也同样是render函数进行渲染 而且里面写的是jsx模板标签,那么我们可不可以在vue的render里面书写jsx模板标签呢?
此时其实也就引出了我们今天的主题,如何在vue的render中去书写jsx标签。
我们来到 git地址
同样官网会给出我们解答
npm install @vue/babel-preset-jsx @vue/babel-helper-vue-jsx-merge-props
babel.config.js
module.exports = {
presets: ['@vue/babel-preset-jsx'],
}
其实就是像这样(因为我这边使用的是vueCli已经携带了babel所以已经有了这个文件)
那么其实这个时候,我们的jsx就已经安装好了,此时我们就可以愉快的在render中书写jsx来进行编码了。
这个时候我们也同样将git上面的几个案例搬运过来
// 书写jsx模板(外层单个标签 不要retrun两个标签) render() { return <p>hello</p> } // 具有动态属性 render() { return <p>hello { this.message }</p> } // 单闭合标签 render() { return <input /> } // 引入组件 import MyComponent from './my-component' export default { render() { return <MyComponent>hello</MyComponent> }, } // 带有属性 render() { return <input type="email" /> } // 带有动态属性(这里面的this指向的便是当前的vue实例) render() { return <input type="email" placeholder={this.placeholderText} /> } // 带有多个动态属性 object解构式写法 render() { const inputAttrs = { type: 'email', placeholder: 'Enter your email' } return <input {...{ attrs: inputAttrs }} /> } // 指令v-model render() { return <input vModel={this.newTodoText} /> } // 指令v-model 修饰符trim 去空格 render() { return <input vModel_trim={this.newTodoText} /> } // 事件@click render() { return <input vOn:click={this.newTodoText} /> } // 事件@click 移除冒泡以及默认行为 render() { return <input vOn:click_stop_prevent={this.newTodoText} /> } // 指令v-html render() { return <p domPropsInnerHTML={html} /> }
当然我们同样是可以使用想onClick = {this.xxx}这种方式去进行书写的。
<!-- * @Author: your name * @Date: 2021-04-29 11:29:18 * @LastEditTime: 2021-04-29 15:23:33 * @LastEditors: Please set LastEditors * @Description: In User Settings Edit * @FilePath: /hx/packages/tbTag/main.vue --> <script> export default { name: "tbTag", render(h) { const data = { props: { ...this.$attrs, }, on: { ...this.$listeners, }, }; // 使用jsx 模板插槽的话 用default[0]即可 return ( <div {...data} style={this.color ? `background-color:${this.color}` : ""} class={`tb-tag tag ${this.tbType} ${this.tbSize} ${this.tbEffect}`}> {this.$slots.default[0]}{" "} <i vOn:click_stop={() => { this.$emit("close"); }} class="iconfont icon-close-bold bold" style="margin-left:2px;" ></i> </div> ); }, data() { return { tbSize: "tag_small", tbType: "", tbEffect: "", isCloseble: "", }; }, props: { // 颜色 type: { type: String, default: "primary", }, // 大小 size: { type: String, default: "small", }, // 三种样式一种是 light也就是默认 发浅色 dark:实心 plain:镂空 effect: { type: String, default: "light", }, // 自定义背景颜色 color: { type: String, default: "", }, // 关闭标签 closable: { type: Boolean, default: false, }, }, created() { this.Ptype(); this.Psize(); this.Peffect(); this.Pclosable(); }, methods: { // 页面加载判断当前标签是否存在关闭小图标 Pclosable() { const vm = this; if (vm.closable) { vm.isCloseble = true; } else { vm.isCloseble = false; } }, // 页面加载判断当前是何种样式 Peffect() { const vm = this; if (vm.effect == "light") { vm.tbEffect = "tag_effect_light"; } else if (vm.effect == "dark") { vm.tbEffect = "tag_effect_dark"; } else if (vm.effect == "plain") { vm.tbEffect = "tag_effect_plain"; } }, // 页面加载判断当前按钮大小 Psize() { const vm = this; if (vm.size == "mini") { vm.tbSize = "tag_mini"; } else if (vm.size == "small") { vm.tbSize = "tag_small"; } else if (vm.size == "medium") { vm.tbSize = "tag_medium"; } }, // 页面加载判断当前按钮类型 Ptype() { const vm = this; if (vm.type == "primary") { vm.tbType = "tag_primary"; } else if (vm.type == "success") { vm.tbType = "tag_success"; } else if (vm.type == "info") { vm.tbType = "tag_info"; } else if (vm.type == "warning") { vm.tbType = "tag_warning"; } else if (vm.type == "danger") { vm.tbType = "tag_danger"; } }, }, }; </script> <style scoped> .bold { cursor: pointer; } .tag { margin: 0 2px; border-radius: 4px; background: #ffffff; } /* .tag:focus, .tag:hover { color: #409eff; border-color: #c6e2ff; background-color: #ecf5ff; } */ /* size 样式 */ .tag_mini { height: 30px; font-size: 12px; display: inline-block; border: 1px solid #eeeeee; line-height: 30px; text-align: center; padding: 0 16px; /* cursor: pointer; */ } .tag_small { height: 35px; font-size: 14px; display: inline-block; border: 1px solid #eeeeee; line-height: 35px; text-align: center; padding: 0 20px; /* cursor: pointer; */ } .tag_medium { height: 40px; font-size: 16px; display: inline-block; border: 1px solid #eeeeee; line-height: 40px; text-align: center; padding: 0 24px; /* cursor: pointer; */ } /* effect 按钮样式 */ .tag_primary { color: #409eff; background-color: #ecf5ff; border-color: #d9ecff; } .tag_success { color: #67c23a; background-color: #f0f9eb; border-color: #e1f3d8; } .tag_info { color: #909399; background-color: #f4f4f5; border-color: #e9e9eb; } .tag_warning { color: #e6a23c; background-color: #fdf6ec; border-color: #faecd8; } .tag_danger { color: #f56c6c; background-color: #fef0f0; border-color: #fde2e2; } /* .tag_primary:focus, .tag_primary:hover { color: #409eff; background-color: #ecf5ff; border-color: #d9ecff; } .tag_success:focus, .tag_success:hover { color: #67c23a; background-color: #f0f9eb; border-color: #e1f3d8; } .tag_info:focus, .tag_info:hover { color: #909399; background-color: #f4f4f5; border-color: #e9e9eb; } .tag_warning:focus, .tag_warning:hover { color: #e6a23c; background-color: #fdf6ec; border-color: #faecd8; } .tag_danger:focus, .tag_danger:hover { color: #f56c6c; background-color: #fef0f0; border-color: #fde2e2; } */ .tag_primary.tag_effect_dark { color: #fff; background-color: #409eff; border-color: #409eff; } /* .tag_primary.tag_effect_dark:focus, .tag_primary.tag_effect_dark:hover { background: #66b1ff; border-color: #66b1ff; color: #fff; } */ .tag_success.tag_effect_dark { color: #fff; background-color: #67c23a; border-color: #67c23a; } /* .tag_success.tag_effect_dark:focus, .tag_success.tag_effect_dark:hover { background: #85ce61; border-color: #85ce61; color: #fff; } */ .tag_info.tag_effect_dark { color: #fff; background-color: #909399; border-color: #909399; } /* .tag_info.tag_effect_dark:focus, .tag_info.tag_effect_dark:hover { background: #a6a9ad; border-color: #a6a9ad; color: #fff; } */ .tag_warning.tag_effect_dark { color: #fff; background-color: #e6a23c; border-color: #e6a23c; } /* .tag_warning.tag_effect_dark:focus, .tag_warning.tag_effect_dark:hover { background: #ebb563; border-color: #ebb563; color: #fff; } */ .tag_danger.tag_effect_dark { color: #fff; background-color: #f56c6c; border-color: #f56c6c; } /* .tag_danger.tag_effect_dark:focus, .tag_danger.tag_effect_dark:hover { background: #f78989; border-color: #f78989; color: #fff; } */ .tag_primary.tag_effect_plain { color: #409eff; background: #ffffff; border-color: #b3d8ff; } /* .tag_primary.tag_effect_plain:focus, .tag_primary.tag_effect_plain:hover { background: #409eff; border-color: #409eff; color: #fff; } */ .tag_success.tag_effect_plain { color: #67c23a; background: #ffffff; border-color: #c2e7b0; } /* .tag_success.tag_effect_plain:focus, .tag_success.tag_effect_plain:hover { background: #67c23a; border-color: #67c23a; color: #fff; } */ .tag_info.tag_effect_plain { color: #909399; background: #ffffff; border-color: #d3d4d6; } /* .tag_info.tag_effect_plain:focus, .tag_info.tag_effect_plain:hover { background: #909399; border-color: #909399; color: #fff; } */ .tag_warning.tag_effect_plain { color: #e6a23c; background: #ffffff; border-color: #f5dab1; } /* .tag_warning.tag_effect_plain:focus, .tag_warning.tag_effect_plain:hover { background: #e6a23c; border-color: #e6a23c; color: #fff; } */ .tag_danger.tag_effect_plain { color: #f56c6c; background: #ffffff; border-color: #fbc4c4; } /* .tag_danger.tag_effect_plain:focus, .tag_danger.tag_effect_plain:hover { background: #f56c6c; border-color: #f56c6c; color: #fff; } */ </style>
引入调用即可。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。