0.2.3 • Published 2 years ago

wbfc-vs-tpl-editor v0.2.3

Weekly downloads
20
License
-
Repository
-
Last release
2 years ago

wbfc-vs-tpl-editor

wbfc-vs-tpl-editor是一个基于 Element UI 制作的可视化模板编辑器框架。(如果你不喜欢EL,当然也可以全部自定义UI组件) 它是由Wisea base framework cloud - visual templete editor的缩写而命名的。

它可以使用模板数据来自动生成并绑定el的表单。将数据模型驱动显示这种所见即得的功能更好的发挥。

想象一下,你可以提供一套制作好的模板给别人,他们不需要自己制作样式,制作配色,他们只要根据模板中的功能填写数据就可以得到想要的结果!这更接近真实的项目使用方案,毕竟全部动态的代码是很危险的,很容易造成XSS攻击。如果我们有现成的模板,只把数据做动态处理,就安全的多了。于是便有了本项目。

下载安装

npm install wbfc-vs-tpl-editor
import WbfcVsTplEditor from 'wbfc-vs-tpl-editor';
Vue.use(WbfcVsTplEditor);

使用流程

  1. 制作你自己需要的vue组件
  2. 为该组件制作一个对应的模板
  3. 保存模板所需要的数据
  4. 完成

以上流程可以查看 Demo 或者 下载源码后 npm run dev 打开对应网页也可见到默认的demo页面

如何制作一个编辑器

在你的模板Vue文件中引入templete-binder和templete-editor(binder负责数据模型绑定,editor负责页面渲染), 模板Vue需要mixins(混入)binder。在页面中使用TempleteEditor, 绑定v-model="tplModel" :tpl-form-elems="tplFormElems", 设置tplFormElems对应的表单元素数据,然后再将editor的插槽showComponent部分写入你的插件并绑定v-model="componentModel"即可。例:

MyComponent.vue

<template>
<div>InputTextVal:{{value.textVal}}</div>
</template>
<script type="text/javascript">
export default {
  name: 'MyComponent',
  props: {
    value: {
      type: Object,
      default () { return {}; }
    }
  }
}
</script>

MyEditor.vue

<template>
  <div>
    <TempleteEditor :tpl-form-elems="tplFormElems" v-model="tplModel" ref="tpl">
      <template v-slot:showComponent>
        <MyComponent v-model="componentModel"/>
      </template>
    </TempleteEditor>
  </div>
</template>
<script type="text/javascript">
import MyComponent from './MyComponent'
import TempleteBinder from 'wbfc-vs-tpl-editor/components/templete-binder'
import TempleteEditor from 'wbfc-vs-tpl-editor/components/templete-editor'

export default {
  name: 'MyEditor',
  mixins: [TempleteBinder],
  components: {
    TempleteEditor,
    MyComponent
  },
  data() {
    return {
      tplFormElems: [{
        type: 'input',
        name: 'textVal',
        label: 'TestTplInput',
      }]
    };
  }
}
</script>

TempleteBinder

Attributes

参数说明类型必填可选值默认值
tplModel模板数据模型Objecttrue-{}
tplFormElems模板元素列表Arrayfalse-[]
componentModel组件数据模型Objecttrue-{}

TempleteEditor

用于渲染模板页面

Attributes

参数说明类型必填可选值默认值
isEdit是否为编辑模式。true=显示组件(slot:showComponent)和表单编辑器。false=仅显示组件模板(slot:showTemplete)booleantrue/falsetrue
value编辑器的值 可以直接设置,也可以使用v-model绑定Object-{}
tplForm编辑器的表单属性,具体参数说明请参考 Element UI - 表单Object-{labelWidth : '30%', bottomBtns:[]}
tplFormElems编辑器的表单元素Array-[]

TplFormElems

参数说明类型必填可选值默认值
group分组 设置了group的会在编辑器侧显示分割线TplFormElems-Group--
elems组元素(分组时有效,仅支持一层分组)TplFormElems--
type元素类型 默认为输入框 custom为自定义元素,可以通过该元素的插槽 v-slot:"form_item_" + name 进行自定义替换Stringinput/hidden/radio/radio-group/checkbox/checkbox-group/select/cascader/switch/slider/time-select/time-picker/date-picker/date-time-picker/rate/color-picker/transfer/custom 父元素.type = radio-group / checkbox-group时,子元素.type = radio-button/checkbox-button 有效input
name元素名称 默认会按照name映射绑定组件模型 例:{name:'textVal'} 将会绑定 TempleteBinder.componentModel.textValString--
bind绑定名称 若带有'.'则会绝对匹配,不带'.'则会相对匹配 例:{name:'textVal', bind: 'act'} 将会绑定 TempleteBinder.componentModel.act.textVal {name:'textVal', bind: 'act.text'} 将会绑定 TempleteBinder.componentModel.act.textString--
label元素显示标签String--
visible元素是否显示 String会按照表达式处理 可以指定为模型的其他属性 例: tplFormElems = {type: 'switch', name:'textFlag', label:'开关', defVal: true}, {name:'textVal', label:'文字显示联动开关属性', visible: 'textFlag'}String:expression/boolean/function-true
defVal元素默认值 如果模型(value)不指定默认值,也可以通过tplFormElems的这个属性设置Object--
formItemAttrs表单项属性 EL组件具体参数说明请参考 Element UIObject--
notMapping编辑器表单组件模型值不需要映射到显示组件component中booleantrue/falsefalse
attrs元素属性 EL组件具体参数说明请参考 Element UIObject--
events元素事件Object请参考HTML的基础事件和自定义事件-
items子元素列表 type=radio/radio-group/checkbox-group/select 时有效TplFormElems--
text子元素显示标签 type=radio/radio-group/checkbox/checkbox-group/ 时有效String--
helps元素帮助文档String--
helpsType元素帮助文档类型 如果填写为md 则会使用mavon-editor作为显示器 此时helps可以写为markdown格式文档Stringmd-
autoBind自动绑定模型booleantrue/falsetrue
bindType绑定类型 当autoBind=false时必填String'static'/'dynamic'-
bindFunc自定义绑定函数 当autoBind=false时,bindType != 'static'/'dynamic'时必填function--
invisibleNoBindType不显示时的绑定模式 all-既删除表单模型也删除组件模型 holdTplModel-只删除组件模型Stringall/holdTplModel,all
slots插槽列表 默认插槽["xxx"\] 具名插槽[{name:'xid', ....}]Array--

TplFormElems-Group

参数说明类型必填可选值默认值
name分组的标识String-null
label分组的文字显示,会在分割线正中间显示的提示文字String-null
visible分组是否显示(如果该项为false,其组内子项也不会显示)booleantrue/falsetrue
invisibleNoBindType不显示时的绑定模式 all-既删除表单模型也删除组件模型 holdTplModel-只删除组件模型Stringall/holdTplModel,all

TplFormElems-slots

参数说明类型必填可选值默认值
name具名插槽使用的名称,如果不填就是默认的default插槽String--
component组件 {template: ''} 模板字符串对应<template>节点 详情参考Vue.jsnew Vue()--
params组件的数据对象 详情参考Vue.js - createElement-参数Object--
VNodes组件的子节点 一般为默认的插槽(this.$slots.default) 详情参考Vue.js - 完整示例Object--

TempleteEditor - Methods

函数名说明参数示例
addTplFormElems添加一个tplFormElems的节点item(一个节点), model(默认模型值)vm.addTplFormElems({type: 'input', name: 'test', label:'测试输入框', bind: 'wbfc.test'}, '测试字符串');
deleteElem删除一个tplFormElems的节点elem(节点), groupElem(elem的父节点,没有填为null))vm.deleteElem({type: 'input', name: 'test', label:'测试输入框', bind: 'wbfc.test'})
removeWatch移除模型绑定elem(节点非group), holeModelVal(是否保留表单模型值)vm.removeWatch({type: 'input', name: 'test', label:'测试输入框', bind: 'wbfc.test'})

TempleteEditor - Slotes

插槽名说明参数
showTemplete非编辑模式下显示的组件-
showComponent编辑模式下显示的组件-
'form_group_' + name分组模块的头分割线data:tplFormElemsindex
'form_group_' + name + '_bottom'分组模块的尾分割线 默认不显示data:tplFormElemsindex
'bottomBtns_' + index编辑器最底部按钮data:bottomBtns
'form_item_' + name元素组件data:TplFormElemsindex
'form_item_label_' + name元素标签data:TplFormElemsindex

自定义组件

在一些更为复杂的页面中,可能el提供的这些UI组件无法满足你的需求,这样的情况可以使用自定义组件。自定义组件分为:全局组件、编辑器全局组件、局部组件和局部完全自定义组件。

全局组件

直接可以使用Vue原生的全局组件设置Vue.component('component-a', { /* ... */ }) 详细文档请参考 Vue 组件注册

编辑器全局组件

这种组件是在TempleteEditor标签包裹的范围内均可以使用的全局组件。你可以在加载wbfc-vs-tpl-editor前,用use函数注册这些组件。组件要包裹在components下 例: {components: {你import的组件名}}

import WbfcVsTplEditor from 'wbfc-vs-tpl-editor';
import testComp from '../components/testComp';
Vue.use(WbfcVsTplEditor, {
  components: {
    testComp
  }
});

局部组件

通常的场景下,局部组件的使用场景最多。这种组件只在当前页面和当前页面的TempleteEditor包裹的TplFormElems元素下生效。你需要在自己的页面中使用import,然后再在覆盖beforeCreate函数中使用Vue.$formItemComponentsManager.addComponent({组件名});

<template>
  <div>
    <TempleteEditor :tpl-form-elems="tplFormElems" v-model="tplModel" ref="tpl" :childComp="childComp">
      <template v-slot:showComponent>
        <MyComponent v-model="componentModel" />
      </template>
    </TempleteEditor>
  </div>
</template>
<script type="text/javascript">
import Vue from 'vue'
import MyComponent from './MyComponent'
import TempleteBinder from '../src/components/templete-binder'
import TempleteEditor from '../src/components/templete-editor'
import test2 from './test2'

export default {
  name: 'MyEditor',
  mixins: [TempleteBinder],
  components: {
    TempleteEditor,
    MyComponent,
  },
  beforeCreate(){
    Vue.$formItemComponentsManager.addComponent({test2});
  }
  ...
}

局部完全自定义组件

TplFormElems[index].type = 'custom'时,编辑器表单的元素渲染会变成完全自定义的模式,在这样的模式下,必须使用对应的插槽'form_item_' + name才能正确的渲染出结果。_这种组件通常会在只有一个功能使用到了,没有必要制作一个组件的情况下使用__。

<template>
  <div>
    <TempleteEditor :tpl-form-elems="tplFormElems" v-model="tplModel" ref="tpl" :childComp="childComp">
      <template v-slot:showComponent>
        <MyComponent v-model="componentModel" />
      </template>
      <template v-slot:form_item_bgColor="sc">
        <div class="color-schemes-line">
          <div class="color-schemes-line-text">
            <span>{{sc.data.attrs.text}}</span>
          </div>
          <el-color-picker v-model="tplModel.bgColor"></el-color-picker>
        </div>
      </template>
    </TempleteEditor>
  </div>
</template>
<script type="text/javascript">
import Vue from 'vue'
import MyComponent from './MyComponent'
import TempleteBinder from '../src/components/templete-binder'
import TempleteEditor from '../src/components/templete-editor'

export default {
  name: 'MyEditor',
  mixins: [TempleteBinder],
  components: {
    TempleteEditor,
    MyComponent,
  },
  data() {
    return {
      tplFormElems: [{
        type: 'custom',
        name: 'bgColor',
        label: '局部',
        attrs:{
          text: '完全自定义组件'
        }
      }]
    };
  },
  ...
}

特有组件库

link-editor 链接编辑器

它是一个弹出层式的表单交互式组件,必须在弹出的对话框点击确定按钮时手动处理value。当编辑器元素中包含有链接,可以直接使用链接编辑器组件。它必须要实现一个submitDialog函数,用来处理对话框关闭时的操作,一般这个函数可以做编辑器中组件的回显,如果需要默认值,只要实现events的open事件,调用setValue函数即可。

export default {
  data() {
    return {
      tplFormElems: [{
        type: 'link-editor',
        name: 'linkVal',
        label: '链接',
        defVal: {href: 'https://github.com/xudl33/wbfc-vs-tpl-editor', label: '链接文字', target: '_blank'},
        attrs: {
          submitDialog: (val) => {
            // 回显
            this.$set(this.tplModel, 'linkVal', val);
          }
        },
        events:{
          open: (e, linkEditor) => {
            // 默认赋值
            linkEditor.setValue(this.tplModel.linkVal);
          }
        }
      }]
    };
  },
  ...
}

Attributes

参数说明类型必填可选值默认值
dialogProps编辑对话框属性 具体参数请参考 Element UI DialogObjectfalse-{width: '40%'}
editorView编辑器链接属性 它会映射为编辑器的表单元素显示出来 具体参数请参考 Element UI LinkObjectfalse-{type: 'primary', underline: false, href: '#'}
viewLabel编辑器链接文字Stringfalse-'编辑'
dialogTitle编辑对话框标题 (独立属性,即使设置了dialogProps.title也无效)Stringfalse-'-编辑链接-'
propMapping编辑器表单映射 默认的表单属性为{label: '显示文字', href: '超链接', target: '跳转类型'} 如果你的模型并不是这种结构,可以设置该项进行映射转换Objectfalse-{label: 'label',href: 'href',target: 'target'}
defVal表单默认值 每次弹出对话框时的初始值,它只是一个Object,不会直接绑定到编辑器模型中,如果需要从编辑器模型中传递默认值,必须要实现open事件,再调用setValue函数手动赋值Objectfalse-{}
formProps编辑器表单属性 Element UI - 表单Objectfalse-{rules: {label: { required: true, message: '请输入显示文字', trigger: 'blur' },href: { required: true, message: '请输入链接', trigger: 'blur' },target: { required: true, message: '请选择跳转类型', trigger: 'blur' }}}
submitDialog对话框点击确定按钮的回调函数 必须通过改函数手动处理编辑器表单值的对应关系Functiontrue-() => {}

Slotes

插槽名说明参数
view-label显示文字linkEditor:this
footer底部按钮linkEditor:this

propMapping 编辑器表单映射

export default {
  data() {
    return {
      tplFormElems: [{
        type: 'link-editor',
        name: 'linkVal',
        label: '链接',
        defVal: {link: 'https://github.com/xudl33/wbfc-vs-tpl-editor', text: '链接文字', type: '_blank'},
        attrs: {
          propMapping: { // 不是默认结构的数据,需要对表单进行映射转换
             href: 'link',
             label: 'text',
             target: 'type'
          }
        },
        events:{
          open: (e, linkEditor) => {
            // 默认赋值
            linkEditor.setValue(this.tplModel.linkVal);
          }
        }
      }]
    };
  },
  ...

list-sort-editor 列表排序编辑器

它是一个可以直接对列表进行排序操作的编辑器。默认四个按钮,【向上移动】【向下移动】【移动到最前】【移动到最后】。它不是默认的编辑器全局组件,使用前需要import到你的vue中。

<template>
  <div>
          <el-table ref="multipleTable" :data="tplModel.categoryList" style="width:100%">
            <el-table-column type="index">
            </el-table-column>
            <el-table-column prop="text" label="分类名">
            </el-table-column>
            <el-table-column label="排序">
              <template slot-scope="scope">
                <ListSortEditor v-model="tplModel.categoryList" :index="scope.$index"/>
              </template>
            </el-table-column>
          </el-table>
  </div>
</template>
<script type="text/javascript">
import ListSortEditor from 'wbfc-vs-tpl-editor/components/list-sort-editor'
export default {
  components: {
    ListSortEditor,
  },
  data:{
    return {
    tplModel: {
        categoryList: [{
            text: '分类1',
            href: '/'
          },
          {
            text: '分类2',
            href: '/'
          },
          {
            text: '分类3',
            href: '/'
          },
          {
            text: '分类4',
            href: '/'
          },
          {
            text: '分类5',
            href: '/'
          }
        ]
    }
   };
  }
  ...
}
</script>

Attributes

参数说明类型必填可选值默认值
value需要排序的列表Arraytrue--
index当前数据的索引值,上下排序是会根据索引值计算,因此必须为大于等于0的正数,一般会传入列表的index属性,详情可以参考示例。inttrue+[0-Number.MAX_SAFE_INTEGER]-
btns排序按钮Objectfalse-{up: {type: 'text',icon: 'el-icon-arrow-up',title: '向上移动',enabled: true},down: {type: 'text',title: '向下移动',icon: "el-icon-arrow-down",enabled: true},top: {type: 'text',title: '移动到最前',icon: "el-icon-top",enabled: true},bottom: {type: 'text',title: '移动到最后',icon: "el-icon-bottom",enabled: true}}
loop是否循环排序 默认列表的第一个点击【向上移动】不会有效果,列表的最后一个点击【向下移动】也不会有效果。 如果开启该项,列表的第一个点击【向上移动】会变成最后一个,列表的最后一个点击【向下移动】会变成第一个Booleanfalsetrue/falsefalse

btns

参数说明类型必填可选值默认值
type按钮类型 具体参数请参考 Element UI ButtonStringtrue-text
icon按钮图标 具体参数请参考 Element UI IconStringtrue--
title按钮鼠标悬停提示Stringfalse--
enabled按钮是否可用 如果为false则该按钮不可见Booleantruetrue/falsetrue

Slotes

插槽名说明参数
up向上移动index:index
down向下移动index:index
top移动到最前index:index
bottom移动到最后index:index

事件

参数说明
change四个按钮,【向上移动】【向下移动】【移动到最前】【移动到最后】中的任何一个按钮执行操作后,均会触发change事件。

不显示按钮

设置btns属性可以控制按钮是否可见。例: 不显示【移动到最前】【移动到最后】两个按钮。

<template>
  <div>
          <el-table ref="multipleTable" :data="tplModel.categoryList" style="width:100%">
            <el-table-column type="index">
            </el-table-column>
            <el-table-column prop="text" label="分类名">
            </el-table-column>
            <el-table-column label="排序">
              <template slot-scope="scope">
                <ListSortEditor v-model="tplModel.categoryList" :index="scope.$index" :btns="{top:{enabled:false}, bottom:{enabled:false}}"/>
              </template>
            </el-table-column>
          </el-table>
  </div>
</template>
<script type="text/javascript">
import ListSortEditor from 'wbfc-vs-tpl-editor/components/list-sort-editor'
export default {
  components: {
    ListSortEditor,
  }
  ...
}
</script>

自定义按钮

在一些特殊场合下,默认的样式并不能满足需求,这时可以自定义操作按钮。例:自定义【向上移动】和【向下移动】同时不显示【移动到最前】【移动到最后】两个按钮。

<template>
  <div>
          <el-table ref="multipleTable" :data="tplModel.categoryList" style="width:100%">
            <el-table-column type="index">
            </el-table-column>
            <el-table-column prop="text" label="分类名">
            </el-table-column>
            <el-table-column label="排序">
              <template slot-scope="scope">
                <ListSortEditor v-model="tplModel.categoryList" :index="scope.$index" :btns="{top:{enabled:false}, bottom:{enabled:false}}">
                  <template v-slot:up="sc">
                      <div><span>UP</span></div>
          </template>
                  <template v-slot:down="sc">
                      <div><span>DOWN</span></div>
          </template>
                </ListSortEditor>
              </template>
            </el-table-column>
          </el-table>
  </div>
</template>
<script type="text/javascript">
import ListSortEditor from 'wbfc-vs-tpl-editor/components/list-sort-editor'
export default {
  components: {
    ListSortEditor,
  }
  ...
}
</script>

Build Setup

# install dependencies
npm install

# serve with hot reload at localhost:8080
npm run dev

# build for production with minification
npm run build

# build for production and view the bundle analyzer report
npm run build --report

For a detailed explanation on how things work, check out the guide and docs for vue-loader.

0.2.3

2 years ago

0.2.2

2 years ago

0.2.1

3 years ago

0.2.0

3 years ago

0.1.9

3 years ago

0.1.8

3 years ago

0.1.7

3 years ago

0.1.6

3 years ago

0.1.5

3 years ago

0.1.3

3 years ago

0.1.2

3 years ago

0.1.1

3 years ago

0.1.0

3 years ago

0.0.9

3 years ago

0.0.8

3 years ago

0.0.6

3 years ago

0.0.5

4 years ago

0.0.4

4 years ago

0.0.3

4 years ago

0.0.2

4 years ago

0.0.1

4 years ago