Vue2集成ElementUI實(shí)現(xiàn)左側(cè)菜單導(dǎo)航功能
簡(jiǎn)介
在開發(fā)后臺(tái)系統(tǒng)時(shí),通過(guò)菜單進(jìn)行導(dǎo)航是非常重要的一件事情,在前端開發(fā)過(guò)程中使用vue2+elementui可以快速搭建菜單導(dǎo)航,本文主要記錄兩個(gè)菜單的生成方式,通過(guò)在前端router/index.js中直接進(jìn)行配置,后端返回菜單數(shù)據(jù)進(jìn)行對(duì)應(yīng),可以通過(guò)后端返回的菜單數(shù)據(jù)控制權(quán)限;另一種是部門靜態(tài)導(dǎo)航,然后再拼接動(dòng)態(tài)導(dǎo)航,生成完成頁(yè)面導(dǎo)航。
靜態(tài)導(dǎo)航
安裝element-ui,vue-router,vuex
npm install elementui --S npm install vue-router@3 --S npm install vuex --S
編寫router/index.js
router/index.js
import Vue from 'vue'; import Router from 'vue-router'; Vue.use(Router); const router = new Router({ routes: [ { path: '/', name: 'Home', component: () => import('@/views/Home.vue'), children: [ { path: '/index', name: 'Index', component: () => import('@/views/Index.vue'), }, { path: '/documents/note', name: 'NoteManagement', component: () => import('@/views/NoteManagement.vue'), }, { path: '/documents/file', name: 'FileManagement', component: () => import('@/views/FileManagement.vue'), }, { path: '/documents/newMarkdown', name: 'NewDocument', component: () => import('@/components/RichTextEditor.vue'), // 新增路由指向RichTextEditor.vue }, { path: '/documents/newWord', name: 'NewWord', component: () => import('@/components/WordEditor.vue'), }, { path: '/documents/newExcel', name: 'NewExcel', component: () => import('@/components/ExcelEditor.vue'), }, { path: '/system/user', name: 'UserManagement', component: () => import('@/views/UserManagement.vue'), }, { path: '/system/menu', name: 'MenuManagement', component: () => import('@/views/MenuManagement.vue'), }, { path: '/system/role', name: 'RoleManagement', component: () => import('@/views/RoleManagement.vue'), }, { path: 'system/company', name: 'CompanyManagement', component: () => import('@/views/CompanyManagement.vue'), }, { path: '/system/dept', name: 'DeptManagement', component: () => import('@/views/DeptManagement.vue'), }, { path: '/target', name: 'TargetManagement', component: () => import('@/views/TargetManage.vue'), }, { path: '/targetTask', name: 'TargetTask', component: () => import('@/views/TargetTask.vue'), // 新增路由指向MonthTask.vue }, { path: '/dayTask', name: 'DayTask', component: () => import('@/views/DayTask.vue'), // 新增路由指向DayTask.vue } ] }, { path: '/login', name: 'Login', component: () => import('@/views/Login.vue'), }, { path: '/register', name: 'Register', component: () => import('@/views/Register.vue'), // 更新注冊(cè)路由 }, ], }); // 導(dǎo)航守衛(wèi) // 使用 router.beforeEach 注冊(cè)一個(gè)全局前置守衛(wèi),判斷用戶是否登陸 router.beforeEach((to, from, next) => { if (to.path === '/login') { next(); } else { let token = localStorage.getItem('Authorization'); if (token === null || token === '') { next('/login'); } else { next(); } } }); export default router;
main.js中引入elementui,router
main.js
import Vue from 'vue' import App from './App.vue' import ElementUI from 'element-ui' import 'element-ui/lib/theme-chalk/index.css' import store from './store' import router from './router/index' // import mavonEditor from 'mavon-editor' // import 'mavon-editor/dist/css/index.css'; // import mermaidItMarkdown from 'mermaid-it-markdown' // mavonEditor.mavonEditor.getMarkdownIt().use(mermaidItMarkdown) // Vue.use(mavonEditor) Vue.config.productionTip = false Vue.use(ElementUI) new Vue({ store, router, render: h => h(App), }).$mount('#app')
編寫左側(cè)導(dǎo)航
<!-- 第二部分:導(dǎo)航欄和內(nèi)容顯示區(qū)域 --> <div class="main-content"> <el-menu :default-active="activeMenu" @select="handleMenuSelect" background-color="#545c64" text-color="#fff" active-text-color="#ffd04b" :collapse="isCollapse" > <el-menu-item v-for="item in filteredMenuItems" :key="item.menuPath" :index="item.menuPath" > <i :class="item.menuIcon"></i> <span slot="title">{{ item.menuName }}</span> </el-menu-item> <el-submenu v-for="item in menuItemsWithChildren" :key="item.menuPath" :index="item.menuPath" > <template #title> <i :class="item.menuIcon"></i> <span slot="title">{{ item.menuName }}</span> </template> <el-menu-item v-for="child in item.children" :key="child.menuPath" :index="child.menuPath" > <i :class="child.menuIcon"></i> <span slot="title">{{ child.menuName }}</span> </el-menu-item> </el-submenu> </el-menu> //路由出口 <div class="content"> <router-view></router-view> </div> </div>
返回的菜單數(shù)據(jù)
菜單數(shù)據(jù)時(shí)根據(jù)用戶id請(qǐng)求后端菜單權(quán)限后返回的菜單數(shù)據(jù)
動(dòng)態(tài)導(dǎo)航
安裝vue-router、elementui步驟與靜態(tài)導(dǎo)航相同
編寫router/index.js
import Vue from "vue"; import VueRouter from "vue-router"; Vue.use(VueRouter); const constantRoutes = [ { path: "/login", name: "Login", component: () => import("@/views/Login.vue") }, { path: "/home", name: "Home", component: () => import("@/views/Home.vue"), children: [] }, // { // path: "*", // name: "NotFound", // component: () => import("@/views/NotFound.vue") // }, ] const createRouter = () => new VueRouter({ mode: "hash", routes: constantRoutes }) const router = createRouter(); //路由重置方法 export function resetRouter() { const newRouter = createRouter(); router.matcher = newRouter.matcher; // 重置路由 } //動(dòng)態(tài)加載路由方法 export const addDynamicRoutes = (menus) => { debugger; const routes = []; //1.轉(zhuǎn)換菜單為路由配置 const asyncRoutes = coverMenusToRoutes1(routes,menus); //2. 添加嵌套路由到Home asyncRoutes.forEach(route => { // debugger; // if (route.name !== '') { // router.addRoute("Home", route); // } router.addRoute("Home", route); }); } //菜單轉(zhuǎn)換路由方法 const coverMenusToRoutes = (menus) => { if (!menus) return []; const routes = []; menus.forEach(menu => { const route = { path: menu.path, name: menu.path.slice(1), meta: {title: menu.name,icon: menu.icon}, component: resolveComponent(menu.component), }; if (menu.children && menu.children.length > 0) { route.children = coverMenusToRoutes(menu.children); } routes.push(route); }) return routes; } const coverMenusToRoutes1 = (routes,menus) => { if (!menus) return []; // const routes = []; menus.forEach(menu => { if (menu.component.length > 0){ const route = { path: menu.path, name: menu.path.slice(1), meta: {title: menu.name,icon: menu.icon}, component: resolveComponent(menu.component), }; routes.push(route); } if (menu.children && menu.children.length > 0) { coverMenusToRoutes1(routes,menu.children); } }) return routes; } //動(dòng)態(tài)解析組件路由 function resolveComponent(component) { if (!component) return undefined; return () => import(`@/views/${component}`); } // 導(dǎo)航守衛(wèi) // 使用 router.beforeEach 注冊(cè)一個(gè)全局前置守衛(wèi),判斷用戶是否登陸 router.beforeEach((to, from, next) => { if (to.path === '/login') { next(); } else { let token = localStorage.getItem('token'); if (token === null || token === '') { next('/login'); } else { next(); } } }); export default router;
動(dòng)態(tài)導(dǎo)航需要特別注意路徑問(wèn)題,如果路徑不正確會(huì)導(dǎo)致菜單無(wú)法正常顯示,因?yàn)樵陧?xiàng)目中返回的菜單數(shù)據(jù)時(shí)樹形結(jié)構(gòu),在處理菜單數(shù)據(jù)時(shí)如果按樹形結(jié)構(gòu)嵌套再添加到Home路由的children列表中,菜單無(wú)法正常的顯示,后面修改了處理邏輯,把有組件的菜單添加到Home路由的children列表后,菜單可以正常顯示,需要特別注意
左側(cè)菜單
通過(guò)for循環(huán)生成
<template> <el-menu :default-active="defaultActive" class="el-menu" @open="handleOpen" @close="handleClose" @select="handleSelect" :collapse="isCollapse" background-color="#545c64" text-color="#fff" active-text-color="#ffd04b" > <span><i :class="collapseClass" @click="changeMenu"></i></span> <template v-for="item in menuList"> <el-submenu v-if="item.children && item.children.length" :index="item.path" :key="item.id" > <template slot="title"> <i :class="item.icon"></i> <span slot="title">{{ item.name }}</span> </template> <template v-for="child in item.children"> <el-submenu v-if="child.children && child.children.length" :index="child.path" :key="child.id"> <template slot="title"> <i :class="child.icon"></i> <span slot="title">{{child.name}}</span> </template> <el-menu-item v-for="ch in child.children" :index="ch.path" :key="ch.id"> <i :class="ch.icon"></i> <span slot="title">{{ch.name}}</span> </el-menu-item> </el-submenu> <!-- v-for="child in item.children" --> <el-menu-item v-else :index="child.path" :key="child.id" > <i :class="child.icon"></i> <span slot="title">{{ child.name }}</span> </el-menu-item> </template> </el-submenu> <el-menu-item v-else :index="item.path" :key="item.id"> <i :class="item.icon"></i> <span slot="title">{{ item.name }}</span> </el-menu-item> </template> </el-menu> </template> <script> export default { data() { return { collapseClass: "el-icon-s-fold", isCollapse: false, defaultActive: "1-4-1", menuList: [], }; }, mounted() { //獲取動(dòng)態(tài)菜單 this.createMenuList(); }, methods: { createMenuList() { console.log(this.$store.state.menus); this.menuList = this.$store.state.menus; }, handleOpen(key, keyPath) { console.log(key, keyPath); }, handleClose(key, keyPath) { console.log(key, keyPath); }, changeMenu() { this.isCollapse = !this.isCollapse; if (this.isCollapse) { this.collapseClass = "el-icon-s-unfold"; } else { this.collapseClass = "el-icon-s-fold"; } }, handleSelect(index) { this.activeMenu = index; if (this.$route.path !== index) { // 檢查當(dāng)前路徑是否與目標(biāo)路徑相同 this.$router.push(index); } }, }, }; </script> <style> .el-menu:not(.el-menu--collapse) { width: 220px; /* height: 100vh; */ overflow: hidden; } .el-menu { width: 60px; /* height: 100vh; */ overflow: hidden; } </style>
通過(guò)for循環(huán)+遞歸生成
菜單生成子組件
<template> <el-menu :default-active="defaultActive" class="el-menu" @open="handleOpen" @close="handleClose" @select="handleSelect" :collapse="isCollapse" background-color="#545c64" text-color="#fff" active-text-color="#ffd04b" > <template v-for="item in menuList"> <el-submenu v-if="item.children && item.children.length" :index="item.path" :key="item.id"> <template slot="title"> <i :class="item.icon"></i> <span slot="title">{{item.name}}</span> </template> <!-- 遞歸調(diào)用 --> <AsideMenu :menuList="item.children"></AsideMenu> </el-submenu> <el-menu-item v-else :index="item.path" :key="item.id"> <i :class="item.icon"></i> <span slot="title">{{item.name}}</span> </el-menu-item> </template> </el-menu> </template> <script> export default { name: "AsideMenu", //name必須要有,要和遞歸調(diào)用的名稱保持一致 components: { }, props: { menuList: [], // eslint-disable-next-line vue/require-prop-type-constructor isCollapse: false, }, data() { return { // collapseClass: "el-icon-s-fold", // isCollapse: false, defaultActive: "1-4-1", }; }, methods: { handleOpen(key, keyPath) { console.log(key, keyPath); }, handleClose(key, keyPath) { console.log(key, keyPath); }, handleSelect(index) { debugger; this.activeMenu = index; console.log(index); console.log(this.$route); console.log(this.$router.getRoutes()); if (this.$route.path !== index) { // 檢查當(dāng)前路徑是否與目標(biāo)路徑相同 this.$router.push(index); } }, }, }; </script> <style> .el-menu:not(.el-menu--collapse) { width: 220px; /* height: 100vh; */ overflow: hidden; border-right: none; /* 隱藏右側(cè)的邊框 */ } .el-menu { width: 60px; /* height: 100vh; */ overflow: hidden; border-right: none; } </style>
子組件名稱是必須要有的,遞歸調(diào)用時(shí)按照名稱進(jìn)行遞歸調(diào)用。在這個(gè)項(xiàng)目中子組件名稱為:AsideMenu,遞歸調(diào)用時(shí)使用 AsideMenu來(lái)引用自身
調(diào)用菜單生成的父組件
<template> <div class="sidebar"> <span><i :class="collapseClass" @click="changeMenu"></i></span> <!-- 調(diào)用菜單生成組件 --> <aside-menu :menuList="menuList" :isCollapse="isCollapse" /> </div> </template> <script> import AsideMenu from '@/components/AsideMenu.vue'; export default { components: { AsideMenu }, data() { return { collapseClass: "el-icon-s-fold", isCollapse: false, menuList: [] }; }, mounted() { //獲取動(dòng)態(tài)菜單 this.createMenuList(); }, methods: { createMenuList() { console.log(this.$store.state.menus); this.menuList = this.$store.state.menus; }, changeMenu() { this.isCollapse = !this.isCollapse; if (this.isCollapse) { this.collapseClass = "el-icon-s-unfold"; } else { this.collapseClass = "el-icon-s-fold"; } }, } }; </script> <style scoped> .sidebar { /* border: 1px solid red; */ background-color:#545c64; } </style>
store/index.js
使用vuex保存用戶id,token,菜單列表,權(quán)限信息,角色信息
import Vue from "vue"; import vuex from "vuex"; Vue.use(vuex); const store = new vuex.Store({ state: { //用戶id userId: {}, //用戶token token: "", //用戶角色 role: "", //用戶權(quán)限 permission: "", //用戶菜單 menus: [], //用戶路由 }, getters: { //獲取用戶id getUserId(state) { return state.userId; }, //獲取用戶token getToken(state) { return state.token; }, //獲取用戶角色 getRole(state) { return state.role; }, //獲取用戶權(quán)限 getPermission(state) { return state.permission; }, //獲取用戶菜單 getMenus(state) { return state.menus; }, }, mutations: { //設(shè)置用戶id setUserId(state, userId) { state.userId = userId; localStorage.setItem("userId", userId); }, //設(shè)置用戶token setToken(state, token) { state.token = token; localStorage.setItem("token", token); }, //設(shè)置用戶角色 setRole(state, role) { state.role = role; }, //設(shè)置用戶權(quán)限 setPermission(state, permission) { state.permission = permission; }, //設(shè)置用戶菜單 setMenus(state, menus) { state.menus = menus; localStorage.setItem("menus", menus); }, } }) export default store;
main.js中引入store
import Vue from 'vue' import App from './App.vue' import ElementUI from 'element-ui' import 'element-ui/lib/theme-chalk/index.css' import router from './router' import store from './store' Vue.use(ElementUI) Vue.config.productionTip = false new Vue({ store, router, render: h => h(App), }).$mount('#app')
登錄頁(yè)面代碼
登錄頁(yè)面存儲(chǔ)用戶信息、菜單信息、并動(dòng)態(tài)加載路由
<!-- eslint-disable vue/multi-word-component-names --> <template> <el-row type="flex" justify="center" align="middle" style="height: 100vh;"> <el-col :xs="24" :sm="12" :md="8" :lg="6"> <el-card class="box-card"> <div class="clearfix"> <img src="@/assets/logo.png" class="logo" /> <h2>歡迎登錄</h2> </div> <el-form :model="loginForm" ref="loginForm" :rules="loginRules" label-width="100px"> <el-form-item label="用戶名" prop="username"> <el-input v-model="loginForm.username" prefix-icon="el-icon-user" autocomplete="off"></el-input> </el-form-item> <el-form-item label="密碼" prop="password"> <el-input type="password" v-model="loginForm.password" prefix-icon="el-icon-lock" show-password autocomplete="off"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="submitForm">登錄</el-button> <el-button @click="resetForm">重置</el-button> </el-form-item> </el-form> </el-card> </el-col> </el-row> </template> <script> import { Message } from 'element-ui'; import http from '../request/http' import { resetRouter,addDynamicRoutes } from '@/router/index' export default { data() { return { loginForm: { username: '', password: '' }, loginRules: { username: [{ required: true, message: '請(qǐng)輸入用戶名', trigger: 'blur' }], password: [{ required: true, message: '請(qǐng)輸入密碼', trigger: 'blur' }] } }; }, methods: { submitForm() { this.$refs.loginForm.validate((valid) => { if (valid) { // 這里可以添加提交到服務(wù)器的邏輯 http.post('/user/login',this.loginForm,{ headers: { "Content-Type": "application/json;charset=UTF-8", }, }).then((res) => { if (res.data.code === 200) { // 登錄成功,可以進(jìn)行后續(xù)操作,如跳轉(zhuǎn)到主頁(yè) //保存用戶id、token、菜單列表 // console.log(res.data.data); const userId = res.data.data.user.id; const token = res.data.data.user.token; this.$store.commit('setUserId', userId); this.$store.commit('setToken', token); this.$store.commit('setMenus', res.data.data.menus); //創(chuàng)建動(dòng)態(tài)路由 //1.重置路由 resetRouter(); //2.添加動(dòng)態(tài)路由 const menus = res.data.data.menus; addDynamicRoutes(menus); this.$router.push('/home'); } else { // 登錄失敗,可以提示錯(cuò)誤信息 Message.error(res.msg); } }); } else { console.log('表單驗(yàn)證失?。?); return false; } }); }, resetForm() { this.$refs.loginForm.resetFields(); } } }; </script> <style scoped> .box-card { /* border: 1px solid red; */ width: 100%; /* 或者具體寬度 */ border-radius: 10px; /* 圓角 */ box-shadow: 0 0 10px rgba(0,0,0,0.1); /* 陰影 */ background-color:aliceblue; } .el-row { background-image: url('../assets/pic01.jpg'); background-size: cover; background-position: center; background-repeat: no-repeat; } .logo { width: 80px; height: 80px; } </style>
菜單返回?cái)?shù)據(jù)
{ "code": 200, "message": "請(qǐng)求成功", "data": { "menus": [ { "id": "1913479834787434497", "parentId": null, "name": "系統(tǒng)管理", "path": "", "component": "", "perms": null, "type": 1, "icon": "el-icon-s-tools", "orderNum": 0, "visible": false, "createTime": null, "updateTime": null, "rf1": null, "rf2": null, "rf3": null, "rf4": null, "rf5": null, "children": [ { "id": "1913484019050274818", "parentId": "1913479834787434497", "name": "菜單管理", "path": "/menu", "component": "MenuManage.vue", "perms": null, "type": 1, "icon": "el-icon-menu", "orderNum": 0, "visible": false, "createTime": null, "updateTime": null, "rf1": "系統(tǒng)管理", "rf2": null, "rf3": null, "rf4": null, "rf5": null, "children": null }, { "id": "1913488214084083714", "parentId": "1913479834787434497", "name": "二級(jí)菜單", "path": "", "component": "", "perms": null, "type": 1, "icon": "el-icon-location", "orderNum": 1, "visible": false, "createTime": null, "updateTime": null, "rf1": "系統(tǒng)管理", "rf2": null, "rf3": null, "rf4": null, "rf5": null, "children": [ { "id": "1913488799369846786", "parentId": "1913488214084083714", "name": "三級(jí)菜單", "path": "/san", "component": "SanManage.vue", "perms": null, "type": 1, "icon": "el-icon-star-on", "orderNum": 0, "visible": false, "createTime": null, "updateTime": null, "rf1": "二級(jí)菜單", "rf2": null, "rf3": null, "rf4": null, "rf5": null, "children": null } ] } ] } ], "user": { "id": "123456", "username": "admin", "password": "$2a$10$0uPlhwgy.OlkV20pRJ/9Wu8OJ61OfbcMqMXf60qI4qsahlxJD4iUq", "nickname": "wangcheng", "avatar": null, "email": null, "mobile": null, "status": 1, "deptId": null, "createTime": null, "updateTime": null, "token": "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIzMWMwOTgzNzQ2MTQ0ZGNiYmJhZTgwZmJhYzNkNWFjMSIsImlhdCI6MTc0NTE5NjAxNCwic3ViIjoiMTIzNDU2IiwiZXhwIjoxNzQ1ODAwODE0fQ.OyZaKaHRfu0PfMSubrnU1qLDOQHfisdQkTvByCMeIes", "roles": null } } }
總結(jié)
項(xiàng)目開發(fā)過(guò)程中動(dòng)態(tài)菜單生成、動(dòng)態(tài)路由的正確配置是困難點(diǎn)。
動(dòng)態(tài)菜單的遞歸調(diào)用
遞歸調(diào)用最主要的是對(duì)自身的調(diào)用,要保持名稱和調(diào)用自身組件的一致性。
動(dòng)態(tài)路由
動(dòng)態(tài)路由要注意路徑問(wèn)題,不要因?yàn)椴藛畏祷貥湫谓Y(jié)構(gòu),后期處理的路由也是樹形結(jié)構(gòu),造成子路由里面多層嵌套,無(wú)法正常渲染菜單。
記錄菜單處理的另外一種方式
MenuTreeOne.vue
<template> <div class="custom-menu-tree"> <template v-for="item in menuList"> <el-submenu v-if="item.children && item.children.length" :index="item.path" :key="item.id" > <template slot="title"> <i :class="item.icon"></i> <span slot="title">{{ item.name }}</span> </template> <!-- 遞歸調(diào)用 --> <AsideMenuOne :menuList="item.children"></AsideMenuOne> </el-submenu> <el-menu-item v-else :index="item.path" :key="item.id"> <i :class="item.icon"></i> <span slot="title">{{ item.name }}</span> </el-menu-item> </template> </div> </template> <script> export default { name: "AsideMenuOne", props: { menuList: [], }, data() { return {}; }, mounted() {}, methods: {}, }; </script> <style scoped> .custom-menu-tree { height: 100%; display: flex; flex-direction: column; } </style>
AsideMenuOne.vue
<template> <el-menu :default-active="defaultActive" class="el-menu" @open="handleOpen" @close="handleClose" @select="handleSelect" :collapse="isCollapse" background-color="#545c64" text-color="#fff" active-text-color="#ffd04b" > <span><i :class="collapseClass" @click="changeMenu"></i></span> <menu-tree-one :menuList="menuList"></menu-tree-one> </el-menu> </template> <script> import MenuTreeOne from '@/components/MenuTreeOne.vue'; export default { components: { MenuTreeOne }, data() { return { collapseClass: "el-icon-s-fold", isCollapse: false, defaultActive: "1-4-1", menuList: [], }; }, mounted() { //獲取動(dòng)態(tài)菜單 this.createMenuList(); }, methods: { createMenuList() { console.log(this.$store.state.menus); this.menuList = this.$store.state.menus; }, handleOpen(key, keyPath) { console.log(key, keyPath); }, handleClose(key, keyPath) { console.log(key, keyPath); }, changeMenu() { this.isCollapse = !this.isCollapse; if (this.isCollapse) { this.collapseClass = "el-icon-s-unfold"; } else { this.collapseClass = "el-icon-s-fold"; } }, handleSelect(index) { this.activeMenu = index; if (this.$route.path !== index) { // 檢查當(dāng)前路徑是否與目標(biāo)路徑相同 this.$router.push(index); } }, }, }; </script> <style> .el-menu:not(.el-menu--collapse) { width: 220px; /* height: 100vh; */ overflow: hidden; } .el-menu { width: 60px; /* height: 100vh; */ overflow: hidden; } </style>
到此這篇關(guān)于Vue2集成ElementUI實(shí)現(xiàn)左側(cè)菜單導(dǎo)航功能的文章就介紹到這了,更多相關(guān)Vue ElementUI左側(cè)菜單導(dǎo)航內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue-router實(shí)現(xiàn)嵌套路由的講解
今天小編就為大家分享一篇關(guān)于vue-router實(shí)現(xiàn)嵌套路由的講解,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-01-01vue中vue-router的使用說(shuō)明(包括在ssr中的使用)
這篇文章主要介紹了vue中vue-router的使用說(shuō)明(包括在ssr中的使用),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-05-05vue動(dòng)態(tài)子組件的兩種實(shí)現(xiàn)方式
這篇文章主要介紹了vue動(dòng)態(tài)子組件的兩種實(shí)現(xiàn)方式,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-09-09手把手教你Vue3實(shí)現(xiàn)路由跳轉(zhuǎn)
Vue Router是Vue.js的官方路由器,它與Vue.js核心深度集成,使使用Vue.js構(gòu)建單頁(yè)應(yīng)用程序變得輕而易舉,下面這篇文章主要給大家介紹了關(guān)于Vue3實(shí)現(xiàn)路由跳轉(zhuǎn)的相關(guān)資料,需要的朋友可以參考下2022-08-08vue實(shí)現(xiàn)圖片下載點(diǎn)擊按鈕彈出本地窗口選擇自定義保存路徑功能
vue前端實(shí)現(xiàn)前端下載,并實(shí)現(xiàn)點(diǎn)擊按鈕彈出本地窗口,選擇自定義保存路徑,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2023-12-12Vue中scrollIntoView()方法詳解與實(shí)際運(yùn)用舉例
這篇文章主要給大家介紹了關(guān)于Vue中scrollIntoView()方法詳解與實(shí)際運(yùn)用舉例的相關(guān)資料,該scrollIntoView()方法將調(diào)用它的元素滾動(dòng)到瀏覽器窗口的可見區(qū)域,需要的朋友可以參考下2023-12-12vue進(jìn)行下載與處理二進(jìn)制流文件的方法詳解
這篇文章主要為大家詳細(xì)介紹了vue如何實(shí)現(xiàn)將后端返回的二進(jìn)制流進(jìn)行處理并實(shí)現(xiàn)下載,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-12-12vue組件實(shí)現(xiàn)可搜索下拉框擴(kuò)展
這篇文章主要為大家詳細(xì)介紹了vue組件實(shí)現(xiàn)可搜索下拉框的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-06-06