vue动态渲染svg、添加点击事件的实现
业务需求(vue项目中)
1.页面展示svg内容
2.监听svg内部的点击事件
3.动态改变svg内部元素的属性和值
html标签
经多次实验,用embed、img等标签改变src属性的方式,均无法实现上述全部功能(尤其是svg内部点击事件),最终采用Vue.extend()方法完整实现,代码也较为简洁,html结构如下
<template> <div> <div id="svgTemplate"></div> </div> </template>
直接将svg文件的内容复制粘贴到.vue文件里,是可以在标签内直接添加@click事件完成需求的,方式简单但会造成文件过长,本文不多陈述
实现思路
1.创建xhr对象
const xhr = new XMLHttpRequest(); this.svgUrl = ...; // svg的绝对地址,在浏览器中打开能看到的那个 xhr.open("GET", this.svgUrl, true); xhr.send();
2.监听xhr对象(获取svg的dom -> 添加事件 -> 修改dom -> 转成虚拟dom并挂载)
xhr.addEventListener("load", () => { // ① 获取svg的dom const resXML = xhr.responseXML; this.svgDom = resXML.documentElement.cloneNode(true); // console.log(this.svgDom); // ② 添加click事件 let btn = this.svgDom.getElementById("..."); btn.setAttribute("v-on:click", "this.handleClick()"); // ↑↑↑ 此处注意原生事件handleClick此时在window层,解决办法见后文 // ③ 修改 dom this.svgDom.getElementById("...").childNodes[0].nodeValue = ... this.svgDom.getElementById("...").setAttribute("style", `....; fill:${this.photoResult.resultColor}; ...`); // ↑↑↑ 用js操作dom的语法,动态设置svg部件的属性和值 // ④ 将svgDom对象转换成vue的虚拟dom,创建实例并挂载到元素上 var oSerializer = new XMLSerializer(); var sXML = oSerializer.serializeToString(this.svgDom); var Profile = Vue.extend({ template: "<div id='svgTemplate'>" + sXML + "</div>" }); new Profile().$mount("#svgTemplate"); });
3.将methods里要执行的事件绑定到window狼蚁网站SEO优化,供外部(刚添加的 handleClick 事件)调用
async mounted() { window["handleClick"] = () => { this.takePhoto(); }; }, methods:{ takePhoto(){ ... } }
到这里就基本完成需求动态渲染了svg、用js操作dom的语法修改svg部件的属性和值、给svg部件动态添加了事件 handleClick,将 takePhoto() 事件绑定给了 window 对象的 handleClick,可以放心大胆的在 takePhoto() 里写你要执行的内容了!
特殊注意
给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狼蚁网站SEO优化,提供给外部调用 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()"); / 3. 修改 dom / this.svgDom.getElementById("...").childNodes[0].nodeValue = ...; this.svgDom.getElementById("...").setAttribute("style", `....; fill:${this.photoResult.resultColor}; ...`); / 4.将svgDom对象转换成vue的虚拟dom / var oSerializer = new XMLSerializer(); var sXML = oSerializer.serializeToString(this.svgDom); var Profile = Vue.extend({ template: "<div id='svgTemplate'>" + sXML + "</div>" }); // 创建实例,并挂载到元素上 new Profile().$mount("#svgTemplate"); }); }, // 事件 takePhoto() { ... }, }, beforeDestroy() { this.svgDom = null; }, watch: { photoResult: { handler(newVal, oldVal) { this.getSvg(); }, deep: true } } }; </script>
到此这篇关于vue动态渲染svg、添加点击事件的实现的文章就介绍到这了,更多相关vue动态渲染svg、添加点击事件内容请搜索狼蚁SEO以前的文章或继续浏览狼蚁网站SEO优化的相关文章希望大家以后多多支持狼蚁SEO!
编程语言
- 甘肃哪有关键词排名优化购买方式有哪些
- 甘肃SEO如何做网站优化
- 河南seo关键词优化怎么做电话营销
- 北京SEO优化如何做QQ群营销
- 来宾百度关键词排名:提升您网站曝光率的关键
- 卢龙关键词优化:提升您网站排名的策略与技巧
- 山东网站优化的注意事项有哪些
- 四川整站优化怎样提升在搜索引擎中的排名
- 疏附整站优化:提升网站性能与用户体验的全新
- 海南seo主要做什么工作售后服务要做到哪些
- 荣昌百度网站优化:提升您网站的搜索引擎排名
- 河北seo网站排名关键词优化如何做SEO
- 江西优化关键词排名推广售后保障一般有哪些
- 古浪SEO优化:提升你的网站可见性
- 西藏网站排名优化怎么把网站排名在百度首页
- 如何提升阳东百度快照排名:详尽指南