亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Vue如何根據(jù)角色獲取菜單動(dòng)態(tài)添加路由

 更新時(shí)間:2024年01月15日 11:22:28   作者:劫辭  
這篇文章主要介紹了Vue如何根據(jù)角色獲取菜單動(dòng)態(tài)添加路由,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧

如果大家寫過后臺(tái)管理系統(tǒng)的項(xiàng)目,那么動(dòng)態(tài)路由一定是繞不開的,如果想偷懶的話,就把所有路由一開始都配置好,然后只根據(jù)后端返回的菜單列表渲染就好菜單就好了,但是這樣的隱患就是我在地址欄輸入的地址的時(shí)候,也會(huì)進(jìn)入這個(gè)頁面,不偷懶的方法就是本文要介紹的,真動(dòng)態(tài)路由了,當(dāng)然不會(huì)僅僅只是介紹使用數(shù)據(jù)怎么換成動(dòng)態(tài)路由添加就好了,會(huì)從登錄獲取token后請(qǐng)求菜單列表…最后注冊(cè)完成,這一系列流程完整的實(shí)現(xiàn)一次,相信對(duì)于第一次接觸這個(gè)案例的朋友會(huì)有幫助

前提提要

  • 本文有些東西我不會(huì)詳細(xì)的說,比如后端部分,前端代理啊,基于 element-ui 的遞歸菜單封裝等其他組件使用等等,我不會(huì)在做額外的贅述了,后端這個(gè)流程包裹這些封裝,后面我會(huì)單獨(dú)開一篇文章來說明
  • 前端 vue 項(xiàng)目結(jié)構(gòu)部分也不會(huì)太過詳細(xì)的說明,所以觀看本文還是需要一定的基礎(chǔ),至少知道vue的基礎(chǔ)語法、用過 vue-router 和 vuex 吧,要求還是不高的

需求分析

  • 在實(shí)現(xiàn)我們這個(gè)需求,不難想到主要就是完成登錄,通過登錄獲取到正確的菜單列表,通過菜單列表進(jìn)行渲染
  • 但是完成這個(gè)步驟的話,我們還需要捋一下頁面的關(guān)系,按照我們的開發(fā)時(shí)態(tài)來說,我們啟動(dòng)一個(gè)項(xiàng)目之后,會(huì)通過 http://localhost:8080/ 這樣的一個(gè)地址在瀏覽中打開
  • 打開這個(gè)地址之后,觸發(fā)的是什么路徑,是不是 /,表示根路徑,在后臺(tái)管理系統(tǒng)中,一般這個(gè)跟路徑我們會(huì)映射到什么組件上,是不是 layout 組件,比如這樣的,如圖:

  • 但是這樣的話就和我們的需求有點(diǎn)不一樣了,我們要先登錄啊,都沒登錄怎么能打開這個(gè)呢?所以一把來說,我們一般會(huì)要么把 ‘/’ 的路徑觸發(fā)時(shí),重定向到 ‘/login’,或者在全局路由前置守衛(wèi)中,通過登錄的狀態(tài)來決定是不是跳轉(zhuǎn)到登錄頁,一般我們使用第二種,因?yàn)楹笈_(tái)管理系統(tǒng)中,一定會(huì)有路由權(quán)限的判斷,到時(shí)候一樣會(huì)來改動(dòng)這個(gè),所以選擇后者,至于實(shí)現(xiàn)部分,我們后面再看
  • 完成了上述的操作之后,就是登錄了,登錄之后獲取菜單列表數(shù)據(jù),拿到之后我們就直接注冊(cè)嗎?
  • 我們知道,這種菜單,往往會(huì)有一級(jí)、二級(jí)、三級(jí)等等不同級(jí)別的菜單,而是不是每個(gè)菜單都需要注冊(cè)的呢,其實(shí)不然,我們需要注冊(cè)的僅僅是需要展示的那一部分菜單,比如在我們的案例中,設(shè)備管理是一個(gè)一級(jí)菜單,但是存在子級(jí)菜單,那么此時(shí)這個(gè)設(shè)備管理菜單就是不需要注冊(cè)的,如圖:

  • 所以這一點(diǎn)我們也需要做一下區(qū)分,但是具體注冊(cè)那些呢?這些就還是要在前端先配置好,但是這個(gè)配置不會(huì)是直接配置到 route 中,是一個(gè)映射關(guān)系,比如定義了 a = 組件A,然后依次書寫,把所有會(huì)展示的頁面通過這樣的方式,用一個(gè)文件存儲(chǔ)起來,那么通過后端返回的菜單列表數(shù)據(jù)時(shí),就可以進(jìn)行一個(gè)對(duì)比,篩選,取出符合條件的數(shù)據(jù),組裝成一個(gè)適配業(yè)務(wù)的 route 進(jìn)行注冊(cè)
  • 而通過這樣的匹配,我們最后是可以得到一個(gè)數(shù)組的,[route1, route2, …],得到這個(gè)數(shù)組之后,使用 vueRouter的 addRoute 方法添加即可
  • 這里需要注意的事情是,我所演示的案例中,所有的子組件都是在 main 區(qū)域顯示的,所以我就不需要在去單獨(dú)的關(guān)心這些子組件的層級(jí)關(guān)系了,但是如果某個(gè)項(xiàng)目中的,層級(jí)關(guān)系如圖:

  • 像這種或者更多層級(jí)的,就需要額外處理一下 children 屬性了,但是方法都是差不的,無非就是數(shù)據(jù)處理的時(shí)候多處理一下,而且一般來說就是兩層,最外層第一個(gè) router-view 來展示一級(jí)路由(比如登錄、404、layout),main 區(qū)域的 router-view 展示二級(jí)路由(比如 home、my、user…)
  • 經(jīng)過這個(gè)分析之后,我們就是能確定,我們要做的事情就是,把這些獲取的菜單數(shù)據(jù),來找到對(duì)應(yīng)的組件,并把這些組件添加為 layout 組件的子組件,在 main 區(qū)域展示

具體實(shí)現(xiàn)

配置靜態(tài)路由

根據(jù)上面的粗略的分析,第一步就是創(chuàng)建路由,這一步非常簡單,我直接粘貼代碼了,如下:

import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const router = new VueRouter({
	mode: 'hash',
	routes: []
})
export default router

這就是一個(gè)最基礎(chǔ)的結(jié)構(gòu)了,而在這個(gè)需求中,至少有兩個(gè)路由一定是靜態(tài)的,一個(gè)是 login,一個(gè)是 layout,當(dāng)然通常還有個(gè)一個(gè)任意路由,表示 404,這里我就不寫了,大家有時(shí)間自己添加一下就好,如下:

import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const router = new VueRouter({
	mode: 'hash',
	routes: [
		{
			path: '/',
			name: 'layout',
			component: () => import('@/layout')
		},
		{
			path: '/login',
			name: 'login',
			component: () => import('@/views/login')
		}
	]
})
export default router

添加兩個(gè)靜態(tài)路由非常簡單吧,然后把這個(gè)在 main js 頁面引入使用,我就不展示了

路由權(quán)限判斷

  • 上面的配置如果我們直接在瀏覽器中打開 http://localhost:8080/ 這個(gè)地址,那么展示的就是 layout 組件,如果需要展示位 login 組件的話,我們就需要在全局前置路由守衛(wèi)上動(dòng)一下手腳了
  • 也非常簡單,一個(gè)用戶登沒登錄,就是判斷是否是存在了 token,如果有就是登錄了,如果沒有就是沒有登錄,根據(jù)這個(gè),我們可以得出一張關(guān)系圖,如圖:

這只是一個(gè)簡單的路由權(quán)限判斷,具體的還需要根據(jù)業(yè)務(wù)來擴(kuò)展,根據(jù)這個(gè)關(guān)系圖,我們可以寫出如下代碼:

import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
import store from '@/store'
const router = new VueRouter({
	mode: 'hash',
	routes: [
		{
			path: '/',
			name: 'layout',
			component: () => import('@/layout')
		},
		{
			path: '/login',
			name: 'login',
			component: () => import('@/views/login')
		}
	]
})
router.beforeEach((to, from, next) => {
	const token = store.state.login.token
	if (token) {
		if (to.path === '/login') {
			next(false)
		} else {
			next()
		}
	} else {
		if (to.path === '/login') {
			next()
		} else {
			next('/login')
		}
	}
})
export default router

登錄

實(shí)現(xiàn)這點(diǎn)的方法也不止一種,本文采用的是在 store 的 login 模塊中完成登錄,至于 axios 的封裝或者基于 xhr 等等的請(qǐng)求方面,我這里不做解析了

store 的基礎(chǔ)配置不做贅述了,直接粘貼代碼,如下:

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
import login from './login'
const store = new Vuex.Store({
	modules: { login }
})
export default store

至于 login 模塊的話,書寫也非常簡單,編寫登錄函數(shù),登錄成功之后同步獲取菜單數(shù)據(jù),如下:

import { loginApi, menuApi } from '@/api'
import router from '@/router'
export default {
	namespaced: true,
	state: {
		userInfo: {} || localStorage.getItem('user_info'),
		token: '' || localStorage.getItem('token'),
		menuList: [] || localStorage.getItem('menu_list')
	},
	mutations: {
		SET_MENU_LIST(state, payload) {
			state.menuList = payload
		},
		SET_USER_INFO(state, payload) {
			state.userInfo = payload
			localStorage.setItem('user_info', JSON.stringify(payload))
		},
		SET_TOKEN(state, payload) {
			state.token = payload
			localStorage.setItem('token', payload)
		},
        // 退出登錄
		LOG_OUT() {
			localStorage.removeItem('token')
			localStorage.removeItem('user_info')
			localStorage.removeItem('menu_list')
			// 刷新頁面-因?yàn)槁酚蓹?quán)限的存在會(huì)導(dǎo)航到login,并且通過這個(gè)刷新可以避免重復(fù)添加路由
			window.location.reload()
		}
	},
	actions: {
		async login({ commit }, payload) {
            // 登錄請(qǐng)求-獲取token
			const loginResp = await loginApi.reqLogin(payload)
			if (loginResp?.errorCode !== 0) return
			commit('SET_USER_INFO', loginResp.data.userInfo)
			commit('SET_TOKEN', loginResp.data.token)
			// 請(qǐng)求菜單列表
			const menuListResp = await menuApi.reqGetMenuList()
			localStorage.setItem('menu_list', JSON.stringify(menuListResp.data))
			commit('SET_MENU_LIST', menuListResp.data)
			// 跳轉(zhuǎn)至首頁
			router.push('/home')
		}
	}
}

這部分代碼還是非常簡單的,在入口文件main.js 引用 store 和在登錄界面收集表單數(shù)據(jù)提交調(diào)用這個(gè) login 方法登錄,大家就自己實(shí)現(xiàn)一下吧

現(xiàn)在我們獲取到這個(gè)數(shù)據(jù)之后,表示我們可以完成兩件事情,第一就是渲染側(cè)邊的菜單列表,第二就是根據(jù)這個(gè)來添加正確的動(dòng)態(tài)路由

渲染菜單列表沒有什么好說的,如果沒有菜單欄的遞歸需求的話,菜單欄直接 cv 組件庫的代碼即可,需要遞歸的話就要自己封裝一下了

添加動(dòng)態(tài)路由

要添加動(dòng)態(tài)路由,需要有兩個(gè)數(shù)據(jù),一個(gè)是遠(yuǎn)程獲取的菜單數(shù)據(jù),一個(gè)是前端的映射的組件關(guān)系。遠(yuǎn)程數(shù)據(jù)已經(jīng)有了,前端映射的組件關(guān)系,就看你自己的業(yè)務(wù)來配置了,還是非常簡單的,把你前端需要展示的頁面都在一個(gè) js 文件引入就好了,如下:

export default [
	{
		name: 'home',
		component: () => import('@/views/home')
	},
	{
		name: 'my',
		component: () => import('@/views/my')
	},
	{
		name: 'device-add',
		component: () => import('@/views/device/add')
	},
	{
		name: 'device-list',
		component: () => import('@/views/device/list')
	},
	{
		name: 'user-add',
		component: () => import('@/views/user/add')
	},
	{
		name: 'user-list',
		component: () => import('@/views/user/list')
	}
]

具體需要多少配置項(xiàng),就視個(gè)人業(yè)務(wù)而定,我這里使用 name 匹配,你也可以是 path 或者其他屬性

在看一下遠(yuǎn)程的數(shù)據(jù)具體是什么樣的,有助于理解,如下:

[
    {
        "id": 1,
        "name": "home",
        "path": "/home",
        "nickname": "首頁",
        "type": 2,
        "order": 1,
        "parentId": 0,
        "icon": "icon-tubiao_shouye-",
        "children": null
    },
    {
        "id": 2,
        "name": "device",
        "path": "/device",
        "nickname": "設(shè)備管理",
        "type": 1,
        "order": 2,
        "parentId": 0,
        "icon": "icon-guanli",
        "children": [
            {
                "id": 3,
                "name": "device-list",
                "path": "/device/list",
                "nickname": "設(shè)備列表",
                "type": 2,
                "order": 1,
                "parentId": 2,
                "icon": "icon-xuanzeweixuanze",
                "children": null
            },
            {
                "id": 4,
                "name": "device-add",
                "path": "/device/add",
                "nickname": "設(shè)備添加",
                "type": 2,
                "order": 2,
                "parentId": 2,
                "icon": "icon-xuanzeweixuanze",
                "children": null
            }
        ]
    },
    {
        "id": 5,
        "name": "my",
        "path": "/my",
        "nickname": "個(gè)人中心",
        "type": 2,
        "order": 3,
        "parentId": 0,
        "icon": "icon-xiazai",
        "children": null
    },
    {
        "id": 6,
        "name": "user",
        "path": "/user",
        "nickname": "用戶管理",
        "type": 1,
        "order": 4,
        "parentId": 0,
        "icon": "icon-yonghuguanli",
        "children": [
            {
                "id": 7,
                "name": "user-list",
                "path": "/user-list",
                "nickname": "用戶列表",
                "type": 2,
                "order": 1,
                "parentId": 6,
                "icon": "icon-xuanzeweixuanze",
                "children": null
            },
            {
                "id": 8,
                "name": "user-add",
                "path": "/user-add",
                "nickname": "用戶添加",
                "type": 2,
                "order": 2,
                "parentId": 6,
                "icon": "icon-xuanzeweixuanze",
                "children": null
            }
        ]
    }
]

剩下的就是遞歸遍歷的找出組裝出對(duì)應(yīng)的 route 配置的事情了,那么我們需要有這樣的一個(gè)函數(shù),來幫助我們完成這件事情,代碼如下:

import router from '@/router'
// 前端映射的組件關(guān)系配置
import routeConfig from '@/router/route-config'
export default function (menuList) {
	const routeList = []
	const deepMenu = menuList => {
		for (const menu of menuList) {
			if (menu.children && menu.children.length > 0) {
				deepMenu(menu.children)
			} else {
				const item = routeConfig.find(item => item.name === menu.name)
				if (!item) return
				// 去掉第一項(xiàng)斜杠-子路由 path 屬性不需要攜帶開頭的 /
				const path = menu.path.replace(/^\//, '')
                // 路由元信息可以幫助我們完成一些其他操作的時(shí)候,需要的一些輔助數(shù)據(jù)
				routeList.push({ ...item, path, meta: { title: menu.nickname } })
			}
		}
	}
	deepMenu(menuList)
	for (const route of routeList) {
        // 遍歷添加路由
		router.addRoute('layout', route)
	}
}

有了這個(gè)方法之后,自然就是使用,如下:

import { loginApi, menuApi } from '@/api'
import router from '@/router'
import menuToRoute from '@/utils/menu-to-route'
export default {
	namespaced: true,
	state: {
		userInfo: {} || localStorage.getItem('user_info'),
		token: '' || localStorage.getItem('token'),
		menuList: [] || localStorage.getItem('menu_list')
	},
	mutations: {
		SET_MENU_LIST(state, payload) {
			state.menuList = payload
            // 調(diào)用菜單轉(zhuǎn)路由方法
			menuToRoute(payload)
		},
		SET_USER_INFO(state, payload) {
			state.userInfo = payload
			localStorage.setItem('user_info', JSON.stringify(payload))
		},
		SET_TOKEN(state, payload) {
			state.token = payload
			localStorage.setItem('token', payload)
		},
        // 退出登錄
		LOG_OUT() {
			localStorage.removeItem('token')
			localStorage.removeItem('user_info')
			localStorage.removeItem('menu_list')
			// 刷新頁面-因?yàn)槁酚蓹?quán)限的存在會(huì)導(dǎo)航到login,并且通過這個(gè)刷新可以避免重復(fù)添加路由
			window.location.reload()
		}
	},
	actions: {
		async login({ commit }, payload) {
			const loginResp = await loginApi.reqLogin(payload)
			if (loginResp?.errorCode !== 0) return
			commit('SET_USER_INFO', loginResp.data.userInfo)
			commit('SET_TOKEN', loginResp.data.token)
			// 請(qǐng)求菜單列表
			const menuListResp = await menuApi.reqGetMenuList()
			localStorage.setItem('menu_list', JSON.stringify(menuListResp.data))
			commit('SET_MENU_LIST', menuListResp.data)
			// 跳轉(zhuǎn)至首頁
			router.push('/home')
		}
	}
}

此時(shí)我們已經(jīng)完成了整個(gè)效果的實(shí)現(xiàn),當(dāng)然還有一個(gè)問題,但是這個(gè)問題后面再說,先看一下效果,如圖:

可以看到,不同的賬戶登錄會(huì)因?yàn)榻巧煌宫F(xiàn)的菜單也不同

修復(fù)刷新路由丟失問題

現(xiàn)在我們這個(gè)看著沒什么問題,是因?yàn)槲覀儧]有點(diǎn)擊刷新,先看看問題,如圖:

一旦刷新之后就會(huì)導(dǎo)致動(dòng)態(tài)路由清空,但是又沒有重新注冊(cè)添加,自然就會(huì)找不到這個(gè)路由了,因此白屏就很正常了

解決也非常簡單,在每次刷新的時(shí)候,都在重新注冊(cè)一次動(dòng)態(tài)路由就好了,所以在 store 的 login 模塊多添加一個(gè)方法,如下:

import { loginApi, menuApi } from '@/api'
import router from '@/router'
import menuToRoute from '@/utils/menu-to-route'
export default {
	namespaced: true,
	state: {
		userInfo: {} || localStorage.getItem('user_info'),
		token: '' || localStorage.getItem('token'),
		menuList: [] || localStorage.getItem('menu_list')
	},
	mutations: {
		SET_MENU_LIST(state, payload) {
			state.menuList = payload
			menuToRoute(payload)
		},
		SET_USER_INFO(state, payload) {
			state.userInfo = payload
			localStorage.setItem('user_info', JSON.stringify(payload))
		},
		SET_TOKEN(state, payload) {
			state.token = payload
			localStorage.setItem('token', payload)
		},
		LOG_OUT() {
			localStorage.removeItem('token')
			localStorage.removeItem('user_info')
			localStorage.removeItem('menu_list')
			window.location.reload()
		}
	},
	actions: {
		async login({ commit }, payload) {
			const loginResp = await loginApi.reqLogin(payload)
			if (loginResp?.errorCode !== 0) return
			commit('SET_USER_INFO', loginResp.data.userInfo)
			commit('SET_TOKEN', loginResp.data.token)
			const menuListResp = await menuApi.reqGetMenuList()
			localStorage.setItem('menu_list', JSON.stringify(menuListResp.data))
			commit('SET_MENU_LIST', menuListResp.data)
			router.push('/home')
		},
		// 加載本地?cái)?shù)據(jù)
		async loadLocal({ commit }) {
			const menuList =  localStorage.getItem('menu_list')
			if (menuList) {
				commit('SET_MENU_LIST', JSON.parse(menuList))
			}
		}
	}
}

loadLocal 這個(gè)方法還可以初始化一下其他你需要初始化的信息,包括但不限于這個(gè)菜單列表,其他是導(dǎo)出這個(gè)方法,讓其他人使用,可以直接從這個(gè)模塊使用,也可以其他地方導(dǎo)出,我這里就在 store/index.js 文件下導(dǎo)出,如下:

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
import login from './login'
const store = new Vuex.Store({
	modules: { login }
})
// 導(dǎo)出方法
export function loadLocal() {
	store.dispatch('login/loadLocal')
}
export default store

最后在 main.js 中調(diào)用此方法即可,導(dǎo)入和使用語句如下:

import { loadLocal } from './store'
loadLocal()

現(xiàn)在我們?cè)趤砜纯葱Ч?,如圖:

結(jié)語

這里只是給大家展示一種思路,具體的實(shí)現(xiàn)需要根據(jù)自己的業(yè)務(wù)來定,但是整體的流程都是差不多的

如果對(duì)于這個(gè)遞歸菜單,和后端部分這個(gè)實(shí)現(xiàn)登錄邏輯部分,可以查看我后續(xù)發(fā)布的其他文章,或者如果我沒忘記的話,我會(huì)來這里補(bǔ)上查看鏈接

到此這篇關(guān)于Vue如何根據(jù)角色獲取菜單動(dòng)態(tài)添加路由的文章就介紹到這了,更多相關(guān)Vue根據(jù)角色添加路由內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue3?邏輯復(fù)用的實(shí)現(xiàn)示例

    vue3?邏輯復(fù)用的實(shí)現(xiàn)示例

    在項(xiàng)目開發(fā)中,有兩個(gè)功能特別類似,如果單獨(dú)實(shí)現(xiàn),會(huì)有很多重復(fù)的代碼,這時(shí)候就會(huì)用到邏輯復(fù)用,本文主要介紹了vue3?邏輯復(fù)用的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-02-02
  • vue實(shí)現(xiàn)修改圖片后實(shí)時(shí)更新

    vue實(shí)現(xiàn)修改圖片后實(shí)時(shí)更新

    今天小編就為大家分享一篇vue實(shí)現(xiàn)修改圖片后實(shí)時(shí)更新,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2019-11-11
  • uniapp和vue如何獲取屏幕或盒子內(nèi)容的寬高

    uniapp和vue如何獲取屏幕或盒子內(nèi)容的寬高

    在實(shí)際開發(fā)中我們會(huì)遇到不確定高度的情況,下面這篇文章主要給大家介紹了關(guān)于uniapp和vue如何獲取屏幕或盒子內(nèi)容的寬高,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-02-02
  • Vue獲取圖片MD5的方法詳解

    Vue獲取圖片MD5的方法詳解

    計(jì)算圖片的MD5可以將其作為圖片的唯一標(biāo)識(shí),從而優(yōu)化對(duì)圖片的存儲(chǔ)和檢索效率,本文主要介紹了Vue獲取圖片MD5的常用方法,感興趣的可以了解下
    2024-12-12
  • vue 項(xiàng)目打包通過命令修改 vue-router 模式 修改 API 接口前綴

    vue 項(xiàng)目打包通過命令修改 vue-router 模式 修改 API 接口前綴

    這篇文章主要介紹了vue 項(xiàng)目打包通過命令修改 vue-router 模式 修改 API 接口前綴的相關(guān)知識(shí),本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2018-06-06
  • Vue發(fā)送ajax請(qǐng)求方法介紹

    Vue發(fā)送ajax請(qǐng)求方法介紹

    這篇文章介紹了Vue發(fā)送ajax請(qǐng)求的方法,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-01-01
  • Vue手寫橫向輪播圖的實(shí)例

    Vue手寫橫向輪播圖的實(shí)例

    這篇文章主要介紹了Vue手寫橫向輪播圖的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • Vue3實(shí)現(xiàn)下拉選擇框多選功能的方法詳解

    Vue3實(shí)現(xiàn)下拉選擇框多選功能的方法詳解

    在vue的實(shí)際開發(fā)過程中,我們?nèi)绾螌⒁赃x中的值直接渲染到頁面中,下面這篇文章主要給大家介紹了關(guān)于Vue3實(shí)現(xiàn)下拉選擇框多選功能的相關(guān)資料,需要的朋友可以參考下
    2023-09-09
  • Vue的混合繼承詳解

    Vue的混合繼承詳解

    這篇文章主要介紹了Vue的混合繼承,有需要的朋友可以借鑒參考下,希望能夠有所幫助,希望能夠給你帶來幫助
    2021-11-11
  • vue 基于element-ui 分頁組件封裝的實(shí)例代碼

    vue 基于element-ui 分頁組件封裝的實(shí)例代碼

    這篇文章主要介紹了vue 基于element-ui 分頁組件封裝的實(shí)例代碼,代碼簡單易懂,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-12-12

最新評(píng)論