资讯中心

Vue 高级开发:状态管理、路由系统、插件与登录权限控制

📅 2026/8/26 18:16:48
Vue 高级开发:状态管理、路由系统、插件与登录权限控制
一、组件通信方式回顾Vue 组件之间可以通过多种方式通信父传子使用props子传父使用$emit父组件需要命令式操作子组件时可以使用$refs。数据层级较深、多个页面共同使用的数据则更适合交给 Vuex 或 Pinia 管理。二、混入 mixin混入用于抽取多个组件重复的选项例如相同的data、方法和生命周期逻辑。组件引入混入后混入对象会与组件自身的选项合并如果发生同名冲突组件自身的选项优先生命周期钩子则会依次执行。// src/mixins/userMixin.jsexportdefault{data(){return{userName:访客}},methods:{resetUserName(){this.userName访客}}}script import userMixin from /mixins/userMixin export default { name: ProfileView, mixins: [userMixin] } /script也可以在main.js中使用Vue.mixin()注册全局混入但全局混入会影响每个组件容易产生隐式依赖和命名冲突。除非是非常通用的逻辑否则优先使用局部混入或组合式工具函数。三、Vue 插件插件用于给 Vue 增加全局能力例如注册组件、注册自定义指令、添加原型方法或混入公共逻辑。插件本质上通常是包含install(Vue, options)方法的对象调用Vue.use(plugin)时 Vue 会自动执行它。// src/plugins/http.jsimportaxiosfromaxiosconsthttpaxios.create({baseURL:http://127.0.0.1:8000,timeout:5000})exportdefault{install(Vue){// Vue 2 中通过原型提供 this.$http。Vue.prototype.$httphttp}}// main.jsimportVuefromvueimportAppfrom./App.vueimporthttpPluginfrom/plugins/httpVue.use(httpPlugin)newVue({render:hh(App)}).$mount(#app)组件中可以通过this.$http.get(...)使用插件提供的能力。自定义指令也可以在插件中注册Vue.directive(focus,{inserted(element){element.focus()}})第三方库如 Vue Router、Vuex 和 Element UI 也都是通过Vue.use()接入。插件注册的全局能力应使用$前缀命名以减少与组件数据和方法冲突的可能。四、插槽回顾默认插槽和具名插槽可以让父组件向子组件注入内容。子组件控制整体布局父组件提供标题、正文或按钮等变化内容这种方式适合卡片、弹窗和布局组件。!-- AboutView.vue -- template ContentCard template slotheaderh2关于页面/h2/template p这里是父组件传入的正文。/p template slotfooterbutton确定/button/template /ContentCard /template!-- ContentCard.vueVue 2 写法 -- template section classcard headerslot nameheader默认标题/slot/header mainslot默认内容/slot/main footerslot namefooter/slot/footer /section /template五、Vuex 状态管理Vuex 是 Vue 2 项目常用的集中式状态管理工具。它把多个组件共享的数据放在 store 中通过明确的mutations修改状态通过actions处理异步操作或业务流程。Vue 3 项目也可以使用 Vuex但新项目通常优先考虑 Pinia。1. 创建 store// src/store/index.jsimportVuefromvueimportVuexfromvuexVue.use(Vuex)exportdefaultnewVuex.Store({state:{count:100},getters:{doubleCount(state){returnstate.count*2}},mutations:{add(state,amount){state.countamount}},actions:{addCount({state,commit},amount){if(state.countamount105)returncommit(add,amount)}}})state保存共享数据getters负责派生数据mutations是同步修改状态的唯一推荐入口actions可以包含异步逻辑并通过commit提交 mutation。不要在组件中直接修改this.$store.state否则状态变化很难追踪。2. 在入口注册 store// main.jsimportVuefromvueimportAppfrom./App.vueimportstorefrom./storenewVue({store,render:hh(App)}).$mount(#app)3. 组件中使用template div p数量{{ $store.state.count }}/p p两倍数量{{ $store.getters.doubleCount }}/p button clickincrease增加/button /div /template script export default { methods: { increase() { this.$store.dispatch(addCount, 1) } } } /script小型项目不必把所有变量都放入 Vuex。只有跨多个页面或多个组件共享、且需要统一修改规则的状态才适合集中管理。六、本地存储浏览器常见的存储方式有三种Cookie 可设置过期时间并会随请求发送sessionStorage只在当前标签页会话中有效localStorage会长期保存除非主动删除或清理站点数据。三者都不适合保存密码等高敏感信息。localStorage和sessionStorage只能保存字符串数组或对象需要先序列化constuser{name:lqz,age:19}localStorage.setItem(user,JSON.stringify(user))constsavedUserJSON.parse(localStorage.getItem(user)||{})sessionStorage.setItem(draft,临时内容)sessionStorage.removeItem(draft)localStorage.removeItem(user)封装存储方法可以统一处理 JSON 和异常exportfunctionsetStorage(key,value){localStorage.setItem(key,JSON.stringify(value))}exportfunctiongetStorage(key,fallbacknull){constvaluelocalStorage.getItem(key)if(valuenull)returnfallbacktry{returnJSON.parse(value)}catch{returnvalue}}登录 token 的保存方式要结合安全策略选择。localStorage使用简单但 XSS 可能读取其中的 tokenHttpOnly Cookie 能降低脚本读取风险但需要配合 CSRF 防护。不要把“永久保存”误认为“安全保存”。七、Vue Router 基础Vue Router 负责把 URL 映射到页面组件。router-view是页面组件的显示位置router-link是声明式导航组件this.$router用于 JavaScript 跳转this.$route表示当前路由信息。1. 安装和配置# Vue 2 对应 Vue Router 3npminstallvue-router3// src/router/index.jsimportVuefromvueimportVueRouterfromvue-routerimportHomeViewfrom/views/HomeView.vueimportAboutViewfrom/views/AboutView.vueVue.use(VueRouter)exportdefaultnewVueRouter({mode:history,routes:[{path:/,name:home,component:HomeView},{path:/about,name:about,component:AboutView}]})!-- App.vue -- template div idapp router-link to/首页/router-link router-link to/about关于/router-link router-view / /div /template入口文件需要把 router 注入根实例importrouterfrom./routernewVue({router,render:hh(App)}).$mount(#app)2. 路由跳转与参数查询参数适合筛选、分页等可选信息路径参数适合表示资源标识。查询参数不会改变路由匹配组件路径参数通常写在路由路径中。// JavaScript 跳转this.$router.push({name:about,query:{name:张三,age:19}})this.$router.push({name:user,params:{id:10}})// 路由配置路径参数{path:/user/:id,name:user,component:UserView}// UserView.vue 中读取constidthis.$route.params.idconstnamethis.$route.query.namepush会新增浏览历史replace会替换当前记录back()和go(-1)可以返回上一页。路由参数来自地址栏不应直接当作权限依据敏感操作仍需后端认证。八、嵌套路由后台管理页面通常共享顶部和侧边栏只替换右侧内容这时可以使用嵌套路由。父组件必须放置router-view子路由才有渲染位置。constroutes[{path:/backend,component:()import(/views/BackendView.vue),children:[{path:,component:()import(/views/backend/IndexView.vue)},{path:orders,component:()import(/views/backend/OrderView.vue)},{path:goods,component:()import(/views/backend/GoodsView.vue)}]}]!-- BackendView.vue -- template div classbackend aside router-link to/backend首页/router-link router-link to/backend/orders订单/router-link router-link to/backend/goods商品/router-link /aside mainrouter-view //main /div /template九、路由守卫与登录保护路由守卫在页面跳转前执行可以检查 token、用户角色或权限。守卫只负责前端导航体验真正的接口权限必须由后端再次校验。router.beforeEach((to,from,next){constrequiresAuthto.matched.some(recordrecord.meta.requiresAuth)consttokenlocalStorage.getItem(access)if(requiresAuth!token){next({name:login,query:{redirect:to.fullPath}})}elseif(to.namelogintoken){next({name:home})}else{next()}})需要保护的路由通过meta标记{path:/backend,component:BackendView,meta:{requiresAuth:true}}登录成功后可以读取redirect查询参数返回用户原本要访问的页面但应限制跳转为本站路径避免开放重定向。十、Hash 与 History 模式Hash 模式使用 URL 中#后的内容表示前端路由例如/#/about。浏览器不会把 hash 发送给服务器因此部署简单、兼容性好但地址不够简洁。History 模式使用正常路径例如/about地址更美观但刷新页面时服务器必须将未知路径回退到index.html否则会出现 404。选择模式时要同时考虑前端需求和后端部署配置。十一、总结与练习Vuex 适合管理跨组件、跨页面的共享状态状态修改应通过 mutation/action 进行。localStorage、sessionStorage和 Cookie 的生命周期不同保存 token 时要结合 XSS、CSRF 和过期策略。Vue Router 通过router-view渲染页面使用 query 或 params 携带路由参数。嵌套路由适合后台布局路由守卫可以改善登录跳转但不能替代后端权限校验。建议实现一个带登录保护的后台管理页面登录后进入嵌套路由刷新仍能恢复 token退出后所有受保护路由都跳回登录页。