We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
希望我们的后台页面可以靠拖拽组件来生成,开发时只要处理js部分。拖拽后可以查看code直接复制代码。目前设计了一个大框子,大概长下面这个样子:
先说下我在设计这个大框子时遇到的几个问题:
$slots
$createElement
$slots.default
handleNest(result) { const container = result.vueComp; const son = this.$createElement(`my-${this.compName.toLowerCase()}`); container.$slots.default.push(son); container.$mount(); this.component = son.componentInstance;// 这样我们还可以使用this.component去拿到我们添加的方法和属性 },
import { getStringTypeAttr, getResultStringTypeAttr } from '@/components/template'; import mixins from './mixin.js'; const handle = function (_attr, _slots) { // 定义默认属性 const attributes = { content: { type: 'text', valueType: 'text', value: 'el-button', }, type: { type: 'select', valueType: 'text', items: ['primary', 'success', 'warning', 'danger', 'info', 'text'], value: 'primary', }, size: { type: 'select', valueType: 'text', items: ['medium', 'small', 'mini'], value: 'medium', }, disabled: { type: 'select', valueType: 'boolean', items: ['true', 'false'], value: 'false', }, }; const props = { content: { default: 'el-button', }, type: { default: 'primary', }, size: { default: 'medium', }, disabled: { default: false, }, }; const slots = { default: [], }; // 覆盖默认属性 Object.assign(slots, _slots); Object.assign(attributes, _attr); // 获取组件模板 const template = mixins.getStrTemplate(attributes, 'el-button'); // 获取代码模板(组件模板 + 绑定数据值) const getTemplate = (attr, child) => mixins.getTemplateByTag(attributes, attr, 'el-button', child); return { template, props, attributes, slots, getTemplate, }; }; export default handle;
export default { getTemplateByTag(attributes, attr, tagName, child) { const newAttr = _.overwriteDeep(attributes, attr); const resStringAttr = getResultStringTypeAttr(newAttr); const resTemplate = `<${tagName} ${resStringAttr}> ${child || ''} </${tagName}>`; return resTemplate; }, }
const getResultStringTypeAttr = function (attributes) { // value为空的不添加到模板中 let stringAttr = ''; Object.keys(attributes).forEach((key) => { let attrKey; const arr = ['text', 'selection', 'icon', 'ionicon', 'color']; // 这些类型都不用加bind if (arr.includes(attributes[key].valueType)) { attrKey = key; } else { attrKey = `:${key}`; } if (attrKey === 'value') { attrKey = 'v-model'; } const attr = attributes[key].value ? `${attrKey}="${attributes[key].value}"\n` : ''; stringAttr += attr; }); return stringAttr; };
(2)父子关系之间的查找其实很简单,当我们拖拽一个组件的时候,我们就生成一个id,并且遍历这个组件,为其子元素设置id和对应的parentId。当组件之间发生嵌套时,同样进行处理,这样我们最终只要找到根元素id就能遍历出整个dom结构。 (3)html 代码的格式化使用了pretty这个包, html语法高亮使用了vue-highlightjs 这个包
The text was updated successfully, but these errors were encountered:
No branches or pull requests
设计及初步实现
希望我们的后台页面可以靠拖拽组件来生成,开发时只要处理js部分。拖拽后可以查看code直接复制代码。目前设计了一个大框子,大概长下面这个样子:
思路
先说下我在设计这个大框子时遇到的几个问题:
解决方法
$slots
代码如下(1)通过
$createElement
生成vnode(2)把vnode push到container的
$slots.default
数组里(3)vnode.componentInstance 绑定了这个vnode 最终生成的vue实例,这样有了它,我们就能把修改的属性更新到其身上
我们利用我们添加的template属性,可以比较容易的获取到字符串模板。但也遇到了以下一些问题:
(1)比如我们左边是可以修改组件的属性信息的,那么模板如何与属性信息进行绑定的?
(2)组件之间是可以嵌套的,如何建立组件之间的父子关系?
(3)我们最终得到的字符串在代码模式下如何格式化和高亮?
让我们来依次回答下这些问题:
(1)其实我们本质是要用下面这个方法,来获取最终模板, 里面核心的就是获取最终attributes字符串的方法
(2)父子关系之间的查找其实很简单,当我们拖拽一个组件的时候,我们就生成一个id,并且遍历这个组件,为其子元素设置id和对应的parentId。当组件之间发生嵌套时,同样进行处理,这样我们最终只要找到根元素id就能遍历出整个dom结构。
(3)html 代码的格式化使用了pretty这个包, html语法高亮使用了vue-highlightjs 这个包
接下来要做的功能
The text was updated successfully, but these errors were encountered: