新建一个带router和vuex的项目。Router和store的文件在main.js中被引入,在new Vue时传入
Vue Router
Vue Router是 vue 官方的路由管理器,监测URL的变化,在页面中渲染相对应的内容
router 文件引入vue和Vue Router库,通过Vue.use引入官方router插件,配置具体路由后通过new VueRouter创建新的实例,将实例导出。
Vue Router 支持多种路由模式,除了常见的 hash 和 history 模式外,还包括非浏览器环境的 memory 模式和 abstract 通用模式。
hash 和 history
常见的 hash 和 history 模式的主要区别在于 URL 的表现形式和浏览器历史记录的处理方式。
-
Hash 模式:
- URL 表现形式:URL 中的
#后面跟随的是路由路径,例如http://example.com/#/home。 - 兼容性:兼容性较好,可以兼容所有浏览器,包括较老的浏览器。
- 页面刷新:当用户直接访问一个 hash URL 时,页面会重新加载,因为浏览器会认为这是一个锚点跳转。
- 浏览器历史:不利用浏览器的历史记录,而是使用 URL 中的 hash 值来管理路由状态。
- URL 表现形式:URL 中的
-
History 模式:
- URL 表现形式:URL 看起来像普通的 SPA(单页应用)URL,例如
http://example.com/home,没有#。 - 兼容性:需要浏览器支持 HTML5 History API。
- 页面刷新:当用户直接访问一个 history 模式的 URL 时,页面不会重新加载,因为浏览器会将 URL 视为页面的正常路径。
- 浏览器历史:利用浏览器的历史记录 API (
pushState和replaceState) 来管理路由状态,可以添加记录、替换记录等。
- URL 表现形式:URL 看起来像普通的 SPA(单页应用)URL,例如
路由相关基本使用
新建项目的默认页面使用了router-link(a标签) + router-view(路由占位符,是用来显示匹配当前路由组件内容的视图窗口)
router-link的两种使用方式
<router-link to="/about">About</router-link>
<router-link :to="{ name: 'about' }">About</router-link>
新建页面或组件,基本路由的使用步骤:
- views文件夹内新建文件,布置页面内容
- router文件夹下index.js配置文件内配置新页面的路由及其相应组件
- App.vue内设置router-link跳转
路由相关其他使用
动态路由
例如,我们可能有一个 User 组件,它应该对所有用户进行渲染,但用户 ID 不同。这时,我们可以在路径中使用一个动态字段来实现,我们称之为 路径参数 ,路径参数 用冒号 : 表示,如
//在router 的 index.js 配置文件中设置路由
path :'/about/:id'
//并设置在相应的组件内部允许接收路径参数的值
props : ture
//.vue文件中,可以利用props接收,并使用插值表达式{{ id }}应用到页面中
props: ['id']
//也可以直接使用
<p>{{ $route.params.id }}</p>
<router-link to="/about/30">About</router-link>
<router-link :to="{ name: 'about', params:{ id : 28 } }">About</router-link>
嵌套路由
如添加二级路由子组件。配置方式 : router的index.js中相关路由添加配置项children数组,其中需要包含多条子路由(子路由也包含 path、name、components等结构,组件在顶部由import引入)
编程式导航
通过登录、支付等状态进行判断,在代码中重定向跳转,如
this.$router.push({ name : '/' })
跳转时的数据传递
this.$router.push({ name: "home", query: { id: 100 } });
//通过$route接收
console.log(this.$route.query)
$router 和$route
$route 是当前的被激活路由。它包含了路由的信息,比如当前的路径、路由参数、查询参数、路由名称等。$route 是只读的。
常见的$route属性
- path: 当前路由的路径字符串。
- params: 动态路径参数,例如 /user/:id 中的 id。
- query: 查询参数,例如 /user?id=123 中的 id。
- name: 当前路由的名称(如果有的话)。
- hash: 当前路由的 hash 值。
- fullPath: 完整的 URL 解析后的路径,包括 query 和 hash。
- matched: 一个数组,包含当前路由匹配的所有路由记录(route records)
$router 是整个应用的路由器实例,它包含了导航的方法和路由配置。你可以通过 $router 来编程式地导航到不同的路由,或是执行其他与路由相关的操作。
常见的 $router 方法
- push(location): 导航到一个新的路由。location 可以是一个字符串路径或者一个描述目标路由的对象。
- replace(location): 与 push 类似,但不会在导航历史中留下记录。
- go(n): 在浏览器历史记录中前进或后退 n 步。
- back(): 导航到上一个路由。
- forward(): 导航到下一个路由。
- beforeEach(callback): 注册一个全局前置守卫。
- afterEach(callback): 注册一个全局后置守卫。
导航守卫
导航守卫用于控制路由的访问权限。
全局导航守卫:
- 作用:
- 全局前置守卫 (beforeEach):在每次路由跳转前进行全局的权限验证、登录状态检查等操作。
- 全局解析守卫 (beforeResolve):在导航被确认前执行,通常用于确保路由的异步操作完全解析。
- 全局后置守卫 (afterEach):在导航完成后执行,可用于页面统计、日志记录等操作。
- 应用场景:
- 权限控制:验证用户权限,确保用户有访问特定页面的权限。
- 页面加载提示:在页面切换过程中展示加载动画或进度条。
- 路由拦截:阻止用户访问某些页面或执行某些操作。
- 路由解析:确保路由的解析完全,处理可能的异步操作。
const router = createRouter()
router.beforeEach((to, from, next) => {}) //定义全局前置守卫beforeEach()
router.afterEach((to, from, next) => {}) //定义全局后置守卫afterEach()
每个全局导航守卫方法中接收3个形参:to、from和next。
- to:表示目标路由对象;
- from:表示当前导航正要离开的路由对象;
- next:next为函数,如果不接收next()函数,则默认允许用户访问每一个路由;如果接收了next()函数,则必须调用next()函数,否则不允许用户访问任何一个路由。注意:next()函数具有3种调用方式,分别为next()、next(false)和next('/'),其中,next()表示执行下一个钩子函数;next(false)表示强制停留在当前页面;next('/')表示跳转到其他地址。
组件级别的导航守卫:
- 作用:
- beforeRouteEnter:在进入当前组件前执行,适合获取数据等操作。
- beforeRouteUpdate:在当前路由改变,但是路由所属组件被复用时执行。
- beforeRouteLeave:在离开当前组件时执行,可以用于确认离开前的操作。
- 应用场景:
- 数据获取:在进入组件前获取数据,确保组件渲染时数据已准备好。
- 条件判断:根据路由变化进行特定逻辑的处理。
- 离开确认:在用户离开组件前进行确认操作,如弹窗提醒或数据保存。
路由独享的守卫:
- 作用:
- 为特定路由设置独立的导航守卫,与全局导航守卫有区别。
- 应用场景:
- 针对某些特定页面需要额外的导航逻辑或处理时使用。
- 可以在具体路由级别上进行更细粒度的控制和定制。
Vuex(store)
Vuex 是 vue 官方的状态管理工具,如果有多个组件需要同一状态切换的话,vuex就可以来做全局的状态管理
store 文件引入vue和vuex文件库,通过Vue.use引入官方vuex插件,配置后通过new Vue.Store创建了新的实例,将实例导出
store提供了五个功能
state() {
// 数据存储,声明类似data 用this.$store.state.loginStatus引用
return{
loginStatus :'登陆状态'
}
},
getters: {
//计算属性,有缓存功能
len(state){
return state.loginStatus.length
}
//.vue文件中
this.$store.getters.len
},
mutations: {
//数据更改,声明类似methods,使用时通过commit的方式提交更改,修改时必须是同步的
changeLoginStatus(state,new){
state.loginStatus = new
}
//.vue文件中
this.$store.commit('changeLoginStatus',new)
},
actions: {
//异步包装,将异步函数进行包装后再进行修改,在调试工具的时间线中方便进行时间线的逻辑分析
delayChange(store,num){
setTimeout(() => {
store.commit('changeLoginStatus',num)
}, 3000);
}
//.vue文件中
this.$store.dispatch('delayChange',new)
},
modules: {
//将store中各类参数分组,用this.$store.a.state.loginStatus引用
a : { loginStatus,... }
b : { userStatus,... }
}
封装(作业)
在store模块里建 modules文件夹,分a.js b.js 分别包含getter、actions等(不包含vue实例),在实例中(store/index.js)配置modules,分别引入a与b的相关内容
eslint实在太变态了
少一个空格多一个空行有多余的逗号双引号什么的都会报错,单独设置总有遗漏,索性直接一整个禁用