Vue combines native JS to automate custom component generation

Source: Internet
Author: User

In the current three front-end mainstream data-driven framework (VUE,NG,REACT), all have to create custom components of the API, but all must first write the mount point, this mount point can be the original static element tag can also be a custom template, for a variety of components through the same data flow generated, If you write the mount point (mounted) on the page beforehand and then add it dynamically via DOM operation, you will encounter an error message like this:Failed to execute ' appendchild ' on ' Node ': Parameter 1 isn't of type ' Node '. (...)。 And why, what about the next step?

The reason is that any DOM operation object must be a standard-compliant element, except as described below, overwriting the prototype that generates the HTML element object   (Htmlelement.prototype) and registering the custom element, enabling the effect of dynamically generating custom components.

However, it is understood that the purpose of using a data-driven framework is to avoid DOM operations as much as possible, and that there are some DOM operations in the following code, which, as far as cognitive levels are concerned, feel that these necessary DOM operations are still unavoidable. Other not much to say, look directly at the code ...

<! DOCTYPE html>varJsondata = [        {            "KeyName": "The name is pale and the heat is heavy in the heat of the hot magazine",            ' Type ': ' Text ',            "Key": "Name11"        }, {            "Value": "The name of the hot heat of the Journal of Hubei",            "Key": "Name11"        }, {            "KeyName": "The name of the pale and hot hot heat is the heavy in the middle of the heavy issue of the hot heat of the magazine",        },        {            "KeyName": "The name of the pale and hot hot heat is the heavy in the middle of the heavy issue of the hot heat of the magazine",            "Type": "TextArea",            "Key": "Name"        },        {            "KeyName": "Gender",            "Type": "Radio",            "Key": "Sex",            "Values": [                {                    "Key": "Man",                    "Value": "Male Tutoring class"                },                {                    "Key": "Women",                    "Value": "Female"                }            ]        },        {            "KeyName": "Check",            ' Type ': ' checkbox ',            "Key": "checkbox",            "Values": [                {                    "Key": "Man",                    "Value": "Male"                },                {                    "Key": "Women",                    "Value": "Female"                }            ]        },        {            "KeyName": "Type",            ' Type ': ' SELECT ',            "Key": "Type1",            "Values": [                {                    "Key": "Type1",                    "Value": "Type 1"                },                {                    "Key": "Type2",                    "Value": "Type 2"                },                {                    "Key": "Type3",                    "Value": "Type 3"                },                {                    "Key": "Type4",                    "Value": "Type 4"                }            ]        },        {            "KeyName": "Positioning",            "Type": "GPs",            "Key": "BTN",            "Value": "Map get positioning"        },        {            "KeyName": "Take pictures",            "Type": "Photo",            "Key": "BTN",            "Value": "Take pictures"        }    ]; (function() {Analyjson (jsondata);    })(); functionAnalyjson (data) {if(' ID 'inchdata)        {Arguments.callee (data.values); } Else {            if(' Name 'inchdata) {HTMLName=Data.name;                Createinputviewer (Data.name);            Arguments.callee (data.values); } Else {                if(' type 'inchdata)                {createinputviewer (data); } Else {                     for(varPinchdata)                    {createinputviewer (data[p]); }                }            }        }    }    functioncreateinputviewer (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; }        }    }    functionFh_c (d, C, CN, TPL) {console.log (d); Vue.component (c, {template:tpl,//props:[' key ', ' keyname ', ' values ', ' value ' ,Datafunction () {                returnd}}); NewVue ({el:'. Mui-content ', components: {CN:CN},}); varMyelementproto =object.create (Htmlelement.prototype); Myelementproto.createdcallback=function () {             This. InnerHTML =TPL}; varMyComponent =Document.registerelement (c, {prototype:myelementproto}); Document.queryselector ('. Mui-content '). AppendChild (Newmycomponent ()); }</script>

In order to maintain the maintainability and legibility of the code, I put the template part separately in the Fuhao-components.js file, as follows:


var texttpl= ' \
<div class= "mui-content-padded" >\
<input:type= "type": Name= "key":p laceholder= "KeyName" >\
</div>\
‘;
var textareatpl= ' \
<div class= "mui-content-padded" >\
<textarea rows= "5":p laceholder= "KeyName" > \
</textarea>\
</div>\
‘;
var radiotpl= ' \
<form class= "Mui-input-group mui-content-padded" >\
<div class= "Mui-input-row mui-radio mui-left" v-for= "value in Values" >\
<label>{{value.key}}</label>\
<input:name= "key": Type= "type": value= "key" >\
</div>\
</form>\
‘;
var checkboxtpl= ' \
<form class= "Mui-input-group mui-content-padded" >\
<div class= "Mui-input-row mui-checkbox mui-left" v-for= "value in Values" >\
<label>{{value.key}}</label>\
<input:name= "key": Type= "type": value= "key" >\
</div>\
</form>\
‘;
var selecttpl= ' \
<div class= "mui-content-padded" >\

<select class= "Mui-btn mui-btn-block": Name= "key" >\
<option value= "key" v-text= "Value.key" v-for= "value in Values" >{{value.key}}</option>\
</select>\
</div>\
‘;
var phototpl= ' \
<div class= "mui-content-padded" >\
<span v-text= "KeyName" ></span>\
<button:name= "Key" onclick= "Takephoto (this.name)" class= "mui-btn mui-btn-primary" > Photography </button> \
\
</div>\
‘;
var gpstpl= ' \
<div class= "Mui-content col-xs-12" >\
<button class= "Mui-btn mui-btn-primary": id= "Key" onclick= "\takelocation (this.id)" >\
Get location \
</button>\
</div>\
‘;
var defaulttpl= ' \
<div class= "mui-content-padded" v-if= "key" >\
<ul class= "Mui-table-view" >\
<li class= "Mui-table-view-cell mui-media" >\
<span class= "Fuhaokey" v-text= "key" ></span>\
<span class= "Fuhaovalue" v-text= "value" ></span>\
</li>\
</ul >\
</div>\
‘;

The final rendering effect is as follows:

Since Vue combines DOM operations to dynamically generate custom components, the console will report a certain error this bug is still in the effort to repair, may need more in-depth understanding of the Vue data binding and delivery mechanism and JS dynamic registration of custom components in-depth understanding, continue to work ...

Thank you for reading, the shortcomings are also looking for a lot of advice, thank you very much.

Reference: 1.http://www.html-js.com/article/2753

2.http://vuejs.org/

Vue with native JS for custom component auto-generation

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.