背景
每一次新項目的準備開發工作,都總是在重複使用組件去開發一個項目。組件的複用率雖然高,但還是需要開發人員去進行路由頁面的開發工作,工作任務仍歸類給前端。在這樣的背景下,搭建可視化頁面編輯的中臺系統尤爲重要,這樣可以解決大部分的前臺開發工作。
效果圖
思路示意圖
思路分析
- 所有面板之間的數據交互使用
Vuex
進行管理; - 組件使用封裝的
mount
方法實例化組件; - 使用
scopedStyle
方法爲組件插入scoped css
; - 拖曳組件時,設置被拖曳的組件數據,拖曳結束後,爲預覽面板新增一條組件數據,並實例化被拖曳的組件;
- 屬性面板只顯示當前組件
(currentComponent)
的屬性。
核心代碼解析
mount()
// 給定模板,和要掛載的元素id,掛載組件
var mount = function (id, _component) {
// 數據響應關係脫離
let _vue = global.deepClone(_component.vue);
if ( _vue.script && typeof _vue.script==='string' ) {
_vue.script = eval('(' + _vue.script + ')');
}
return new Promise((resolve, reject) => {
//需要延遲才能取到document.getElementById(id)
setTimeout(() => {
let VUELint = function (key,type) {
let _default;
let script = _vue.script || {};
let toString = Object.prototype.toString;
switch (type) {
case 'Object':
_default = {};
break;
case 'Function':
_default = ()=> {};
break;
}
if ( !script.hasOwnProperty(key) ) {
return _default;
} else if ( toString.call(script[key]).slice(8,-1)===type ) {
if ( type==='Object' ) {
return script[key];
} else if ( type==='Function' ) {
return script[key].call(this);
}
}
};
// 返回一個對象, 融合了組件暴露的屬性和data數據,暴露的屬性(attributes)優先於data, 且不一定存在於data
let VUEdata = function (){
let data = {};
let attributes = {};
if ( _vue.script.data ) {
data = _vue.script.data();
}
if ( _component.attributes ) {
Object.keys(_component.attributes).forEach(key => {
attributes[key] = _component.attributes[key].value;
});
}
return Object.assign(data, attributes);
};
// 核心代碼
let vm = new Vue({
router,
store,
name : id.toString(),
el : document.getElementById(id),
template : _vue.template,
data : VUEdata.call(this),
beforeCreate : VUELint.call(this,'beforeCreate','Function'),
created : VUELint.call(this,'created','Function'),
beforeMount : VUELint.call(this,'beforeMount','Function'),
mounted () {
this.$el.id = id;
scopedStyle(this.$el, _vue.css);
VUELint.call(this,'mounted','Function');
},
beforeUpdate : VUELint.call(this,'beforeUpdate','Function'),
updated : VUELint.call(this,'updated','Function'),
beforeDestroy: VUELint.call(this,'beforeDestroy','Function'),
destroyed : VUELint.call(this,'destroyed','Function'),
computed : VUELint.call(this,'computed','Object'),
watch : VUELint.call(this,'watch','Object'),
filters : VUELint.call(this,'filters','Object'),
methods : VUELint.call(this,'methods','Object'),
});
resolve(vm);
}, 200);
});
項目地址
文獻貢獻
基於Github
開源項目Vue-Layout
源碼基礎下,修改其思路模式所開源的項目,在此對作者表示感謝。