页面生成实现路程
- 在写 v-html渲染组件问题 的时候就是我想尝试实现页面的生成,但是当时技术还是不行没实现成功,现在有点效果了,记录一下过程
第一步也就是生成一个页面,如下图
- 刚开始我是将组件和页面分开,页面是生成个数组结果的对象,组件是直接挂载,页面数组如下:
[{
content: [
{
tag:"span",
content:"n你好"
}
]
style: "text-align:center"
tag: "div"
}]
/* 数组对象转化字符串
[
tag:,
style,
content
]*/
function arrChangeStr(arr) {
let str = ""
arr.forEach(e => {
if (Array.isArray( e.content)) {
str += `<${e.tag} style="${e.style}">${arrChangeStr(e.content)}</${e.tag}>`
} else {
str += `<${e.tag} style="${e.style}">${e.content}</${e.tag}>`
}
})
return str
}
// <div style="text-align:center"> <span>n你好</span></div>
然后就是每次点击左边的元素时,找到对应的数组的结点,对数组进行修改,再调用arrChangeStr转化为字符串,v-html 渲染
/* 反推找到DOM节点对应的数组位置 */
function backFind(el) {
let result = "";
console.log(el.className);
if (el.parentNode && el.className.indexOf("viewShowPage")==-1 && el.className.indexOf("view")==-1) {
console.log(el.parentNode.children);
[...el.parentNode.children].forEach((e, i) => {
if (e == el)
result= backFind(el.parentNode)+","+i
}
})
}
return result
}
- 但是后面发现,当组件挂载的时候,每次数组更新组件会消失重新挂载,这就需要每次挂载结点id的保存,并且每次都重新挂载,比较麻烦,而且最后生成代码也比较难搞,所以放弃这个方式,直接将arrChangeStr转化为字符串的dom直接挂载,这也就是源码。
- 然后就是对vue组件进行二次封装,将所有属性,尽量一次性数据解决,只需要传一个数据就可以,实现所有效果,这个就要是有人有想法的话,可以帮忙写一写🙏 😀,给个例子:
<div>
<div v-for="(item) in radioLists" :key="item.label">
<el-radio-group v-model="radio" :size="item.size">
<el-radio
v-if="!item.type||item.type!=='button'"
:disabled="item.disabled"
:border="item.border"
:size="item.size"
:label="item.label"
>{{item.name}}</el-radio>
<el-radio-button
v-else
:disabled="item.disabled"
:size="item.size"
:label="item.label"
>{{item.name}}</el-radio-button>
</el-radio-group>
</div>
</div>
</template>
<script>
export default {
name: "",
props: {
radioList: {
default: [
{
name: "备选框", /单选框名字
label: "1", //v-model 对应的值 唯一
disabled: false, //禁用
border: false, // 边框
size: "small", //
type: "button" //组件的显示类型
}
],
type: Array
}
},
data() {
return {
radio: "1",
radioLists: null
};
},
created() {
this.radioLists = this.radioList;
console.log(this.radioList);
},
Mounted() {
console.log(this.radioList);
},
watch: {
radioList: {
handler(oldval) {
this.radioLists = oldval;
console.log(this.radio);
}
}
}
};
</script>
<style scoped>
</style>
这里面 只需传radioList 数组就行, 当然还差change 的方法,这个先放一放。