电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

vue動態渲染svg、添加點擊事件的實現

瀏覽:48日期:2023-01-31 14:39:23

業務需求(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下面,供外部(剛添加的 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下面,提供給外部調用 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、添加點擊事件內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Vue
相關文章:
主站蜘蛛池模板: 西装定制/做厂家/公司_西装订做/制价格/费用-北京圣达信西装 | 咖啡加盟,咖啡店加盟连锁品牌-卡小逗 | 产业规划_产业园区规划-产业投资选址及规划招商托管一体化服务商-中机院产业园区规划网 | 北京开业庆典策划-年会活动策划公司-舞龙舞狮团大鼓表演-北京盛乾龙狮鼓乐礼仪庆典策划公司 | 外观设计_设备外观设计_外观设计公司_产品外观设计_机械设备外观设计_东莞工业设计公司-意品深蓝 | 定制/定做衬衫厂家/公司-衬衫订做/订制价格/费用-北京圣达信 | 自动部分收集器,进口无油隔膜真空泵,SPME固相微萃取头-上海楚定分析仪器有限公司 | 佛山市钱丰金属不锈钢蜂窝板定制厂家|不锈钢装饰线条|不锈钢屏风| 电梯装饰板|不锈钢蜂窝板不锈钢工艺板材厂家佛山市钱丰金属制品有限公司 | 【直乐】河北石家庄脊柱侧弯医院_治疗椎间盘突出哪家医院好_骨科脊柱外科专业医院_治疗抽动症/关节病骨伤权威医院|排行-直乐矫形中医医院 | 常州减速机_减速机厂家_常州市减速机厂有限公司 | 上海噪音治理公司-专业隔音降噪公司-中广通环保 | 硬质合金模具_硬质合金非标定制_硬面加工「生产厂家」-西迪技术股份有限公司 | 影视模板素材_原创专业影视实拍视频素材-8k像素素材网 | 上海物流公司,上海货运公司,上海物流专线-优骐物流公司 | 冷水机,风冷冷水机,水冷冷水机,螺杆冷水机专业制造商-上海祝松机械有限公司 | 壹车网 | 第一时间提供新车_资讯_报价_图片_排行! | 制氮设备_PSA制氮机_激光切割制氮机_氮气机生产厂家-苏州西斯气体设备有限公司 | 英超直播_英超免费在线高清直播_英超视频在线观看无插件-24直播网 | 找果网 | 苹果手机找回方法,苹果iPhone手机丢了找回,认准找果网! | 翰香原枣子坊加盟费多少钱-正宗枣核糕配方培训利润高飘香 | 厌氧反应器,IC厌氧反应器,厌氧三相分离器-山东创博环保科技有限公司 | 蜘蛛车-登高车-高空作业平台-高空作业车-曲臂剪叉式升降机租赁-重庆海克斯公司 | 专业的压球机生产线及解决方案厂家-河南腾达机械厂 | 宽带办理,电信宽带,移动宽带,联通宽带,电信宽带办理,移动宽带办理,联通宽带办理 | 卫浴散热器,卫浴暖气片,卫生间背篓暖气片,华圣格浴室暖气片 | 产业规划_产业园区规划-产业投资选址及规划招商托管一体化服务商-中机院产业园区规划网 | 工业铝型材-铝合金电机壳-铝排-气动执行器-山东永恒能源集团有限公司 | 挖掘机挖斗和铲斗生产厂家选择徐州崛起机械制造有限公司 | 尼龙PA610树脂,尼龙PA612树脂,尼龙PA1010树脂,透明尼龙-谷骐科技【官网】 | 超声波电磁流量计-液位计-孔板流量计-料位计-江苏信仪自动化仪表有限公司 | 伸缩节_伸缩器_传力接头_伸缩接头_巩义市联通管道厂 | 防渗膜厂家|养殖防渗膜|水产养殖防渗膜-泰安佳路通工程材料有限公司 | 英超直播_英超免费在线高清直播_英超视频在线观看无插件-24直播网 | 纯化水设备-纯水设备-超纯水设备-[大鹏水处理]纯水设备一站式服务商-东莞市大鹏水处理科技有限公司 | 2025世界机器人大会_IC China_半导体展_集成电路博览会_智能制造展览网 | 上海办公室装修公司_办公室设计_直营办公装修-羚志悦装 | 北京易通慧公司从事北京网站优化,北京网络推广、网站建设一站式服务商-北京网站优化公司 | 并离网逆变器_高频UPS电源定制_户用储能光伏逆变器厂家-深圳市索克新能源 | 深圳VI设计-画册设计-LOGO设计-包装设计-品牌策划公司-[智睿画册设计公司] | 滤芯,过滤器,滤油机,贺德克滤芯,精密滤芯_新乡市宇清流体净化技术有限公司 | LHH药品稳定性试验箱-BPS系列恒温恒湿箱-意大利超低温冰箱-上海一恒科学仪器有限公司 |