Vue-Router
- npm i vue-router --save (如果上线以后还需要使用该模块加 --dev)
- 作用:实现单页面鞥带组件之间的跳转效果
- 配置:
- 创建独立的Router文件夹,并在文件夹下创建index文件
- import Vue from ‘vue’
- import Router from ‘vue-router’
- Vue.use(Router) // 配置Vue - Router
- const router = new Router({ 路由匹配规则代码 })
- export defoult router
- 在main.js文件中引入
- import router from ‘路径’
- 创建独立的Router文件夹,并在文件夹下创建index文件
import Vue from 'vue'
import Router from 'vue-router'
// 对应想要现实的页面
import A from '../components/A.vue'
import B from '../components/B.vue'
import C from '../components/C.vue'
Vue.use(Router)
const router = new Router({
// 路由匹配规则代码
routes: [
{
// 重定向:当什么都不输的时候,就会自动跳转到指定页面
path: '/',
redirect: '/a'
},
{
// path后的
path: '/a',
component: A
},
{
path: '/b',
component: B
},
{
path: '/c',
component: C
},
]
})
export default router
路由传参
-
在router、index.js文件的路由规则中指定参数名称:XXX
{ path:'/b/:myid' component:B }
-
在B.vue中获取XXX的值
this.$route.params.XXX
-
在router-link标签上添加myid的实参
<router-link to = '/b/112233'>跳转</router-link>
方法二(不常用)
-
在router-link标签上添加XXX的实参
<router-link to = '/a?XXX=123'></router-link> 或 <router-link :to="{path:'/a' , query:{XXX:123}}"></router-link>
-
在A.vue中获取id的值
this.$route.query.XXX
二级目录跳转
- 注:如果一级目录上有参数,则需要传三层
const router = new Router({
routes: [
{
// 重定向:当什么都不输的时候,就会自动跳转到指定页面
path: '/',
redirect: '/a/:myid'
},
{
path: '/a/:myid',
component: A,
// 二级菜单
children: [
{
path: 'one_son',
component: son1
},
{
path: 'two_son',
component: son2
}
]
},
]
})
-
父页面包含跳转的子页面(因父页面含有参数,所以变成了三级目录)
<router-link to="/a/123/one_son">儿子1</router-link> <router-link to="/a/123/two_son">儿子2</router-link>
-
别名
aliasL:‘名字’
编程式导航
- push()能够保留历史记录的跳转
- this.$router.push(’/a/123’)
- this.$router.push({path:’/a’})
- this.$router.push({name:‘A’,params:{id:123}})
- replace()不保留历史记录的跳转(无法回退)
- this.$router.replace(‘参数与push一样的’)
- go()基于有历史记录的情况进行跳转
- this.$router.go(X) 前进X页
- this.$router.go(-X) 后退X页
命名视图
场景:一个页面中需要同时显示多个子组件,也就是说一个path多个组件
用法:假设给B组件里添加多个二级路由的命名视图
组件间信息传递
一个组件既要接收来自父组件的数据Props,又想要接受来自路由的数据Params
-
传递数据
<router-link :to="{ name:'C', params: { ids: 123 } }" active-class=" myLink">跳转C</router-link>
-
在router/index.js文件中给C组件添加props属性
{ path: '/c/:ids', component: C, name:'C', props: true },
-
在C组件中可以直接用Props来就收参数了
export default { props:['ids'] }
路由的模式(面试题)
Hase模式:地址栏始终有一个#,原理是锚链接【默认】
History模式:原理是H5的history机制,没有#,优点:利于SEO,缺点:服务器必须配置对应路径
- 例如:’/a/menu’会被服务端拦截到,当作服务端的URL地址,于是返回404
- 例如:’/#/a/ment’不会被服务端拦截
new Router({
model:history
})
路由懒加载(面试题)
含义:当我们访问这个地址的时候,采取加载这个对应的组件,不访问也就不加载了
语法
{
path:'list',
component:()=>import('路径')
}
路由守卫
路由跳转前做一些验证,比如登陆验证,也是网站的普遍要求
全局守卫:routes/index.js里
const router = new Router({......})
// 路由前置首位
router.afterEach((to,from,next)=>{
console.log(`从哪来:${to.path}`)
console.log(`到哪去:${from.path}`)
next(); // 执行下一个钩子
next(false); // 中断
next('/XXX'); // 跳转到
})
// 路由后置守卫
router.afterEach((to,from)=>{
console.log(`从哪来${to.path}`);
console.log(`到哪去${from.path}`);
})
路由独享守卫:routes/index.js里
{
path:'/c/:title',
component:C,
beforeEnter(to,from,next){
console.log('---C组件的路由独享守卫---');
console.log("从哪儿来:",from.path)
console.log("去哪儿:",to.path)
next();
}
}
组件内部守卫:写在C.vue文件中
export default {
name:'C',
beforeRouteEnter(to,from,next){
console.log('---C组件内部守卫:渲染当前组件时触发---')
next();
},
beforeRouteUpdate(to,from,next){
console.log('---C组件内部守卫:参数更新时触发---')
next();
},
beforeRouteLeave(to,from,next){
console.log('---C组件内部守卫:离开当前组件时触发---')
next();
}
}
配置原信息
-
配置原信息
const router = new Router({ routes:[ { path: '/a/:myid', component: A, meta: { title: '首页', keepalive: true }, } ] })
-
在路由守卫中动态修改网页的标题
// 路由前置守卫 router.beforeEach((to, from, next) => { document.title = to.meta.title next() })
-
给router-view添加是否缓存
<keep-alive v-if='$router.meta.keepAlive'> <router-view></router-view> </keep-alive> <router-view v-else></router-view>
常见问题
-
不允许跳转到自身路径上,通过catch消除这个历史遗留BUG
答:this.$router.replace(url).catch(err => err)
-
如果img的src是动态加载的如何渲染?
需要使用requery进行动态导入才可以,例如:<img :src=‘requery(xxx.jpg)’
-
编程导航中不允许重复跳转到同一个路径上,会报错?
通过catch消除这个历史遗留bug: this.$router.replace(url).catch(err=>err)
Vuex
Vuex是一个专为Vue.js应用程序开发的状态管理模式。
含义:集中式的数据管理仓库
场景:数据共享的时候,比如:登录状态,个人信息,账号信息
Vuex的四大核心模块
state:状态【存储数据的地方】
getters:查询【查询数据的函数】
mutations:修改数据【修改数据的唯一途径】
action:业务处理【和mutations最大的区别在于action可以写异步代码】
关于Vuex的使用
-
安装Vuex
-
npm i vuex --save
-
-
在src下建一个store文件夹,并创建入口文件index.js
-
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store
-
在main.js中引入
import store from './store/import' Vue.config.productionTip = false new Vue({ store, render: h => h(App), }).$mount('#app')
-
-
使用
export default new Vuex.Store({ state: { eat: ['橘子', '香蕉', '苹果'] }, getters: { getEat(state) { return state.eat } }, mutations: {}, actions: {} })
<template> <div> <p v-for="(value, index) in cat" :key="index">{{ value }}</p> </div> </template> <script> export default { computed: { cat() { return this.$store.getters.getEat; }, }, }; </script>
-
添加/修改
export default new Vuex.Store({ state: { eat: ['橘子', '香蕉', '苹果'] }, getters: { getEat(state) { return state.eat } }, mutations: { addEat(state,product){ state.eat.push(product) } }, actions: {} })
<template> <div> <input type="text" v-model="my_text" /> <button @click="gogo">添加</button> </div> </template> <script> export default { name: "add", data() { return { my_text: "", }; }, methods: { gogo() { this.$store.commit('addEat', this.my_text); }, }, }; </script>
-
异步修改
在显示页面写入 <script> export default { computed: { cat() { return this.$store.getters.getEat; }, }, mounted() { // 1. 调用store/import.js的actions的loadEat方法 this.$store.dispatch("loadEat"); }, }; </script>
在js文件中 mutations: { addEat(state, product) { state.eat.push(product) }, setEat(state, list) { // 4. 赋值 state.eat = list } }, actions: { loadEat(context) { setTimeout(() => { // 2. 异步获取数据 var res = ['橘子', '香蕉', '苹果'] // 3. 调用mutations的setEat方法传参 context.commit('setEat', res) }, 2000) } } })
辅助函数
原始写法
computed: {
cat() {
return this.$store.getters.getEat;
},
},
辅助函数写法 -- 从State里面获取
import { mapState } from "vuex";
computed: mapState({
cat: "eat",
}),
辅助函数写法 -- 从Getters里面获取
import { mapGetters } from "vuex";
computed: mapGetters({
// cat定义计算属性的名字,getEat:store仓库Getters的函数名
cat: "getEat",
}),