使用render封装一个select组件
父组件
value - {{ value }} ; value2 - {{ value2 }} <!-- disabled clearable --> <Select v-model="value" :option-data="optionData" placeholder="请选择" clearable /> <Select v-model="value2" :option-data="optionData" /> value: '', // 默认值为空字符串 value2: 'area1', optionData: [ { label: '区域1', value: 'area1' }, { label: '区域2', value: 'area2' } ],
Select.vue
<script> export default { name: 'Select', props: { value: { default: '', type: [String, Number] }, optionData: { default: () => { return [] }, type: Array } }, computed: { newValue: { get({ value }) { return value }, set(val) { this.$emit('input', val) } } }, methods: { onChangeHandle(val) { this.newValue = val } }, render(createElement) { return createElement( // 标签 'el-select', // 相关属性参数 { // html 相关的属性 placeholder id 等 attrs: { ...this.$attrs // ( { placeholder:请输入 } ) }, // props相关的 props: { value: this.newValue }, // 事件相关 on: { change: this.onChangeHandle } }, this.optionData && this.optionData.map(option => { return createElement( 'el-option', { props: { label: option.label, value: option.value } } ) }) ) } } </script>
效果
vue另类封装--render函数封装
在讲解render函数封装前,扩展一下组件自动全局注册的方法
先看看文件的结构
接下来就是注册代码(即lib下的index.js代码)
export default { install(Vue) { // 读取components文件夹下的文件 // const req = require.context('路径','是否读取子文件夹','正则匹配') // req是一个函数,该函数有三个属性分别是resolve、keys、id // 下面进行详细说明这三个属性 const req = require.context("@/components", false, /\.vue$/); //拿到读取文件的路径 //导入处理 req.keys().forEach((item) => { const com = req(item).default; // 全局注册组件 Vue.component(com.name, com); }); }, };
接下来我们在App文件直接使用components下的组件
<template> <div> <myA></myA> <myB></myB> </div> </template> <script> export default { name: "", data() { return { flag: false, }; }, computed: {}, methods: {}, }; </script> <style lang="less" scoped></style>
resolve :它是一个函数,接收一个参数(这个参数是匹配文件的相对路径),返回值是匹配文件相对于项目的路径 keys :它也是一个函数,返回的是匹配成功文件的相对路径(不包括文件名称) id :返回的是一个字符串,匹配的文件夹的路径()、匹配规则等
render函数封装
下面封装以面包屑为例
在a.vue下定义组件
<template> ? <span> ? ? <router-link v-if="to" :to="to"> ? ? ? <slot /> ? ? </router-link> ? ? <span v-else> ? ? ? <slot /> ? ? </span> ? </span> </template> <script> export default { ? name: "BreadcrumbItem", ? props: { ? ? to: { ? ? ? type: [Object, String], ? ? ? default: "", ? ? }, ? }, }; </script>
在b组件进行封装
<script> export default { ? name: "Breadcrumb", ? // 开启函数组件模式,它内部的东西不是响应式,并且没有生命周期 ? functional: true, ? render: (h, context) => { ? ? //创建数组接收虚拟节点 ? ? const vnodeArr = []; ? ? context.slots().default.forEach((item, index, arr) => { ? ? ? // 将处箭头外的虚拟dom存储起来 ? ? ? vnodeArr.push(item); ? ? ? // 判断是不是最后一项,是最后一项就不要加箭头 ? ? ? if (arr.length - 1 !== index) { ? ? ? ? // 加上箭头虚拟节点 ? ? ? ? vnodeArr.push(h("i", { class: "el-icon-arrow-right" })); ? ? ? } ? ? }); ? ? // render作用:它会return一个虚拟dom,return什么就渲染相应的实体Dom ? ? // h:创建虚拟DOM,有三个参数 ? ? 参数一:标签/组件 ? ?参数二:虚拟dom配置 ? 参数三:虚拟dom/子节点 ? ?// h(标签名/组件,{虚拟dom配置},子集:也是虚拟dom节点信息支持字符串与数组) ? ?// 进行渲染,h第三个参数可以为数组 ? ? return h("span", {}, vnodeArr); ? }, }; </script>
App组件运用
<template> ? <div> ? ? <Breadcrumb> ? ? ? <BreadcrumbItem to="/">首页</BreadcrumbItem> ? ? ? <BreadcrumbItem>活动列表</BreadcrumbItem> ? ? ? <BreadcrumbItem>活动管理</BreadcrumbItem> ? ? ? <BreadcrumbItem>活动详情</BreadcrumbItem> ? ? </Breadcrumb> ? </div> </template> <script> export default { ? name: "", ? data() { ? ? return { ? ? ? flag: false, ? ? }; ? }, ? computed: {}, ? methods: {}, }; </script> <style lang="less" scoped></style>
效果图如下
以上为个人经验,希望能给大家一个参考,也希望大家多多支持。
查看更多关于vue中使用render封装一个select组件的详细内容...
声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://www.haodehen.cn/did121230