js拼接html时怎样使用vue组件?

本文探讨了在Vue中使用JavaScript拼接HTML组件标签时遇到的渲染问题及其解决方案。通过分析Vue实例化和组件解析的时机,提出了两种方法使js拼接的组件能够正常渲染:在Vue实例化前执行或在拼接后重新实例化。同时,展示了如何实现js拼接的HTML组件使用Vue指令、修饰符,并调用父实例的方法。示例代码详细展示了具体实现过程。
问题

因业务需要,需要使用js拼接html来绘制dom,但是发现js拼接组件标签时,不能把组件渲染出来

如下面这种方式

html:

<div id="app">
  <div id="container"></div>
</div>

javascript:

new Vue({
  el: '#app',
  mounted() {
    let html = `<el-button>Button</el-button>`
    document.getElementById('container').innerHTML = html
  },
})

最终编辑出来的html没能正常将渲染

异常渲染截图

在这里插入图片描述

而我们一般将组件写在html的就可以正常渲染,如下

html:

<div id="app">
  <div id="container">
    <el-button>Button</el-button>
  </div>
</div>

javascript:

new Vue({
  el: '#app',
})

正常渲染截图
在这里插入图片描述

思考
为什么js拼接的组件标签就不能正常解析呢?

因为vue执行mounted钩子的时候vue实例已经实例化完成了,而在组件标签的渲染是在组件实例化的时候才能解析,所以这次会出现<el-button>解析不了的情况

怎样才能让js拼接的组件标签正常解析呢?

第一种方法:js拼接html,在vue实例化之前执行,如下

html:

 <div id="app">
  <div id="container"></div>
</div>

javascript:

let html = `<el-button>Button</el-button>`
document.getElementById('container').innerHTML = html
new Vue({
  el: '#app',
})

第二种方法:在js拼接html执行后,再实例化一遍,此时实例的节点应是拼接元素的父级或祖先,如下

html:

<div id="app">
  <div id="container"></div>
</div>

javascript:

new Vue({
  el: '#app',
  mounted() {
    let html = `<el-button>Button</el-button>`
    document.getElementById('container').innerHTML = html
    this.$nextTick(() => {
      new Vue({
        el: '#container'
      })
    })
  },
})

渲染截图
在这里插入图片描述

拓展思考

以上已经实现了js拼接html组件,那么我们怎么实现js拼接的html可以使用vue的指令,修饰符等功能、以及怎么调用父实例的模块呢?

下面直接上源码(已标明主要注释),可以直接copy运行

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <script src="https://unpkg.com/element-ui/lib/index.js"></script>
</head>
<body>
  <div id="app">
    <p>点击次数:{{count}}</p>
    <div id="container"></div>
  </div>
</body>
</html>

<script>
  new Vue({
    el: '#app',
    data() {
      return {
        count: 0,
      }
    },
    mounted() {
      const vm = this // 将父实例存储于vm
      let html = `<el-button @click="changeMessage">Button</el-button>`
      document.getElementById('container').innerHTML = html
      new Vue({
        el: '#container',
        methods: {
          // 子实例方法
          changeMessage() {
            vm.count++ // 调用并操作父实例的属性
          }
        },
      })
    },
  })
</script>



ps: 转载请注明出处

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值