最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue router動態(tài)路由實現過程

 更新時間:2023年03月14日 09:58:09   作者:Bennett_G  
Vue動態(tài)路由(約定路由),聽起來好像很玄乎的樣子,但是你要是理解了實現思路,你會發(fā)現沒有想象中的那么難,下面這篇文章主要給大家介紹了關于vue實現動態(tài)路由添加功能的簡單方法,需要的朋友可以參考下

?????? vue動態(tài)路由(約定路由),聽起來好像很玄乎的樣子?? 但是你要是理解了實現思路,你會發(fā)現,沒有想象中的那么難??

在沒有親自實現功能前,永遠不要低估自己的個人實力和潛力??????

??????下面是本人一個剛從服務端開發(fā)轉職前端開發(fā)的程序猿的實現過程??????

實現思路

思路其實很簡單,也很明確:

1、將路由分為靜態(tài)路由(staticRouters)、動態(tài)路由

2、靜態(tài)路由初始化時正常加載

3、用戶登陸后,獲取相關動態(tài)路由數據,

4、然后利用vue:addRoute追加到vue實例中即可。 實現思路雖然很簡單,但是過程并不是一帆風順,需要注意的細節(jié)還是很多的

環(huán)境介紹

  • vue-cli: v4.x.x
  • vue: v2.6.11
  • vuex: v3.4.0
  • vue-router: v3.2.0

實現過程

路由文件處理(router/index.js):

import Vue from 'vue'
import VueRouter from 'vue-router'
import HomeLayout from '../layouts/HomeLayout'
import store from '@/store/index'
Vue.use(VueRouter)
// 解決重復點擊路由報錯的BUG
const originalPush = VueRouter.prototype.push
VueRouter.prototype.push = function push(location) {
    return originalPush.call(this, location).catch((err) => err)
}
const routes = [
	{
		path: '/',
		name: 'homeBase',
		component: HomeLayout,
		redirect: {
			name: 'home'
		},
		children: [
			// 門戶路由
			{
				path: 'home',
				name: 'home',
				component: () => import('../views/portal/Home.vue'),
			},
			{
				path: 'lists',
				name: 'lists',
				component: () => import('../views/portal/Lists.vue'),	
			},
			{
				path: 'detail',
				name: 'detail',
				component: () => import('../views/portal/Detail.vue'),	
			},
		]
	},
]
// 定義靜態(tài)路由集合
const staticRouterMap = [
	'home',
	'lists',
	'detail'
]
const router = new VueRouter({
	mode: 'history',
	base: process.env.BASE_URL,
	routes,
})
// 路由全局攔截
// 以下可根據業(yè)務邏輯自行在攔截路由中進行處理,此處僅以本人業(yè)務作為示例展示
// 本示例以 vuex+sessionStorage相互配合完成動態(tài)路由的數據存儲
// 僅以vuex存儲獲取到的動態(tài)路由信息后,在刷新頁面時,動態(tài)路由信息是會丟失,
// 從而導致頁面404
router.beforeEach((to, from, next) => {
	const userState = JSON.parse(sessionStorage.getItem('userState'))
	if (!userState || !userState.isLogin) {
		// 沒有登錄
		// 如果前往頁面非公共路由,則跳轉至首頁
		if (staticRouterMap.indexOf(to.name) < 0) {
			next({name: 'home'})
		} else {
			next()
		}
	} else {
		// 登錄
		// 已經存在路由列表: 注意剛登陸成功第一次調轉route時相應store數據還未更新
		const hasGetRoute = store.getters['user/hasGetRoute']
		const routeMap = JSON.parse(sessionStorage.getItem('routeMap'))
		if(!hasGetRoute && routeMap) {
            // 刷新頁面且有route記錄數據,可再次追加動態(tài)路由
			store.dispatch('user/updateRouteOfUser', routeMap)
			next({...to, replace: true})
		} else {
			next()
		}
	}
})
export default router

view數據處理

<template>
	<div class="home">
		<div>
			這是demo
		</div>
		<div>
			<div v-show="!isLogin">
				<a-divider>調用接口: 模擬登陸</a-divider>
				<div style="margin-top:5px;">
					<a-space :size="size">
						<a-button type="primary" @click="login()">
							用戶登陸
						</a-button>
					</a-space>
					<p>{{loading}}</p>
				</div>
			</div>
		</div>
	</div>
</template>
<script>
	// @ is an alias to /src
	import {
		Base64
	} from 'js-base64'
	import User from '../../api/user'
	import {
		mapGetters,
		mapMutations,
		mapActions
	} from 'vuex'
	export default {
		name: 'home',
		data() {
			return {
				size: "middle",
				user: {
					'name': 'xxxx',
					'pass': Base64.encode('xxxx')
				},
			}
		},
		components: {},
		computed: {
			...mapGetters('user', ['isLogin', 'userInfo', 'hasGetRoute'])
		},
		methods: {
			...mapMutations('user', ['setUserState']),
			...mapActions('user', ['getUserInfo', 'getDynamicRouteOfUser']),
			login() {
				if (this.isLogin) {
					this.$router.push({
						path: '/user'
					})
				} else {
					// 模擬用戶
					User.login(this.user).then(res => {
						this.setUserState({
							'isLogin': true,
							'ut': res.data.user_token,
							'userType': 1
						})
						this.getUserInfo()
						//以下就是根據用戶登陸信息,獲取動態(tài)路由信息操作
						this.getDynamicRouteOfUser(type).then(() => {
							this.$router.push({
								path: '/user'
							})
						})
					}).catch(() => {
					})
				}
			},
		},
	}
</script>
<style lang="scss" scoped>
	.home {
		padding: 20px;
	}
</style>

vuex

import VueRouter from '../../router'
import UserApi from '../../api/user'
import axios from 'axios'
import TeacherLayout from '@/layouts/Layout'
import NotFound from '@/layouts/404'
const user = {
    namespaced: true,
    state: {
        // 用戶狀態(tài)相關 
        userState: JSON.parse(sessionStorage.getItem('userState')) || {ut: '', isLogin: false, userType: null},
        // 用戶信息相關
        userInfo: JSON.parse(sessionStorage.getItem('userInfo')) || {},
        // 是否獲取route
        hasGetRoute: false,
        // routeMap
        routeMap: JSON.parse(sessionStorage.getItem('routeMap')) || [],
    },
    getters: {
        ut : state => state.userState.ut,
        isLogin: state => !!state.userState.isLogin,
        userInfo: state => state.userInfo,
        hasGetRoute: state => state.hasGetRoute,
        routeMap: state => state.routeMap[0].children,
    },
    mutations: {
        setUserState(state, playload) {
            state.userState = playload
            sessionStorage.setItem('userState', JSON.stringify(state.userState))
        },
        setUserInfo(state, playload) {
            state.userInfo = playload
            sessionStorage.setItem('userInfo', JSON.stringify(state.userInfo))
        },
        setRouteMap(state, routers) {
            state.routeMap = routers
            // 為了防止用戶刷新頁面導致動態(tài)創(chuàng)建的路由失效,將其存儲在本地中
            sessionStorage.setItem('routeMap', JSON.stringify(routers));
        },
        setDynamicRouteMap(state, routers) {
            state.hasGetRoute = true
            let routerMaps = filterRouter(routers)
            // 最后追加404路由
            routerMaps.push({
                path: '*',
                component: NotFound
            })
            // 追加路由
            // 這塊是重點,如果直接使用addRoute是無效的
            routerMaps.forEach(item => {
                VueRouter.addRoute(item);
            })
        },
        resetLogin() {
            sessionStorage.clear()
        }
    },
    actions: {
        // 獲取用戶信息
        async getUserInfo({commit}) {
            await UserApi.user().then(res => {
                commit('setUserInfo', res)
            }).catch(error => {
                console.log(error)
            })
        },
        // 獲取用戶授權動態(tài)路由
        async getDynamicRouteOfUser({commit}, type) {
            let flag = false
            // mock api
            mockRouter().then(res => {
                commit('setRouteMap', res.data)
                commit('setDynamicRouteMap', res.data)
                flag = true
            }).catch(err => {
                console.log(err)
            })
            return flag
        },
        // 刷新重置路由
        updateRouteOfUser({commit}, routerMap) {
            commit('setDynamicRouteMap', routerMap)
        },
    }
}
// handle views
const loadView = (viewPath) => {
    return () => import('@/views/' + viewPath)
}
// Handle routers
const filterRouter = (routers) => {
    return routers.filter((router) => {
   		// 區(qū)分布局與視圖文件,因為加載方式不同
        if (router.component === 'Layout') {
            router.component = Layout
        }else {
            // view
            router.component = loadView(router.component)
        }
        // 刪除路由記錄中的無用字段:這段是本示例與后臺協(xié)商的,但在vue-router中不被支持的字段信息,可忽略
        if (!router.redirect || !router.redirect.length) { delete router.redirect }
        // 判斷是否存在子路由,并遞歸調用自己
        if(router.children && router.children.length) {
            router.children = filterRouter(router.children)
        }
        return true
    })
} 
// mock 數據
async function mockRouter() {
    const url = 'http://localhost:8080/t.json'
    let routerData
    await axios.get(url).then(res => {
        routerData = res.data
    }).catch(err => {
        console.log(err)
    })
    return routerData
}
export default user;

路由數據(demo)

貢獻本人于服務端約定的路由數據結構,僅供參考

{
    "data":[
        {
            "title":"demo",
            "name":"x",
            "pname":"",
            "path": "/x",
            "type": 1,
            "component": "Layout",
            "redirect": {"name": "xx"},
            "children": [
                {
                    "title":"child1",
                    "name":"xx",
                    "pname":"x",
                    "path": "",
                    "type": 2,
                    "icon": "desktop",
                    "component": "xx.vue",
                    "redirect": {}
                },
                {
                    "title":"child1",
                    "name":"xx",
                    "pname":"tBase",
                    "path": "xx",
                    "type": 2,
                    "icon": "container",
                    "component": "xx.vue",
                    "redirect": {"name": "xxx"},
                    "children": [
                        {
                            "title":"child2",
                            "name":"xx",
                            "pname":"xx",
                            "path": "xx",
                            "type": 2,
                            "icon": "unordered-list",
                            "component": "xx.vue",
                            "redirect": {} 
                        }
                    ]
                },
            ]
        }
    ]
}

到此這篇關于Vue router動態(tài)路由實現過程的文章就介紹到這了,更多相關Vue router動態(tài)路由內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Vue3非遞歸渲染Tree組件的初步實現代碼

    Vue3非遞歸渲染Tree組件的初步實現代碼

    這篇文章主要介紹了Vue3非遞歸渲染Tree組件的初步實現,文中通過代碼示例講解的非常詳細,對大家的學習或工作有一定幫助,需要的朋友可以參考下
    2024-05-05
  • element?tab標簽管理路由頁面的項目實踐

    element?tab標簽管理路由頁面的項目實踐

    本文主要介紹了element?tab標簽管理路由頁面的項目實踐,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-08-08
  • 淺談webpack SplitChunksPlugin實用指南

    淺談webpack SplitChunksPlugin實用指南

    這篇文章主要介紹了淺談webpack SplitChunksPlugin實用指南,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-09-09
  • Vue.js頁面中有多個input搜索框如何實現防抖操作

    Vue.js頁面中有多個input搜索框如何實現防抖操作

    debounce是lodash工具庫中的一個非常好用的函數。這篇文章主要介紹了Vue.js頁面中有多個input搜索框如何實現防抖操作,需要的朋友可以參考下
    2019-11-11
  • Vue項目中使用Base64

    Vue項目中使用Base64

    在vue項目中有時會使用到Base6464轉碼,現將自己使用的一種方法記錄下來,對vue使用Base64相關知識感興趣的朋友一起看看吧
    2024-02-02
  • Vue3?echarts組件化及使用hook進行resize方式

    Vue3?echarts組件化及使用hook進行resize方式

    這篇文章主要介紹了Vue3?echarts組件化及使用hook進行resize方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • vue+axios?methods方法return取不到值問題及解決

    vue+axios?methods方法return取不到值問題及解決

    這篇文章主要介紹了vue+axios?methods方法return取不到值問題及解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • 深入了解Vue3中偵聽器watcher的實現原理

    深入了解Vue3中偵聽器watcher的實現原理

    在平時的開發(fā)工作中,我們經常使用偵聽器幫助我們去觀察某個數據的變化然后去執(zhí)行一段邏輯。在?Vue.js?2.x?中,你可以通過?watch?選項去初始化一個偵聽器,稱作?watcher。本文將詳細為大家介紹一下偵聽器的實現原理,需要的可以參考一下
    2022-04-04
  • Vite使用Esbuild提升性能詳解

    Vite使用Esbuild提升性能詳解

    這篇文章主要為大家介紹了Vite使用Esbuild提升性能示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-08-08
  • Vue開發(fā)指南之重點知識梳理

    Vue開發(fā)指南之重點知識梳理

    這篇文章主要介紹了Vue開發(fā)指南之重點知識梳理,對Vue框架感興趣的同學,可以參考下
    2021-05-05

最新評論

莆田市| 和顺县| 乡宁县| 常宁市| 正安县| 东海县| 边坝县| 长顺县| 揭阳市| 高青县| 株洲市| 洞口县| 敦煌市| 平阴县| 吴旗县| 额敏县| 南漳县| 三都| 应城市| 蓬安县| 五指山市| 花莲市| 兴化市| 杭州市| 枞阳县| 宣恩县| 南雄市| 景泰县| 宁德市| 彰武县| 博客| 景谷| 漳州市| 崇礼县| 汉沽区| 正阳县| 宜州市| 嘉禾县| 抚顺市| 自治县| 河北省|