vue html拼接自定义组件,Vue结合原生js实现自定义组件自动生成

就目前三大前端主流数据驱动框架(vue,ng,react)而言,均具有创建自定义组件的api,但都是必须先做到事先写好挂载点,这个挂载点可以是原有静态元素标签也可以是自定义模板;对于多种组件通过同一数据流生成的,如果事先在页面上写好挂载点(mounted),然后通过dom操作去动态添加,会遇到类似这样一条错误提示信息:Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'.(…)。这又是为何呢,下一步该怎么办?

原因是任何dom操作的对象必须是符合W3C标准的元素,除非如下所述的,改写生成html元素对象的原型(HTMLElement.prototype)并注册自定义元素,从而实现动态生成自定义组件的效果。

不过,大家都明白使用数据驱动框架的初衷就是尽可能避免dom操作,而如下代码中还是有一些dom操作的,就目前认知水平而言,感觉这些必要的dom操作还是避免不了的。其它不多说了,直接看代码。。。

`

var jsonData = [

{

"keyname": "姓名鄂然失色而热重重中之重重中之重杂志的热热",

"type": "text",

"key": "name11"

}, {

"value": "姓名鄂之重杂志的热热",

"key": "name11"

}, {

"keyname": "姓名鄂然失色而热热热热是重中之重重中之重重中之重杂志的热热",

},

{

"keyname": "姓名鄂然失色而热热热热是重中之重重中之重重中之重杂志的热热",

"type": "textarea",

"key": "name"

},

{

"keyname": "性别",

"type": "radio",

"key": "sex",

"values": [

{

"key": "man",

"value": "男辅导班"

},

{

"key": "women",

"value": "女"

}

]

},

{

"keyname": "复选",

"type": "checkbox",

"key": "checkbox",

"values": [

{

"key": "man",

"value": "男"

},

{

"key": "women",

"value": "女"

}

]

},

{

"keyname": "类型",

"type": "select",

"key": "type1",

"values": [

{

"key": "type1",

"value": "类型1"

},

{

"key": "type2",

"value": "类型2"

},

{

"key": "type3",

"value": "类型3"

},

{

"key": "type4",

"value": "类型4"

}

]

},

{

"keyname": "定位",

"type": "gps",

"key": "btn",

"value": "地图获取定位"

},

{

"keyname": "拍照",

"type": "photo",

"key": "btn",

"value": "拍照"

}

];

(function () {

AnalyJson(jsonData);

})();

function AnalyJson(data) {

if ('id' in data) {

arguments.callee(data.values);

} else {

if ('name' in data) {

htmlname = data.name;

CreateInputViewer(data.name);

arguments.callee(data.values);

} else {

if ('type' in data) {

CreateInputViewer(data);

} else {

for (var p in data) {

CreateInputViewer(data[p]);

}

}

}

}

}

function CreateInputViewer(data) {

switch (data.type) {

case 'text': {

fh_C(data, 'c-input-text' + '-' + data.key, 'fhInputText', textTpl);

break;

}

case 'textarea': {

fh_C(data, 'c-textarea' + '-' + data.key, 'fhInputTextarea', textareaTpl);

break;

}

case 'radio': {

fh_C(data, 'c-input-radio' + '-' + data.key, 'fhInputTextarea', radioTpl);

break;

}

case 'checkbox': {

fh_C(data, 'c-input-checkbox' + '-' + data.key, 'fhInputCheckbox', checkboxTpl);

break;

}

case 'select': {

fh_C(data, 'c-select' + '-' + data.key, 'fhSelect', selectTpl);

break;

}

case 'photo': {

fh_C(data, 'c-photo' + '-' + data.key, 'fhPhoto', photoTpl);

break;

}

case 'gps': {

fh_C(data, 'c-gps' + '-' + data.key, 'fhGPS', gpsTpl);

break;

}

default: {

fh_C(data, 'c-default' + '-' + data.key, 'fhInputDefault', defaultTpl);

break;

}

}

}

function fh_C(d, c, cn, tpl) {

console.log(d);

Vue.component(c, {

template: tpl,

// props:['key','keyname','values','value'],

data: function () {

return d

}

});

new Vue({

el: '.mui-content',

components: {

cn: cn

},

});

var MyElementProto = Object.create(HTMLElement.prototype);

MyElementProto.createdCallback = function () {

this.innerHTML = tpl

};

var MyComponent = document.registerElement(c, {prototype: MyElementProto});

document.querySelector('.mui-content').appendChild(new MyComponent());

}

`

复制代码

为了保持代码的可维护性及易读性,我将模板部分单独放在fuhao-components.js的文件里边,如下所示:

` var textTpl= '\

\

\

\

';

var textareaTpl= '\

\

\

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值