全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

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操作还是避免不了的。其它不多说了,直接看代码。。。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="Content-type" content="text/html,charset=utf-8"/>
  <meta http-equiv="X-UA-Compatible" content="IE-edge">
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <link href="css/mui.min.css" rel="stylesheet">
  <link href="css/app.css" rel="stylesheet">
  <script src="js/vue.js" type="text/javascript"></script>
</head>
<body>
<div id="main" class="mui-content">
</div>
</body>
<script src="js/fuhao-components.js" type="text/javascript"></script>

<script>

  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());
  }
</script>
</html>

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

var textTpl='';
<div class="mui-content-padded">
  <input :type="type" :name="key" :placeholder="keyname" >
</div>
  
var textareaTpl= '';
<div class="mui-content-padded ">
  <textarea rows="5" :placeholder="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">
  <h5 class="mui-content-padded" v-text="keyname"></h5>
    <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">拍照</button> 
  <img :id="key" height="70" width="100" class="img-rounded">
</div>
  
var gpsTpl='';
<div class="mui-content col-xs-12">
  <button class="mui-btn mui-btn-primary" :id="key" onclick="takeLocation(this.id)">
  获取定位
  </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>

最终渲染效果如下:

鉴于vue结合dom操作动态生成自定义组件,控制台会报一定的错误这一点bug还在努力修复中,可能需要更加深入地了解vue数据绑定及传递机制与js动态注册自定义组件的深入领会,继续努力中。。。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


# vue  # 自定义组件  # vue.js  # 使用 webpack 插件自动生成 vue 路由文件的方法  # vue-cli3 项目优化之通过 node 自动生成组件模板 generate View、Compo  # 通过npm或yarn自动生成vue组件的方法示例  # 基于Vue-Cli 打包自动生成/抽离相关配置文件的实现方法  # 如何通过shell脚本自动生成vue文件详解  # vue3输入单号和张数如何自动生成连号的单号  # 重中之重  # 自定义  # 之重  # 会报  # 写好  # 重中  # 都是  # 放在  # 还在  # 大家都  # 说了  # 不多  # 三大  # 提示信息  # 我将  # 所示  # 所述  # 绑定  # 必须先  # 大家多多 


相关文章: 哪家制作企业网站好,开办像阿里巴巴那样的网络公司和网站要怎么做?  h5网站制作工具有哪些,h5页面制作工具有哪些?  弹幕视频网站制作教程下载,弹幕视频网站是什么意思?  XML的“混合内容”是什么 怎么用DTD或XSD定义  ,交易猫的商品怎么发布到网站上去?  智能起名网站制作软件有哪些,制作logo的软件?  Python lxml的etree和ElementTree有什么区别  青岛网站建设如何选择本地服务器?  公司网站设计制作厂家,怎么创建自己的一个网站?  沈阳个人网站制作公司,哪个网站能考到沈阳事业编招聘的信息?  c# Task.Yield 的作用是什么 它和Task.Delay(1)有区别吗  网站制作费用多少钱,一个网站的运营,需要哪些费用?  西安专业网站制作公司有哪些,陕西省建行官方网站?  建站主机数据库如何配置才能提升网站性能?  高端建站如何打造兼具美学与转化的品牌官网?  如何零成本快速生成个人自助网站?  桂林网站制作公司有哪些,桂林马拉松怎么报名?  宁波自助建站系统如何快速打造专业企业网站?  建站org新手必看:2024最新搭建流程与模板选择技巧  浅析上传头像示例及其注意事项  在线ppt制作网站有哪些,请推荐几个好的课件下载的网站?  视频网站制作教程,怎么样制作优酷网的小视频?  如何撰写建站申请书?关键要点有哪些?  MySQL查询结果复制到新表的方法(更新、插入)  大同网页,大同瑞慈医院官网?  大连网站制作公司哪家好一点,大连买房网站哪个好?  如何正确下载安装西数主机建站助手?  建站主机系统SEO优化与智能配置核心关键词操作指南  建站主机解析:虚拟主机配置与服务器选择指南  已有域名如何快速搭建专属网站?  如何快速生成可下载的建站源码工具?  如何在Mac上搭建Golang开发环境_使用Homebrew安装和管理Go版本  微信小程序 五星评分(包括半颗星评分)实例代码  宝塔Windows建站如何避免显示默认IIS页面?  如何在云虚拟主机上快速搭建个人网站?  如何高效配置IIS服务器搭建网站?  网站图片在线制作软件,怎么在图片上做链接?  为什么Go需要go mod文件_Go go mod文件作用说明  JS中使用new Date(str)创建时间对象不兼容firefox和ie的解决方法(两种)  定制建站策划方案_专业建站与网站建设方案一站式指南  如何在万网自助建站中设置域名及备案?  建站之星后台管理系统如何操作?  深圳网站制作培训,深圳哪些招聘网站比较好?  如何制作网站标识牌,动态网站如何制作(教程)?  如何通过服务器快速搭建网站?完整步骤解析  建站之星如何优化SEO以实现高效排名?  相册网站制作软件,图片上的网址怎么复制?  公司网站建设制作费用,想建设一个属于自己的企业网站,该如何去做?  建站之星Pro快速搭建教程:模板选择与功能配置指南  实例解析Array和String方法 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。