最近在研究一个自动化项目, 让使用者可以直接编辑网页上得模块 (用 Vue 写的)
项目业务
1.首先 从数据库 获取 head 和 body 的innerHTML 文本
2.然后用 递归 循环 head ,body 的所有节点 其中包括 注释节点, 转换成 render 函数节点 (期间添加N多个自动化方法),这样就可以在vue 中渲染页面实现想要 自动化的功能
render 函数参数 使用方法简介 :
render 中返回一个 h函数 h(元素名,{ 元素上绑定的,事件,attrs,style,class ....等 }, [子节点 h(...), h(...), h(...) , ...... ])
import Vue from 'vue'
let VNode = new Vue({
created () { // 生命周期 },
render ( h ) { // render 创建虚拟DOM 直到渲染
return h ('div', {...}, [...])
},
methods: { // 方法 },
data () {
return { // 数据 }
}
}).$mount()
export default VNode
小栗子:
// 递归所有DOM节点 生成 VNode 函数
childs (node, h) {
let childNode = []
let flage = false
node.childNodes.forEach(ele => {
if (ele.childNodes.length > 0) {
childNode.push(this.childs(ele, h))
} else {
if (ele.nodeType === 1) {
childNode.push(h(ele.tagName, this.setAttr(ele.attributes)))
} else {
if (ele.nodeType === 8) {
let notes = h('', {})
notes.text = ele.nodeValue
childNode.push(notes)
} else {
if (ele.nodeValue.replace(/\s/g, '') !== '') flage = true
childNode.push(ele.nodeValue)
}
}
}
})
return h(node.tagName, this.setAttr(node.attributes, flage), childNode)
},
// 还原 attributes 属性
setAttr (attr, flage) {
let obj = {
style: {},
attrs: {},
on: {}
}
if (flage) obj.attrs['contenteditable'] = true
for (let key in attr) {
if (attr.hasOwnProperty(key)) {
if (attr[key].nodeName === 'href') {
obj.attrs[attr[key].nodeName] = path.resolve(__dirname, 'static/' + (attr[key].nodeValue.split('/').pop()))
} else if (attr[key].nodeName === 'src') {
obj.attrs[attr[key].nodeName] = path.resolve(__dirname, 'static/images/' + (attr[key].nodeValue.split('/').pop()))
} else {
obj.attrs[attr[key].nodeName] = attr[key].nodeValue
}
}
}
return obj
}
问题:
1. render 函数 怎么添加字符串节点
h 函数 第一个参数 必须填 标签名, 如果不填 就会渲染成 注释的空节点 <!-- -->
所以最好 在子集数组中 push 字符串 自动生成字符串节点
我也试过 在对象中 添加 innerText 属性, 虚拟节点时能看到结构, 但渲染真是DOM 后 添加innerText的元素 子级元素 就全没了
h('div', {...}, ['我是字符串节点1', '我是字符串节点2'])
2. render 函数 怎么添加 注释节
let notes = h('', {}) // 首先创建一个空节点 render 会创建出一个
notes.text = '我是被注释的内容'
此时 notes 虚拟节点 最后会被渲染成 : <-- 我是被注释的内容 -->
VNode 虚拟节点属性作用 参考
children 子节点,数组,也是VNode类型。
text 当前节点的文本,一般文本节点或注释节点会有该属性。
elm 当前虚拟节点对应的真实的DOM节点。
ns 节点的namespace。
context 编译作用域。
functionalContext 函数化组件的作用域。
key 节点的key属性,用于作为节点的标识,有利于patch的优化。
componentOptions 创建组件实例时会用到的信息选项。
child 当前节点对应的组件实例。
parent 组件的占位节点。
raw 原始html。
isStatic 静态节点的标识。
isRootInsert 是否作为根节点插入,被<transition>包裹的节点,该属性的值为false。
isComment 当前节点是否是注释节点。
isCloned 当前节点是否为克隆节点。
isOnce 当前节点是否有v-once指令。