vue动态渲染svg、添加点击事件的实现

2020-06-16 06:37:27易采站长站整理

给svg的dom部件添加事件时:
1.经多次尝试,只有 setAttribute + v-on:click 写法有效
2.setAttribute 不支持 @click(非原生事件),会报语法错误
3.addEventListener 和 onclick 均会被 vue 拦截
将svgDom对象转换成vue的虚拟dom时:
1.如果报错如下

则将 import Vue from “vue” 改为 import Vue from “vue/dist/vue.esm.js”
其原因及其他解决办法本文不做探讨可自行百度。
2.vue.extend() 方法是 vue 的一个构造器,用来动态创建 vue 实例,template 组件模板只能有一个根元素
3.$mount 手动挂载到 id 为 svgTemplate的 元素上,挂载后将替换原本的dom(替换原本的 <div id=”svgTemplate”></div>)。由于每次更新 svg 都要重新挂载,没有找到 dom 元素是无法挂载的,因此 template 里面最外层的 div 也要加上 id 的属性:


var Profile = Vue.extend({
template: "<div id='svgTemplate'>" + sXML + "</div>"
// ↑↑↑ 最外层的 id 不能省略,否则首次渲染后找不到 #svgTemplate
});
new Profile().$mount("#svgTemplate");
// ↑↑↑ 原本的 #svgTemplate 将被替换成 Profile 的 template

完整代码


<template>
<div>
<div id="svgTemplate"></div>
</div>
</template>


<script>
import Vue from "vue/dist/vue.esm.js";

// window.handleClick = () => {
// 原本的 handleClick 事件是 window 的
// };

export default {
name: "svg-drawing",
data() {
return {
/* 全局 */
svgUrl: "", // svg的url
svgDom: null, // 获取到的svg元素
/* svg的变量 */
photoResult: {
resultVal: 0, // 测试结果 - 值
resultMsg: "未检测", // 测试结果 - 字段
resultColor: "#dcdee2" // 测试结果 - 字段背景色
}
};
},
async mounted() {
// 将takePhoto方法绑定到window下面,提供给外部调用
window["handleClick"] = () => {
this.takePhoto();
};
},
created() {
this.getSvg();
},
methods: {
// 初始化svg
getSvg() {
/* 创建xhr对象 */
const xhr = new XMLHttpRequest();
this.svgUrl = this.baseUrl + "/svgs/" + "test.svg";
xhr.open("GET", this.svgUrl, true);
xhr.send();

/* 监听xhr对象 */
xhr.addEventListener("load", () => {
/* 1. 获取 dom */
const resXML = xhr.responseXML;
this.svgDom = resXML.documentElement.cloneNode(true);

/* 2.SVG对象添加click事件 */
let btnTakePhotoDom = this.svgDom.getElementById("...");
btnTakePhotoDom.setAttribute("v-on:click", "this.handleClick()");