vue vue-router路由

1、安装
	cnpm install vue-router -S

2、在创建路由的js中引入
	import Vue from 'vue'
	import VueRouter from 'vue-router'

3、创建路由
	routes=[{
		name:'路由名称'
		component:组件,
		path:'/路由路径',
		meta:{...},	路由元信息,$route.meta获取
			ts中定义:typings.d.ts or router.ts
			
			import 'vue-router'
			
			declare module 'vue-router' {
			  interface RouteMeta {
				meta中的字段...
			  }
			}

		
		路由重定向
			redirect: '/',	
			redirect: { name: 'homepage',params... } } 通过路由名重定向
			redirect: to => {
		      to相当于$route	
		      return { path: '/search', query: { q: to.params.searchText } }
		    },
			写redirect的时候,可以省略component配置,唯一的例外是嵌套路由:如果一个路由有children和redirect属性,也应该有component属性
			
		路由别名
			alias: '/home'
			alias: ['/:id']
			alias: ['/home',...]
			children:[{
				alias: ['/people', 'list']		嵌套路由中加上/则为绝对路径,/people则可访问,否则/父路由/list才能访问
			}]
		
		将路由参数传递给组件
			props:true		route.params将被设置为组件的props,组件可直接this.x使用
			props: { ... }	手动定义传给组件props的内容,适用于静态组件
			props: route => ({ query: route.query.q })	将静态值与基于路由的值相结合
			命名视图中必须为每个视图定义
			    components: { default: User, sidebar: Sidebar },
			    props: { default: true, sidebar: false }
	},...]
	
	新版本:
	const router = VueRouter.createRouter({
	  history: VueRouter.createWebHashHistory(),	hash模式
	  	base:提供的可选 base,https://example.com/folder/之类的文件夹中时非常有用当应用程序被托管在诸如 
	  history: createWebHistory(),		history模式
	  history: createMemoryHistory() 	SSR
	  linkActiveClass:'x', 			用于激活的RouterLink的类,默认会使用router-link-active
	  linkExactActiveClass :'x',	用于精准激活的RouterLink的默认类,默认会使用 router-link-exact-active
	  parseQuery: qs.parse,			用于解析查询的自定义实现
	  stringifyQuery: qs.stringify,	对查询对象进行字符串化的自定义实现,不应该在前面加上 ?
	  routes,
	})
	const app = Vue.createApp({})
	app.use(router)
	app.mount('#app')

3.5、嵌套路由
	const routes = [
	  { path: '/users/:id', 
	  	component: User,
	  	children:[{
	  		name:'...'
			path:'不加/、不加父级路径的名称', 若加上/则为绝对路径,/x访问子路由,而不是/父路由路径/x访问
			component:子组件,
			children:[{...}]
		}]
	  },
	]

4、展示路由对应的组件
	<router-view />
	嵌套路由:在父路由的组件中设置给子路由的组件显示位置处设置

4.1、命名视图
	同级展示多个视图,而不是嵌套展示
	<router-view name="LeftSidebar"></router-view>
	<router-view></router-view>	没有设置name默认为default
	<router-view name="RightSidebar"></router-view>
	  routes: [
	    {
	      path: '/',
	      components: {
	        default: Home,
	        LeftSidebar:LeftSidebar,
	        RightSidebar:RightSidebar
	      },
	    },
	  ],
	  
	嵌套命名视图同理,在children中配置多个components
	
4.5、编程式导航、声明式导航
	声明式导航:
		<router-link :to="..."> 	相当于调用router.push(...)
		to的使用方法和编程式跳转中的使用方式相同:
		如:
			<router-link :to="{ name: 'user', params: {id: 123 }}">User</router-link>
			
		其中router-link的额外属性:
			(1)custom :自定义是否应该将其内容包裹在<a>元素中
			
				<router-link to="/home" custom v-slot="{ navigate, href, route }">
				  <a :href="href" @click="navigate">{{ route.fullPath }}</a>
				</router-link>
				渲染成:<a href="/home">/home</a>
				
				<router-link to="/home" v-slot="{ route }">
				  <span>{{ route.fullPath }}</span>
				</router-link>
				渲染成:<a href="/home"><span>/home</span></a>
				
				把激活的class应用到一个外部元素而不是<a>标签本身
				<router-link
				  to="/foo"
				  custom
				  v-slot="{ href, route, navigate, isActive, isExactActive }"
				>
				  <li
				    :class="[isActive && 'router-link-active', isExactActive && 'router-link-exact-active']"
				  >
				    <a :href="href" @click="navigate">{{ route.fullPath }}</a>
				  </li>
				</router-link>

				
				v-slot向外暴露的内容:
					href:解析后的 URL
					route:解析后的规范化的地址。
					navigate:触发导航的函数
					isActive:如果需要应用active class,为true
					isExactActive:如果需要应用exact active class,为true
				
				
		 	(2)replace:将默认的this.$router.push()替换成replace
		 		用法:标签添加 replace
		 		
		 	(3)active-class:设置active-class属性是当router-link中的链接被激活是,添加css类名。
		 		也就是当前页面所有与当前地址所匹配的的链接都会被添加class属性,包括父路由的名称
		 		如果没有设置active-class属性,vue会有一个默认的class来表示当前链接被激活:.router-link-active。
		 		用法:active-class='类名'
		 		
		 	(4)exact-active-class:配置当链接被精确匹配的时候应该激活的 class。
		 		将当前所在路由名称改变,不改变父路由路径
		 		不设置的时候,默认的class:.router-link-exact-active或全局createRouter({
					linkExactActiveClass:'类名' 在主入口的style中设置该类样式
				})
		 		用法:exact-active-class='类名'
		
	编程式导航:(返回的是Promise,可以使用await等待导航结束)
		this.$router.push('/users/eduardo')
		this.$router.push({ path: '/users/eduardo' })	path不能和params一起使用
		this.$router.push({ name: 'user', params: { username: 'eduardo' } })	/user/:username
		this.$router.push({ path: '/register', query: { plan: 'private' } })	/register?plan=private
			this.$route.query获取参数
		this.$router.push({ path: '/about', hash: '#team' })	/about#team
		
		替换当前路由
		this.$router.push({ path: '/home', replace: true })
		this.$router.replace({ path: '/home' })
		
		前进后退
		this.$router.forward()	等效于this.$router.go(1)
		this.$router.back()		等效于this.$router.go(-1)
		this.$router.go(n)
		
		事件回调
		this.$router.push(...,onComplete,onAbort)
			onComplete:	在导航成功完成(在所有的异步钩子被解析之后)调用	
			onAbort:	终止(导航到相同的路由、或在当前导航完成之前导航到另一个不同的路由)的时候进行相应的调用
	
	  	等待导航结束
	  	await this.$router.push('/users/eduardo');
	  	
	  	检测导航故障
	  	this.$router.push如果导航未成功,会返回一个Promise,成功返回false或undefined
	  	
	  		const navigationResult = await router.push('/my-profile')
	  		if(navigationResult){
	  			失败导航
	  		}else{
	  			成功导航
	  		}
	  		
	  		检验失败类型
	  		const failure = await router.push('/articles/2')
	  		
			if(isNavigationFailure(failure, NavigationFailureType.aborted)){
	   			NavigationFailureType.aborted:在导航守卫中返回false 中断了本次导航。
	   			NavigationFailureType.cancelled: 在当前导航还没有完成之前又有了一个新的导航。比如,在等待导航守卫的过程中又调用了router.push
	   			NavigationFailureType.duplicated:导航被阻止,因为我们已经在目标位置了
	   			NavigationFailureType.redirected:导航被重定向了
	   			如果忽略第二个参数:isNavigationFailure(failure),那么就只会检查这个failure是不是一个Navigation Failure
	   		}
	  		或
	  		router.push('/admin').then(failure => {
			  if (isNavigationFailure(failure, NavigationFailureType.redirected)) {
				...
			  }
			})

5、动态参数路由匹配
	(1)创建
		const routes = [
		  { path: '/users/:id', component: User },
		  { path: '/路径/:键名/路径/:键名',...}
		  可选参数
		  { path: '/users/:userId?' },	0个或1个,匹配/users和/users/posva
		  通过正则区分不同类型
		  { path: '/:orderId(\\d+)' }	仅匹配参数是数字的路径,如/123,在数组的顺序并不重要
		  { path: '/user/:orderId(\\d+)?' }	匹配/users和/users/42
		  { path: '/:productName' }		匹配任意类型
		  匹配多个参数
		  { path: '/:chapters+' },	0个或多个,如/one/two/three
		  { path: '/:chapters*' },	1个或多个,如/one/two/three
		]
	
	(2)传递路径参数
		<router-link to='/users/值'><router-link>
		this.$router.push('/users/123')
		this.$router.push({ name:'users',params: {id: 123 } })
		
	(3)获取路径参数
		this.$route.params.id

6、监听路由变化
	当使用路由参数时,例如从/user/foo导航到/user/bar,原来的组件实例会被复用。意味着组件的生命周期钩子不会再被调用。
	  watch: {
	    $route(to, from) {
			...
	    }
	  }
	   this.$watch(
	      () => this.$route.params,
	      (toParams, previousParams) => {
	        ...
	      }
	    )
	  或路由守卫:
	    beforeRouteUpdate(to, from, next) {
	    	...
	    	next();
	  }

7、404路由
	const routes = [
	  { path: '/users/:id', component: User },
	  创建可捕获参数的路由
	  pathMatch是参数的名称,例如,跳转到/not/found会得到,{ params: { pathMatch: ['not', 'found'] } }
	  pathMatch(.*)*:末尾的*表示重复的意思,若没有,在解析或跳转时,参数中的 `/` 字符将被编码,即not/found=>/not%2Ffound'
	  { path: '/:pathMatch(.*)*', name: 'NotFound', component: NotFound }, 将匹配所有内容并将其放在 `$route.params.pathMatch` 下
	  { path: '/user-:afterUser(.*)', component: UserGeneric }, 	将匹配以`/user-`开头的所有内容,并将其放在 `$route.params.afterUser` 下
	]
	
8、路由过渡动效
	<router-view v-slot="{ Component }">  插槽原理,v-slot向外暴露组件中的内容
	
	  <transition name="fade">
	    <component :is="Component" />
	  </transition>
	  
	</router-view>
	
	根据meta展示不同动效
	const routes = [
	  {
	    path: '/custom-transition',
	    component: PanelLeft,
	    meta: { transition: 'slide-left' },
	  },
	  {
	    path: '/other-transition',
	    component: PanelRight,
	    meta: { transition: 'slide-right' },
	  },
	]
	
	<router-view v-slot="{ Component, route }">
	
	  <transition :name="route.meta.transition || 'fade'">
	    <component :is="Component" />
	  </transition>
	</router-view>

9、监听滚动行为
	当切换到新路由时,想要页面滚到顶部,或者是保持原先的滚动位置等功能
	const router = createRouter({
	  history: createWebHashHistory(),
	  routes: [...],
	  scrollBehavior (to, from, savedPosition) {
	   	savedPosition 由浏览器的后退/前进按钮触发时才能使用
	   	
	   	return savedPosition;	在按下后退/前进按钮时,就会像浏览器的原生表现那样
	   	return false或{}	不会发生滚动
	   	return { top: 0,behavior: 'smooth', }	返回滚动位置,behavior可设置滚动动画('instant'|'auto')
	   	return {
	   		el:选择器或dom元素,
	   		top,left		基于选中元素的偏移位置
	   	}
	   	return {
	   		el: to.hash,	如果hash用作了锚点,可实现滚动到锚点的功能
	   	}
	   	延迟滚动
   	    return new Promise((resolve, reject) => {
	      setTimeout(() => {
	        resolve({ left: 0, top: 0 })
	      }, 500)
	    })
	    
	  }
	})

10、路由懒加载
	不要在路由中使用异步组件,异步组件仍然可以在路由组件中使用,但路由组件本身就是动态导入的。
	
	const UserDetails = () => import('./views/UserDetails')
	把某个路由下的所有组件都打包在同个异步块(chunk)中
	const UserDetails = () =>
	  import(/* webpackChunkName: "group-user" */ './UserDetails.vue')
	  
	const router = createRouter({
	  routes: [{ path: '/users/:id', component: UserDetails }],
	})

11、动态添加|删除路由
	const router = createRouter({
	  history: createWebHistory(),
	  routes: [{ path: '/:articleName', component: Article }],
	})
	(1)新增路由
		router.addRoute({ path: '/about', component: About })
		
		如果新增加的路由与已有路由位置相匹配,就需要用router.push()或router.replace()来手动导航
			await router.replace(router.currentRoute.value.fullPath)
			也可以使用this.$route或route = useRoute()
		
		如果添加的路由name和原有路由相同,会删除原有路由
			router.addRoute({ path: '/about', name: 'about', component: About })
			这将会删除之前已经添加的路由
			router.addRoute({ path: '/other', name: 'about', component: Other })
		
		添加嵌套路由
			将路由的name作为第一个参数传递
			router.addRoute('admin', { path: 'settings', component: AdminSettings })

	(2)在导航守卫中添加路由
		router.beforeEach(to => {
		  if (...) {
		    router.addRoute({...})
		    
		    触发重定向,如果新添加的路由记录将与to位置相匹配,实际上导致与我们试图访问的位置不同
		    return to.fullPath
		  }
		})
		
	(3)删除路由
		方式一:
			const removeRoute = router.addRoute(routeRecord)
			removeRoute() 	删除路由如果存在的话,当路由没有名称时,这很有用
			
		方式二:	
			router.removeRoute('about')	通过路由name进行删除
	
	(4)查看路由
		router.hasRoute():检查路由是否存在。
		router.getRoutes():获取一个包含所有路由记录的数组。

代码示例:
main.js:

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import Axios from 'axios'
import VueRouter from 'vue-router'
import HelloWorld from './components/HelloWorld'

Vue.use(VueRouter)
Vue.config.productionTip = false


const router=new VueRouter({
	routes:[
		{
			path:'/hello',
			name:"HelloWorld",
			component:HelloWorld

		}
	]
})

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})


App.vue:

<template>
  <div id="app">
    <img src="./assets/logo.png">
    <router-view />
  </div>
</template>

<script>

export default {
  name: 'App',
  data()
  {
    return{
      
    }
  }
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

嵌套路由:

import Vue from 'vue'
import VueRouter from 'vue-router'
import HelloWorld from '../components/HelloWorld'
import C from '../components/C'
import D from '../components/D'
import A from '../components/A'
import B from '../components/B'


Vue.use(VueRouter)

export default new VueRouter({
	routes:[
		{
			path:'/hello',
			name:"HelloWorld",
			component:HelloWorld

		},
		{
			path:'/c',
			name:'C',
			component:C,
			//子路由
			children:[
				{
					path:'cc',
				
					component:A,
					//子子路由
					children:[
							{
								path:'ccc',
							
								component:A
							}
						]
				}
			]
		},
		{
			path:'/d/:name',
			name:'D',
			component:D,
			//子路由
			children:[{
				path:"dd",
				component:B
			}]
		}
	]
})
===============================父路由组件
<template>
  <div id="app">
    <img src="./assets/logo.png">
    <ul>
      <router-link to='/d/jeff'>d</router-link>
      <router-link to='/c'>c</router-link>
    </ul>
    //主路由的显示
    <router-view />
  </div>
</template>

<script>
import Vuedemo from './components/Vuedemo'
import Vue1 from './components/Vuee'
import A from './components/A'
import B from './components/B'
import D from './components/D'

export default {
  name: 'App',
  data()
  {
    return{
      
    }
  },
  methods:{
    

  },
  components: {
    Vuedemo,
    Vue1,
    A,
    B,
    D
  }
}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

=======================子路由组件
<template>
	<div>

		ccc
		<ul>
			<router-link to="/c/cc">c的子路由</router-link>
		</ul>
		<router-view />
	</div>

</template>

<script>
export default{
	name:'c',
	data()
	{
		return{
			
		}
	}
}
</script>

<style lang='css'>

</style>

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue 3 中,你可以使用 Vue Router 进行由跳转。下面是一些基本的步骤: 1. 首先,确保你已经安装了 Vue Router。你可以通过运行以下命令来安装它: ``` npm install vue-router@next ``` 2. 在你的主文件(例如 `main.js` 或 `main.ts`)中导入 Vue Router 和你的由配置: ```javascript import { createApp } from 'vue'; import { createRouter, createWebHistory } from 'vue-router'; import App from './App.vue'; import Home from './views/Home.vue'; import About from './views/About.vue'; const routes = [ { path: '/', component: Home }, { path: '/about', component: About } ]; const router = createRouter({ history: createWebHistory(), routes }); const app = createApp(App); app.use(router); app.mount('#app'); ``` 在上面的示例中,我们创建了两个由:`/` 对应 `Home` 组件,`/about` 对应 `About` 组件。你可以根据自己的需求添加更多的由。 3. 在你的组件中使用由跳转,你可以使用 `<router-link>` 组件或 `$router.push` 方法。 使用 `<router-link>` 组件: ```html <router-link to="/">Home</router-link> <router-link to="/about">About</router-link> ``` 使用 `$router.push` 方法: ```javascript // 在方法中调用 methods: { goToHome() { this.$router.push('/'); }, goToAbout() { this.$router.push('/about'); } } // 或者在模板中调用 <button @click="$router.push('/')">Go to Home</button> <button @click="$router.push('/about')">Go to About</button> ``` 这样,当用户点击链接或按钮时,由就会进行跳转。 这只是一个基本的示例,你还可以使用更多的 Vue Router 功能,如由参数、嵌套由、由守卫等。你可以参考 Vue Router 的官方文档来了解更多信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值