這篇文章主要介紹vue動態(tài)渲染svg、添加點擊事件的實現(xiàn)方法,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!
懷來網(wǎng)站制作公司哪家好,找成都創(chuàng)新互聯(lián)公司!從網(wǎng)頁設計、網(wǎng)站建設、微信開發(fā)、APP開發(fā)、響應式網(wǎng)站設計等網(wǎng)站項目制作,到程序開發(fā),運營維護。成都創(chuàng)新互聯(lián)公司從2013年創(chuàng)立到現(xiàn)在10年的時間,我們擁有了豐富的建站經(jīng)驗和運維經(jīng)驗,來保證我們的工作的順利進行。專注于網(wǎng)站建設就選成都創(chuàng)新互聯(lián)公司。
業(yè)務需求(vue項目中)
1.頁面展示svg內(nèi)容
2.監(jiān)聽svg內(nèi)部的點擊事件
3.動態(tài)改變svg內(nèi)部元素的屬性和值
html標簽
經(jīng)多次實驗,用embed、img等標簽改變src屬性的方式,均無法實現(xiàn)上述全部功能(尤其是svg內(nèi)部點擊事件),最終采用Vue.extend()方法完整實現(xiàn),代碼也較為簡潔,html結構如下:
<template> <div> <div id="svgTemplate"></div> </div> </template>
直接將svg文件的內(nèi)容復制粘貼到.vue文件里,是可以在標簽內(nèi)直接添加@click事件完成需求的,方式簡單但會造成文件過長,本文不多陳述
實現(xiàn)思路
1.創(chuàng)建xhr對象
const xhr = new XMLHttpRequest(); this.svgUrl = ...; // svg的絕對地址,在瀏覽器中打開能看到的那個 xhr.open("GET", this.svgUrl, true); xhr.send();
2.監(jiān)聽xhr對象(獲取svg的dom -> 添加事件 -> 修改dom -> 轉(zhuǎn)成虛擬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的語法,動態(tài)設置svg部件的屬性和值 // ④ 將svgDom對象轉(zhuǎn)換成vue的虛擬dom,創(chuàng)建實例并掛載到元素上 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里要執(zhí)行的事件綁定到window下面,供外部(剛添加的 handleClick 事件)調(diào)用
async mounted() { window["handleClick"] = () => { this.takePhoto(); }; }, methods:{ takePhoto(){ ... } }
到這里就基本完成需求:動態(tài)渲染了svg、用js操作dom的語法修改svg部件的屬性和值、給svg部件動態(tài)添加了事件 handleClick,最后將 takePhoto() 事件綁定給了 window 對象的 handleClick,可以放心大膽的在 takePhoto() 里寫你要執(zhí)行的內(nèi)容了!
特殊注意
給svg的dom部件添加事件時:
1.經(jīng)多次嘗試,只有 setAttribute + v-on:click 寫法有效
2.setAttribute 不支持 @click(非原生事件),會報語法錯誤
3.addEventListener 和 onclick 均會被 vue 攔截
將svgDom對象轉(zhuǎn)換成vue的虛擬dom時:
1.如果報錯如下
則將 import Vue from "vue" 改為 import Vue from "vue/dist/vue.esm.js"
其原因及其他解決辦法本文不做探討可自行百度。
2.vue.extend() 方法是 vue 的一個構造器,用來動態(tài)創(chuàng)建 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下面,提供給外部調(diào)用 window["handleClick"] = () => { this.takePhoto(); }; }, created() { this.getSvg(); }, methods: { // 初始化svg getSvg() { /* 創(chuàng)建xhr對象 */ const xhr = new XMLHttpRequest(); this.svgUrl = this.baseUrl + "/svgs/" + "test.svg"; xhr.open("GET", this.svgUrl, true); xhr.send(); /* 監(jiān)聽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對象轉(zhuǎn)換成vue的虛擬dom */ var oSerializer = new XMLSerializer(); var sXML = oSerializer.serializeToString(this.svgDom); var Profile = Vue.extend({ template: "<div id='svgTemplate'>" + sXML + "</div>" }); // 創(chuàng)建實例,并掛載到元素上 new Profile().$mount("#svgTemplate"); }); }, // 事件 takePhoto() { ... }, }, beforeDestroy() { this.svgDom = null; }, watch: { photoResult: { handler(newVal, oldVal) { this.getSvg(); }, deep: true } } }; </script>
Vue是一套用于構建用戶界面的漸進式JavaScript框架,Vue與其它大型框架的區(qū)別是,使用Vue可以自底向上逐層應用,其核心庫只關注視圖層,方便與第三方庫和項目整合,且使用Vue可以采用單文件組件和Vue生態(tài)系統(tǒng)支持的庫開發(fā)復雜的單頁應用。
以上是“vue動態(tài)渲染svg、添加點擊事件的實現(xiàn)方法”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對大家有幫助,更多相關知識,歡迎關注創(chuàng)新互聯(lián)行業(yè)資訊頻道!
當前文章:vue動態(tài)渲染svg、添加點擊事件的實現(xiàn)方法
網(wǎng)頁網(wǎng)址:http://m.newbst.com/article24/gpijce.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站排名、網(wǎng)站改版、定制開發(fā)、靜態(tài)網(wǎng)站、ChatGPT、建站公司
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)