Vue項(xiàng)目中Websocket的使用實(shí)例
前言
由于項(xiàng)目需求有要使用長鏈接,我們普通的http請求如果用輪詢的方式與服務(wù)端通訊就很消耗資源。我們一起來學(xué)習(xí)一下在vue項(xiàng)目里如何使用websocket,本文純屬個(gè)人觀點(diǎn),如果有不正確的地方請大家批評指正,技術(shù)無高低,謙虛學(xué)習(xí)的心態(tài)我認(rèn)為很重要,天外有天人外有人。
判斷瀏覽器是否支持websocket的方法
比較直觀的方式是直接判斷全局對象中是否包含WebSocket對象即可:
if( typeof(WebSocket) != "function" ) { alert("您的瀏覽器不支持Websocket通信協(xié)議,請更換瀏覽器為Chrome或者Firefox再次使用!") }
但是這種方式不嚴(yán)謹(jǐn),在 Android 中,即使瀏覽器不支持 WebSocket ,但是它還是存在這個(gè)屬性。所以可以使用下面的方法:
if (typeof WebSocket != 'undefined') { console.log("您的瀏覽器支持Websocket通信協(xié)議") }else{ alert("您的瀏覽器不支持Websocket通信協(xié)議,請使用Chrome或者Firefox瀏覽器!") }
或者是這種方法:
if (!!window.WebSocket && window.WebSocket.prototype.send) { console.log("您的瀏覽器支持Websocket通信協(xié)議") }else{ alert("您的瀏覽器不支持Websocket通信協(xié)議,請使用Chrome或者Firefox瀏覽器!") }
Vue項(xiàng)目里使用websocket的實(shí)例
上面這個(gè)頁面是我所做項(xiàng)目里的某個(gè)頁面,由于硬件資源監(jiān)測和網(wǎng)絡(luò)性能監(jiān)測兩個(gè)板塊需要傳遞給服務(wù)端不同的參數(shù)來獲取數(shù)據(jù),傳參分別如下:
{ message: "sys_info" }
{ message: "net_info" }
我們需要建立2個(gè)不同的長鏈接。我們項(xiàng)目都是統(tǒng)一在public文件夾下的config.js里統(tǒng)一配置,不管是http請求還是websocket,代碼如下:
然后在一個(gè)js文件里將其封裝成一個(gè)函數(shù)并暴露出去,代碼如下:
然后在我們要使用到的組件里引入,并在data里定義兩個(gè)websock實(shí)例,然后再在mounted里初始化兩個(gè)websock實(shí)例,最后在destroyed銷毀頁面時(shí)一并銷毀兩個(gè)websock實(shí)例,代碼如下:
然后我們在methods里看看初始化websocket的兩個(gè)方法怎么寫的,代碼如下:
這里為了考慮各大瀏覽器是否兼容websocket,所以加了一個(gè)判斷語句:
if (typeof WebSocket === "undefined") return console.log("您的瀏覽器不支持websocket");
最后附上完整代碼,如有不正確之處望同行前輩批評指正:
<template> <div class="homePage"> <div class="topArea"> <el-card class="el-card"> <div slot="header" class="clearfix"> <div class="headerBox"> <span class="arrow" ><img src="../../assets/homePage/arrow.png" /></span> <span class="title">硬件資源監(jiān)測</span> <span class="topRight" ><img src="../../assets/homePage/topRight.png" /></span> </div> </div> <div class="myCont"> <div class="itemBox"> <div class="titleBox"> <span> <img src="../../assets/homePage/cpuTitle.png" alt="" /> </span> <span class="title">CPU資源監(jiān)測</span> </div> <div class="board"> <div class="left" id="cpuCharts"></div> <div class="right"> <div class="tipBox"> <span>CPU利用率</span> <span>{{ cpu_info.cpu_use }}%</span> </div> <div class="detailBox"> <div> <span></span> <span>CPU顆數(shù)</span> <span>{{ cpu_info.cpu_physical_count }}</span> </div> <div> <span></span> <span>CPU核數(shù)</span> <span>{{ cpu_info.cpu_kernel_count }}</span> </div> <div> <span></span> <span>CPU負(fù)載</span> <span>{{ cpu_info.cpu_average }}</span> </div> </div> </div> </div> </div> <div class="itemBox"> <div class="titleBox"> <span> <img src="../../assets/homePage/Memory.png" alt="" /> </span> <span class="title">內(nèi)存資源監(jiān)測</span> </div> <div class="board"> <div class="left" id="memoryCharts"></div> <div class="right"> <div class="tipBox"> <span>內(nèi)存利用率</span> <span>{{ mem_info.memory_percent }}%</span> </div> <div class="detailBox"> <div> <span style="background: none"></span> <span></span> <span></span> </div> <div> <span style="background: none"></span> <span></span> <span></span> </div> <div> <span></span> <span>內(nèi)存總量</span> <span>{{ mem_info.memory_total | FilterBps(mem_info.memory_total) }}</span> </div> </div> </div> </div> </div> <div class="itemBox"> <div class="titleBox"> <span> <img src="../../assets/homePage/Hard.png" alt="" /> </span> <span class="title">硬盤資源監(jiān)測</span> </div> <div class="board"> <div class="left" id="hardCharts"></div> <div class="right"> <div class="otherBox"> <div class="tipBox2"> <span>硬盤讀速率</span> <span>{{ disk_info.read_speed | FilterSpeed(disk_info.read_speed) }}</span> <span>MB/s</span> </div> <div class="tipBox2"> <span>硬盤寫速率</span> <span>{{ disk_info.write_speed | FilterSpeed(disk_info.write_speed) }}</span> <span>MB/s</span> </div> </div> <div class="detailBox"> <div> <span style="background: none"></span> <span></span> <span></span> </div> <div> <span style="background: none"></span> <span></span> <span></span> </div> <div> <span></span> <span>硬盤大小</span> <span >{{ disk_info.disk_total | FilterDiskTotal(disk_info.disk_total) }}T</span > </div> </div> </div> </div> </div> </div> </el-card> </div> <div class="topArea bottomArea"> <el-card class="el-card"> <div slot="header" class="clearfix"> <div class="headerBox"> <span class="arrow" ><img src="../../assets/homePage/arrow.png" /></span> <span class="title">網(wǎng)絡(luò)性能監(jiān)測</span> <span class="topRight" ><img src="../../assets/homePage/topRight.png" /></span> </div> </div> <div class="myCont"> <div class="Throughput"> <div class="titleBox"> <span ><img src="../../assets/homePage/Throughput.png" alt="" /></span> <span class="title">通道吞吐量</span> </div> <div class="lineBox" id="lineCharts"></div> <div class="lineTips"> <span ><img src="../../assets/homePage/lineTips.png" alt="" /></span> <span>吞吐量</span> <span>{{ inOutWay }}</span> <span>{{ inoutUnit }}</span> </div> </div> <div class="rightArea"> <div class="Item" v-for="(item, i) in card_info" :key="i"> <div class="topBox"> <div class="imgBox"> <img src="../../assets/homePage/Frame.png" alt="" /> </div> <div class="portTip">{{ Object.keys(item)[0] }}</div> <div class="transferBox transferBoxT"> <span> <img src="../../assets/homePage/transferTop.png" alt="" /> </span> <span class="Num">{{ WayMethods(item, "incoming") }}</span> </div> <div class="transferBox transferBoxB"> <span> <img src="../../assets/homePage/transferBottom.png" alt="" /> </span> <span class="Num">{{ WayMethods(item, "outgoing") }}</span> </div> </div> <div class="bottomBox"> <div> <span>工作速率:</span> <span>{{ WayMethods(item, "工作速率") }} </span> </div> <div> <span>雙工模式:</span> <span>{{ WayMethods(item, "雙工模式") }}</span> </div> <div> <span>自協(xié)商:</span> <span>{{ WayMethods(item, "自協(xié)商") }}</span> </div> <div> <span>接口類型:</span> <span>{{ WayMethods(item, "接口類型") }}</span> </div> <div> <span>鏈路狀態(tài):</span> <span>{{ WayMethods(item, "鏈路狀態(tài)") }}</span> </div> </div> </div> </div> </div> </el-card> </div> </div> </template> <script> import { homeWsUrl } from "@/api/websocket.js"; export default { data() { return { wsUrl: homeWsUrl(), websock: null, //ws實(shí)例 websockNet: null, //ws實(shí)例 cpu_info: { cpu_use: 0, }, mem_info: { memory_percent: 0, }, disk_info: { disk_percent: 0, }, inoutArr: [], //吞吐量集合 card_info: [], in_out_total: 0, //吞吐量 inoutUnit: "", }; }, filters: { FilterBps(bps) { if (bps) { let Grate = 1024 * 1024 * 1024; return (Number(bps) / Grate).toFixed(2) + "G"; } }, FilterSpeed(bps) { if (bps) { let Grate = 1024 * 1024; return (Number(bps) / Grate).toFixed(2); } else { return 0; } }, FilterDiskTotal(bps) { if (bps) { let Grate = 1024 * 1024 * 1024 * 1024; return (Number(bps) / Grate).toFixed(2); } }, }, mounted() { this.cpuCharts(); this.memoryCharts(); this.hardCharts(); this.lineCharts(); //初始化websocket,此頁面建立了2個(gè)長鏈接 this.initWebSocket(); this.initWebSocketNet(); }, destroyed() { //離開路由之后斷開websocket連接 this.websock.close(); this.websockNet.close(); }, computed: { inOutWay() { // console.log("inOutWay", this.in_out_total); if (this.in_out_total <= 1000) { return ( (this.inoutUnit = "bit/s"), (this.in_out_total = Number(this.in_out_total)) ); } else if (this.in_out_total > 1000 && this.in_out_total <= 1000 * 1000) { return ( (this.inoutUnit = "Kb/s"), (this.in_out_total = (Number(this.in_out_total) / 1000).toFixed(2)) ); } else if ( this.in_out_total > 1000 * 1000 && this.in_out_total <= 1000 * 1000 * 1000 ) { return ( (this.inoutUnit = "Mb/s"), (this.in_out_total = ( Number(this.in_out_total) / (1000 * 1000) ).toFixed(2)) ); } else if (this.in_out_total > 1000 * 1000 * 1000) { return ( (this.inoutUnit = "Gb/s"), (this.in_out_total = ( Number(this.in_out_total) / (1000 * 1000 * 1000) ).toFixed(2)) ); } }, }, methods: { cpuCharts() { let chartDom = document.getElementById("cpuCharts"); let myChart = this.$echarts.init(chartDom); let option = { // tooltip: { // formatter: "{a} <br/> : {c}%", // }, series: [ { name: "Pressure", title: { show: false, }, type: "gauge", progress: { show: true, }, radius: "100%", detail: { valueAnimation: true, formatter: "{value}%", fontSize: 14, }, data: [ { value: this.cpu_info.cpu_use, name: "SCORE", }, ], }, ], }; option && myChart.setOption(option); }, memoryCharts() { let chartDom = document.getElementById("memoryCharts"); let myChart = this.$echarts.init(chartDom); let option = { // tooltip: { // formatter: "{a} <br/> : {c}%", // }, series: [ { name: "Pressure", title: { show: false, }, type: "gauge", progress: { show: true, }, radius: "100%", detail: { valueAnimation: true, formatter: "{value}%", fontSize: 14, }, data: [ { value: this.mem_info.memory_percent, name: "SCORE", }, ], }, ], }; option && myChart.setOption(option); }, hardCharts() { let chartDom = document.getElementById("hardCharts"); let myChart = this.$echarts.init(chartDom); let option = { // tooltip: { // formatter: "{a} <br/> : {c}%", // }, series: [ { name: "Pressure", title: { show: false, }, type: "gauge", progress: { show: true, }, radius: "100%", detail: { valueAnimation: true, formatter: "{value}%", fontSize: 14, }, data: [ { value: this.disk_info.disk_percent, name: "SCORE", }, ], }, ], }; option && myChart.setOption(option); }, lineCharts() { let chartDom = document.getElementById("lineCharts"); let myChart = this.$echarts.init(chartDom); let option; // prettier-ignore // const data = [["2000-06-05", 1160], ["2000-06-06", 1209], ["2000-06-07", 1035], ["2000-06-08", 86], ["2000-06-09", 703], // ["2000-06-10", 805], ["2000-06-11", 73], ["2000-06-12", 68], ["2000-06-13", 92], ["2000-06-14", 130], ["2000-06-15", 245], // ]; // const dateList = data.map(function (item) { // return item[0]; // }); // const valueList = data.map(function (item) { // return item[1]; // }); // console.log("this.inoutArr",this.inoutArr) const data = this.inoutArr; const dateList = this.inoutArr; const valueList = this.inoutArr; option = { // Make gradient line here visualMap: [ { show: false, type: "continuous", seriesIndex: 0, min: 0, }, { show: false, type: "continuous", seriesIndex: 1, dimension: 0, min: 0, }, ], title: [ { left: "left", text: `吞吐量Gb/s`, textStyle: { fontSize: 12, color: "#7C818D", }, }, ], // tooltip: { // trigger: "axis", // }, xAxis: // { // data: dateList, // }, { show: false, data: dateList, gridIndex: 1, }, yAxis: { gridIndex: 1, min: 0, //取0為最小刻度 // max: 1000000, //取100000為最大刻度 }, grid: [ { bottom: "0%", }, { top: "20%", }, ], series: [ { type: "line", showSymbol: false, data: valueList, }, ], }; option && myChart.setOption(option); }, //初始化Websocket--sys_info initWebSocket() { if (typeof WebSocket === "undefined") return console.log("您的瀏覽器不支持websocket"); this.websock = new WebSocket(this.wsUrl); this.websock.onmessage = this.websocketonmessage; this.websock.onopen = this.websocketonopen; this.websock.onerror = this.websocketonerror; this.websock.onclose = this.websocketclose; }, websocketonopen() { // console.log("鏈接建立之后執(zhí)行send方法發(fā)送數(shù)據(jù)"); let action = { message: "sys_info" }; this.websocketsend(JSON.stringify(action)); }, websocketonerror() { //鏈接建立失敗重連 this.initWebSocket(); }, websocketonmessage(e) { //數(shù)據(jù)接收 const redata = JSON.parse(e.data); // console.log("接收的數(shù)據(jù)", redata); this.cpu_info = redata.cpu_info; this.cpuCharts(); this.mem_info = redata.mem_info; this.memoryCharts(); this.disk_info = redata.disk_info; this.hardCharts(); }, websocketsend(Data) { //數(shù)據(jù)發(fā)送 // console.log("數(shù)據(jù)發(fā)送", Data); this.websock.send(Data); }, websocketclose(e) { //關(guān)閉 // console.log("斷開鏈接", e); }, //初始化Websocket--net_info initWebSocketNet() { if (typeof WebSocket === "undefined") return console.log("您的瀏覽器不支持websocket"); this.websockNet = new WebSocket(this.wsUrl); this.websockNet.onmessage = this.websocketonmessageNet; this.websockNet.onopen = this.websocketonopenNet; this.websockNet.onerror = this.websocketonerrorNet; this.websockNet.onclose = this.websocketcloseNet; }, websocketonopenNet() { // console.log("鏈接建立之后執(zhí)行send方法發(fā)送數(shù)據(jù)"); let action = { message: "net_info" }; this.websocketsendNet(JSON.stringify(action)); }, websocketonerrorNet() { //鏈接建立失敗重連 this.initWebSocketNet(); }, websocketonmessageNet(e) { //數(shù)據(jù)接收 const redata = JSON.parse(e.data); // console.log("net_info接收的數(shù)據(jù)", redata); this.in_out_total = redata.in_out_total; let allRate = 1000 * 1000 * 1000; this.inoutArr = this.inoutArr.concat( (redata.in_out_total / allRate).toFixed(2) ); this.card_info = redata.card_info; this.lineCharts(); }, websocketsendNet(Data) { //數(shù)據(jù)發(fā)送 // console.log("數(shù)據(jù)發(fā)送", Data); this.websockNet.send(Data); }, websocketcloseNet(e) { //關(guān)閉 // console.log("斷開鏈接", e); }, WayMethods(item, type) { let arr = Object.keys(item); // console.log("arr", item, arr); if (type == "incoming") { if (item[arr[0]].incoming <= 1000) { return item[arr[0]].incoming + "bit/s"; } else if ( item[arr[0]].incoming > 1000 && item[arr[0]].incoming <= 1000 * 1000 ) { return (item[arr[0]].incoming / 1000).toFixed(2) + "Kb/s"; } else if ( item[arr[0]].incoming > 1000 * 1000 && item[arr[0]].incoming <= 1000 * 1000 * 1000 ) { return (item[arr[0]].incoming / (1000 * 1000)).toFixed(2) + "Mb/s"; } else if (item[arr[0]].incoming > 1000 * 1000 * 1000) { return ( (item[arr[0]].incoming / (1000 * 1000 * 1000)).toFixed(2) + "Gb/s" ); } } else if (type == "outgoing") { if (item[arr[0]].outgoing <= 1000) { return item[arr[0]].outgoing + "bit/s"; } else if ( item[arr[0]].outgoing > 1000 && item[arr[0]].outgoing <= 1000 * 1000 ) { return (item[arr[0]].outgoing / 1000).toFixed(2) + "Kb/s"; } else if ( item[arr[0]].outgoing > 1000 * 1000 && item[arr[0]].outgoing <= 1000 * 1000 * 1000 ) { return (item[arr[0]].outgoing / (1000 * 1000)).toFixed(2) + "Mb/s"; } else if (item[arr[0]].outgoing > 1000 * 1000 * 1000) { return ( (item[arr[0]].outgoing / (1000 * 1000 * 1000)).toFixed(2) + "Gb/s" ); } } else { return item[arr[0]][type]; } }, }, }; </script> <style lang="scss" scoped> .homePage { display: flex; flex-direction: column; .topArea { display: flex; justify-content: space-between; .el-card { width: 100%; background: #fbfdff; ::v-deep .el-card__header { padding: 0 !important; z-index: 9; position: relative; } ::v-deep .el-card__body { padding: 0 !important; } .headerBox { position: relative; width: 100%; height: 39px; z-index: 9; background: #fff !important; .arrow { position: absolute; top: 0.6875rem; left: 0.5rem; img { width: 1rem; height: 1rem; } } .title { position: absolute; top: 0.687rem; left: 1.625rem; font-weight: bolder; color: #2d3d59; font-size: 1rem; font-family: SourceHanSansCN; } .topRight { position: absolute; bottom: -0.3rem; right: 0; img { width: 2.1875rem; height: 0.3125rem; } } } .myCont { // border: 1px solid blue; width: 100%; display: flex; background: #fbfdff; margin-top: 1rem; margin-bottom: 1rem; .itemBox { width: 32.5625rem; height: 21.75rem; // border: 1px solid red; display: flex; flex-direction: column; .titleBox { height: 2rem; display: flex; span img { margin-top: 0.125rem; width: 1rem; height: 1rem; } .title { margin-left: 0.625rem; font-size: 1rem; font-family: SourceHanSansCN; font-weight: bolder; color: #2d3d59; } } .board { width: 29.5625rem; height: 18.75rem; background: #f3f7ff; box-shadow: inset 0px 0.25rem 0.25rem 0px rgba(92, 127, 252, 0.12); border-radius: 0.25rem; opacity: 1; display: flex; .left { width: 15rem; height: 12.5rem; margin-top: 3.125rem; margin-left: 0.875rem; } .right { width: 15.1875rem; // border: 1px solid blue; margin-top: 3.125rem; position: relative; .tipBox { width: 11.9375rem; height: 4.875rem; display: flex; justify-content: space-between; // border: 1px solid red; position: absolute; top: 1.125rem; left: 1.375rem; span { &:nth-child(1) { font-size: 0.875rem; font-family: SourceHanSansCN; font-weight: bold; color: #413f3f; } &:nth-child(2) { font-size: 1.5rem; font-family: D-DIN-DIN-Bold, D-DIN-DIN; font-weight: bold; color: #0082fa; margin-top: -0.5rem; } } } .detailBox { position: absolute; top: 5rem; left: 1.375rem; display: flex; flex-direction: column; // border: 1px solid salmon; width: 11.9375rem; div { height: 1.75rem; display: flex; position: relative; span { // border: 1px solid red; &:nth-child(1) { width: 0.375rem; height: 0.375rem; border-radius: 0.1875rem; background: #00b42a; opacity: 1; position: absolute; top: 0.5rem; left: 0; } &:nth-child(2) { font-size: 0.8125rem; font-family: SourceHanSansCN; font-weight: 400; color: #413f3f; position: absolute; top: 0.25rem; left: 0.625rem; } &:nth-child(3) { font-size: 0.8125rem; font-family: SourceHanSansCN; font-weight: 400; color: #413f3f; position: absolute; top: 0.25rem; right: 0rem; } } } } .otherBox { display: flex; flex-direction: column; position: absolute; top: 0; left: 1.375rem; height: 4.875rem; width: 100%; // border: 1px solid blue; .tipBox2 { width: 11.9375rem; height: 2.4375rem; display: flex; justify-content: space-between; // border: 1px solid red; span { &:nth-child(1) { font-size: 0.875rem; font-family: SourceHanSansCN; font-weight: bold; color: #413f3f; display: block; } &:nth-child(2) { font-size: 1.5rem; font-family: D-DIN-DIN-Bold, D-DIN-DIN; font-weight: bold; color: #0082fa; margin-top: -0.35rem; } &:nth-child(3) { font-size: 1rem; font-family: D-DIN-DIN-Bold, D-DIN-DIN; font-weight: bold; color: #0082fa; margin-top: -0.05rem; } } } } } } &:nth-child(1) { margin-left: 1.6875rem; } &:nth-child(2) { margin-left: 2.625rem; } &:nth-child(3) { margin-left: 2.625rem; } } } } } .bottomArea { margin-top: 1rem; .el-card { .myCont { height: 19rem; display: flex; .Throughput { width: 36.875rem; display: flex; flex-direction: column; .titleBox { margin-top: 2.5rem; margin-left: 1.5rem; position: relative; height: 2rem; span { position: absolute; top: 0; left: 0; img { width: 1rem; height: 1rem; } } .title { position: absolute; top: 0; left: 1.5rem; font-size: 0.875rem; font-family: SourceHanSansCN; font-weight: 400; color: #2d3d59; } } .lineBox { width: 31.25rem; height: 12.5rem; margin-left: 1.6875rem; // border: 1px solid red; background: #fefbff; } .lineTips { margin-left: 1.6875rem; background: #fefbff; width: 31.25rem; span { img { width: 1rem; height: 1rem; } &:nth-child(1) { margin-top: 0.25rem; } &:nth-child(2) { font-size: 0.875rem; font-family: SourceHanSansCN; font-weight: 400; color: #413f3f; margin: 0rem 0.5rem; } &:nth-child(3) { font-size: 1rem; font-family: D-DIN-DIN-Bold, D-DIN-DIN; font-weight: bold; color: #413f3f; } &:nth-child(4) { font-size: 1rem; font-family: D-DIN-DIN-Bold, D-DIN-DIN; font-weight: bold; color: #413f3f; } } } } .rightArea { // border: 1px solid blue; width: 64.8125rem; display: flex; .Item { width: 14rem; height: 16.125rem; margin-top: 2.5rem; margin-right: 3rem; // border: 1px solid red; opacity: 1; display: flex; flex-direction: column; &:nth-child(4) { margin-right: 0rem; } .topBox { position: relative; background: #f2f3fb !important; height: 5.875rem; z-index: 9; border-radius: 0.25rem; .imgBox { position: absolute; top: 0.875rem; left: 1rem; img { width: 4.125rem; height: 4.125rem; } } .portTip { position: absolute; top: 0.75rem; left: 5.875rem; font-size: 1rem; font-family: SourceHanSansCN; font-weight: 500; color: #413f3f; } .transferBox { span { img { width: 1rem; height: 1rem; } } .Num { font-size: 0.875rem; font-family: SourceHanSansCN; font-weight: 500; color: #7c818d; } } .transferBoxT { position: absolute; top: 2.5rem; left: 5.875rem; } .transferBoxB { position: absolute; top: 3.8125rem; left: 5.875rem; } } .bottomBox { background: #fefbff; // border: 1px solid orange; margin-top: 1.5rem; display: flex; flex-direction: column; div { display: flex; font-size: 0.875rem; font-family: SourceHanSansCN; font-weight: 400; color: #413f3f; line-height: 1.75rem; span { &:nth-child(1) { margin-right: 0.5rem; } } } } } } } } } } </style>
總結(jié)
到此這篇關(guān)于Vue項(xiàng)目中Websocket使用的文章就介紹到這了,更多相關(guān)Vue里Websocket的使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
ElementPlus el-message-box樣式錯(cuò)位問題及解決
這篇文章主要介紹了ElementPlus el-message-box樣式錯(cuò)位問題及解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09Vue實(shí)現(xiàn)Tab標(biāo)簽路由效果并用Animate.css做轉(zhuǎn)場動(dòng)畫效果的代碼
這篇文章主要介紹了Vue實(shí)現(xiàn)Tab標(biāo)簽路由效果,并用Animate.css做轉(zhuǎn)場動(dòng)畫效果,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07Vue Element使用icon圖標(biāo)教程詳解(第三方)
element-ui自帶的圖標(biāo)庫不夠全,還是需要需要引入第三方icon。下面小編給大家?guī)砹薞ue Element使用icon圖標(biāo)教程,感興趣的朋友一起看看吧2018-02-02輕量級富文本編輯器wangEditor結(jié)合vue使用方法示例
在我們項(xiàng)目中,有些時(shí)候需要使用富文本編輯器。本文將以百度開發(fā)的Ueditor結(jié)合Vue.js介紹一下。非常具有實(shí)用價(jià)值,需要的朋友可以參考下2018-10-10使用electron打包Vue前端項(xiàng)目的詳細(xì)流程
這篇文章主要介紹了使用electron打包Vue前端項(xiàng)目的詳細(xì)流程,文中通過圖文結(jié)合的方式給大家介紹的非常詳細(xì),對大家學(xué)習(xí)electron打包Vue有一定的幫助,需要的朋友可以參考下2024-04-04