切换路由
- 导入router,调用push方法
1 | <script> |
知识点:
- 当前访问路径可以通过window.location.pathname 获取
- import的时候,如果目录下只有一个index.js,可以写成import router from ‘./router’ 而不用写成 import router from ‘./router/index.js’
router-view监听子组件的事件
如果有多层组件,子组件的事件只能一层层往上冒泡,顶层不能直接监听到子组件的事件。
栗子:App.vue 包含了Home.vue,Home.vue包含了组件swiper
1.swiper向Home.vue组件传递事件img-click
1 | <template> |
2.Home.vue监听到img-click事件,向App.vue传递事件home-click
1 | <template> |
3.App.vue不能直接监听到img-click事件,只能监听Home.vue的home-click事件,监听到事件后,路由跳转到/about页面
1 | <template> |
注意点:
- 路由的监听事件是写在router-view中,而不是router-link
嵌套路由
- 配置路由的children属性,是一个数组
- 在页面中使用
才能显示子页面 - 使用children属性配置的路由,只有在父页面的router-view才能显示
栗子:在Detail页面中,跳转到Detail页面的子页面SubDetail
1.Detail.vue
1 | <template> |
2.SubDetail.vue
1 | <template> |
3.路由配置
这里配置的sub-detail只有在/detail页面的
1 | const routes = [ |
一种更好的做法是:
不配置children属性,而是配置成平行的。子组件通过传递同一个自定义事件到最上层,通过自定义事件将路由传递到最上层,统一由最上层的事件进行router的跳转。
栗子:App.vue是最上层,监听着子组件的home-click事件。
Home.vue 和 Detail.vue 都可以通过向App.vue传递home-click自定义事件,带上自己跳转的路由参数,统一由App.vue进行路由的跳转。
1.App.vue
1 | <router-view @home-click="onImgClick"/> |
2.Home.vue
1 | <swiper :src="pic" :alt="漂亮的图片" @img-click="onHomeClick"></swiper> |
3.Detail.vue
1 | <button @click="goSubPage">点击去到子页面</button> |
路由参数
1.定义路由参数 :参数名 , 如果定义了参数而不传参,会找不到路由,出现空白页面
1 | const routes = [ |
2.传递参数
1 | function onHomeClick () { |
3.接收参数
通过router可以获取到当前路由currentRoute,再通过value.params.参数名获取路由参数
1 | console.log(router.currentRoute.value.params.id) |
命名路由
可以通过name来当路由,写法是一个对象
1 | context.emit('home-click', { |
跳转路由时可以直接将子组件传递的对象当为参数。但是需要保证每个子组件传递的参数格式一致。
1 | function onImgClick (event) { |
组件切换的几种方法
- 使用router
- 使用v-if隐藏显示
- 使用
动态组件
动态组件和缓存组件的状态
1 | <template> |
currentPage属性控制着应该显示哪个组件。通过按钮点击动态改变currentPage的值,达到动态切换组件。
注意,这里的currentPage应该是响应式对象才能切换。
当组件切换后,原有组件的值不会被保存。此时可以使用keep-alive来缓存切换前组件的值。
keep-alive有两个属性include和exclude,可以根据组件的name来包含或排除应该缓存的组件。
注意,这里组件的值是大小写敏感的。多个组件的值可以使用,分割。
全局状态变量传参
在store中定义方法,在其他组件中使用store.commit方法触发方法,并传递参数。
方法的第一个参数为store中定义的state
- 传递单个参数
store:
1 | export default createStore({ |
app.vue:
1 | function changeView (url) { |
- 传递多个参数
store:多个参数使用payload接收
1 | export default createStore({ |
App.vue:commit的时候使用对象传递多个参数,这里使用的是ES6的语法。
1 | function changeView (url) { |
commit的参数也能写成一个对象的形式,使用type属性指明要触发的函数:
1 | function changeView (url) { |
通过全局参数切换路由
之前的切换路由的方法,如果一个页面包含很多子组件,只能一层层往上传递事件。
使用全局参数,可以实现切换路由。思路如下:
- 在子组件中修改全局参数的值
- 在父组件监听全局参数的值,一旦发生改变,通过router.push完成路由切换
1.子组件Home.vue修改全局参数url的值
1 | function onHomeClick () { |
直接修改state的方式太粗暴了,可以通过传参的方式改变全局参数的值:
1 | function onHomeClick () { |
当然,在全局参数store的文件中:
1 | export default createStore({ |
2.父组件中不再使用事件,直接监听全局参数的值
1 | watch(() => store.state.url, (newVal, oldVal) => { |
也可以通过监听computed properties:
1 | const targetRoute = computed(() => store.state.url) |
带参数的全局参数路由跳转
设置一个对象类型的全局参数,其格式与router.push的参数相同。当子组件设置全局参数时,直接监听全局参数的改变,跳转路由。
store:
1 | export default createStore({ |
子组件设置全局参数,参数的形式与router.push的参数格式一致
1 | function onHomeClick () { |
在App.vue中监听全局参数的变化,跳转路由:
1 | watch(() => store.state.routerParams, (newVal, oldVal) => { |