• Vue全家桶__Vue-router&Vuex


    前介

    多页应用 MPA 每一个页面都是一个.html文件 SEO优化

    单页应用 SPA 相当于一个a标签,切换不同的视图

    ​ 是否用户群体比较多

    ​ 知乎 掘金 网易云 百度移动端

    ​ 后台管理系统 vue-element-admin

    Vue-Router

    资料

    介绍

    Vue Router是vue.js官方的路由管理器它和Vue.js的 核心深度集成,让构建单页面应用变得易如反掌。包含的功能有:

    • 嵌套的路由/视图表
    • 模块化的,基于组件的路由配置
    • 路由参数、查询、通配符
    • 基于Vue.js过渡系统的视图过渡效果
    • 细粒度的导航控制
    • 带有自动激活的CSS class的链接
    • HTML5历史模式或hash模式。在IE9中自动降级
    • 自定义的滚动条行为

    起步

    用Vue.js+Vue Router创建单页应用,是非常简单的。使用Vue.js,我们已经可以通过组件来组成应用程序,当你要把Vue Router添加进来,我们需要做的是将组件(components)映射到路由(routes),然后告诉Vue Router 在哪里渲染它们

    安装

    npm i vue-router -S

    创建项目

    在自己想要创建项目的目录路径下执行vue create myproject进行配置项的选择,空格表示选中安装

    123.PNG

    生成后的目录结构

    123.PNG

    基本使用

    ① 在src/router/index.js

    // 0、引入Vue
    import Vue from 'vue';
    // 1、引入vue-router
    import VueRouter from 'vue-router';
    // 2、模块化机制,使用Router
    Vue.use(VueRouter)
    import Home from '../views/Home.vue';
    import About from '../views/About.vue';
    // 3、创建路由器对象
    const router = new VueRouter({
      routes:[  //rouutes是一个数组
        {
          path: "/",
          component:Home
        },
        {
          path: '/about',
          component:About,
        }
      ]
    })
    // 4、抛出路由对象
    export  default router;
    

    ② 在 src/main.js中

    import Vue from 'vue'
    import App from './App.vue'
    // 导入router对象
    import router from './router'
    
    Vue.config.productionTip = false
    
    new Vue({
      // 5、挂载到vue实例中
      router,
      render: h => h(App)
    }).$mount('#app')
    

    ③ 在 src/App.vue中

    <template>
      <div id="app">
        <!--6、router-link访问对应的路由,通过router-view来渲染路由组件-->
        <!--router-link 相当于a标签 to属性相当于a标签的href-->
          <!--基本配置-->
          		<router-link to='/'>首页</router-link>
          		<router-link to='/about'>关于</router-link>
          <!-- router-view 相当于路由组件的出口-->  
            	<router-view></router-view>
      </div>
    </template>
    
    <style>
    #app {
      font-family: Avenir, Helvetica, Arial, sans-serif;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      text-align: center;
      color: #2c3e50;
    }
    
    #nav {
      padding: 30px;
    }
    
    #nav a {
      font-weight: bold;
      color: #2c3e50;
    }
    
    #nav a.router-link-exact-active {
      color: #42b983;
    }
    </style>
    

    命名路由

    ​ 在配置路由的时候,给路由添加名字,访问时就可以动态的根据名字来进
    ⾏访问

    src/router/index.js

    import Vue from 'vue';
    // 1、导入
    import VueRouter from 'vue-router';
    // 2、模块化机制,使用Router
    Vue.use(VueRouter)
    import Home from '@/views/Home';
    import About from '@/views/About';
    import User from '@/views/User';
    // 3、创建路由器对象
    const router = new VueRouter({
      routes:[
        {
          path: "/",
          name: 'home',
          component: Home
        },
        {
          path: '/about',
          name: 'about',
          component: About
        },
        {
          path: '/user/:id',
          name: 'user',
          component: User
        }
      ]
    })
    // 4、抛出路由对象
    export  default router;
    

    src/App.vue

    <template>
      <div id="app">
        <!--6、router-link访问对应的路由,通过router-view来渲染路由组件-->
        <!--router-link 相当于a标签 to属性相当于a标签的href-->
          <!--命名路由配置-->
            <router-link :to="{name:'home'}">首页</router-link>| 
            <router-link :to="{name:'about'}">关于</router-link>| 
            <router-link :to="{name:'user',params:{id:1}}">用户1</router-link>| 
            <router-link :to="{name:'user',params:{id:2}}">用户2</router-link>
        <!-- router-view 相当于路由组件的出口-->
        <router-view></router-view>
      </div>
    </template>
    
    <style>
    #app {
      font-family: Avenir, Helvetica, Arial, sans-serif;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      text-align: center;
      color: #2c3e50;
    }
    
    #nav {
      padding: 30px;
    }
    
    #nav a {
      font-weight: bold;
      color: #2c3e50;
    }
    
    #nav a.router-link-exact-active {
      color: #42b983;
    }
    </style>
    

    动态路由匹配

    ​ 我们经常需要把某种模式匹配到的所有路由,全都映射到同个组件。例如,我们有⼀个 User 组件,对于所有 ID 各不相同的⽤户,都要使⽤这个组件来渲染。那么,我们可以在 vue-router 的路由路径中
    使⽤“动态路径参数”(dynamic segment) 来达到这个效果

    src/view/User.Vue

    <template>
        <div>
            用户页面 {$route.params.id}
        </div>
    </template>
    
    <script>
        export default {
    
        }
    </script>
    
    <style lang="scss" scoped>
    
    </style>
    

    src/router/index.js

    import Vue from 'vue';
    // 1、导入
    import VueRouter from 'vue-router';
    // 2、模块化机制,使用Router
    Vue.use(VueRouter)
    import Home from '@/views/Home';
    import About from '@/views/About';
    import User from '@/views/User';
    // 3、创建路由器对象
    const router = new VueRouter({
      routes:[
        {
          path: "/",
          name: 'home',
          component: Home
        },
        {
          path: '/about',
          name: 'about',
          component: About
        },
        {
          path: '/user/:id',
          name: 'user',
          component: User
        }
      ]
    })
    // 4、抛出路由对象
    export  default router;
    

    src/App.vue

    <template>
      <div id="app">
        <!--6、router-link访问对应的路由,通过router-view来渲染路由组件-->
        <!--router-link 相当于a标签 to属性相当于a标签的href-->
          <!--命名路由配置-->
            <router-link :to="{name:'home'}">首页</router-link>| 
            <router-link :to="{name:'about'}">关于</router-link>| 
            <router-link :to="{name:'user',params:{id:1}}">用户1</router-link>| 
            <router-link :to="{name:'user',params:{id:2}}">用户2</router-link>
       
          <!--命名路由-->
        <!-- <router-link :to="{name:'home'}">首页</router-link>| 
        <router-link :to="{name:'about'}">关于</router-link> -->
        <!-- router-view 相当于路由组件的出口-->
        <router-view></router-view>
      </div>
    </template>
    
    <style>
    #app {
      font-family: Avenir, Helvetica, Arial, sans-serif;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      text-align: center;
      color: #2c3e50;
    }
    
    #nav {
      padding: 30px;
    }
    
    #nav a {
      font-weight: bold;
      color: #2c3e50;
    }
    
    #nav a.router-link-exact-active {
      color: #42b983;
    }
    </style>
    

    访问

    http://localhost:8080/user/1

    http://localhost:8080/user/2

    查看效果

    当匹配到路由时,参数值会被设置到this.$route.params,可以在每个组件中使⽤,于是,我们可以更新 User 的模板,输出当前⽤户的 ID:

    src/views/User.vue

    <template>
        <div>
            <h3>用户页面 {$route.params.id}</h3>
        </div>
    </template>
    
    <script>
        export default {
    
        }
    </script>
    
    <style lang="scss" scoped>
    
    </style>
    

    在router/index.js的配置文件中,和routes同级的路径下,写出一行这个mode: history, 那么在浏览器访问的时候就会是干净的网页地址。

    响应路由参数的变化

    ​ 当使⽤路由参数时,例如从 /user/1 导航到 /user/2`, 原来的组件实例会被复⽤。因为两个路由都渲染同个组件,⽐起销毁再创建,复⽤则显得更加⾼效。 不过,这也意味着组件的⽣命周期钩⼦不会再被调⽤。

    ​ 复⽤组件时,想对路由参数的变化作出响应的话,你可以简单地watch (监测变化) $route 对象:

    src/views/User.vue

    <template>
        <div>
            用户页面 {$route.params.id}
        </div>
    </template>
    
    <script>
        export default {
            // 当路由的参数变化时 /user/1 切换到/user/2 原来的组件实例会被复用
            // 因为两个路由渲染了同个组件,复用高效
            created(){
                console.log(this.$route.params.id);
            },
            watch:{
                $route:(to)=>{
                    console.log(to.params.id);
                    //发起ajax 请求后端接口数据,数据趋势视图
                }
            }
            // beforeRouteUpdate(to,from,next){
            //     console.log(to.params.id);
    		//      //  查看路由的变化
            //     // 一定要调用next(),不然会阻塞整个路由  放行
            //         next();
            // }
        }
    </script>
    
    <style lang="scss" scoped>
    
    </style>
    

    404路由

    src/router/index.js

    import Vue from 'vue';
    // 1、导入
    import VueRouter from 'vue-router';
    // 2、模块化机制,使用Router
    Vue.use(VueRouter)
    import Home from '@/views/Home';
    import About from '@/views/About';
    import User from '@/views/User';
    
    // 3、创建路由器对象
    const router = new VueRouter({
      routes:[
        {
          path: "/",
          name: 'home',
          component: Home
        },
        {
          path: '/about',
          name: 'about',
          component: About
        },
        {
          path: '/user/:id',
          name: 'user',
          component: User
        },
        {
          path: '*',
          // 局部导入,异步加载组件
          component:()=>import('@/views/404')
        },
      ]
    })
    // 4、抛出路由对象
    export  default router;
    

    在src/views/下新建404.vue

    src/views/404.vue

    <template>
        <div>
            <h3>404页面</h3>
        </div>
    </template>
    
    <script>
        export default {
            
        }
    </script>
    
    <style lang="scss" scoped>
    
    </style>
    

    效果:

    123.PNG

    ​ 当使⽤通配符路由时,请确保路由的顺序是正确的,也就是说含有通配符的路由应该放在最后。路由 { path: '*' } 通常⽤于客户端 404错误
    ​ 当使⽤⼀个通配符时, $route.params 内会⾃动添加⼀个名为 pathMatch 参数。它包含了 URL 通过通配符被匹配的部分:

    src/router/index.js

    import Vue from 'vue';
    // 1、导入
    import VueRouter from 'vue-router';
    // 2、模块化机制,使用Router
    Vue.use(VueRouter)
    import Home from '@/views/Home';
    import About from '@/views/About';
    import User from '@/views/User';
    
    // 3、创建路由器对象
    const router = new VueRouter({
      routes:[
        {
          path: "/",
          name: 'home',
          component: Home
        },
        {
          path: '/about',
          name: 'about',
          component: About
        },
        {
          path: '/user/:id',
          name: 'user',
          component: User
        },
        {
          path: '/user-*',
          component: () => import('@/views/User-admin')
        },
        {
          path: '*',
          // 局部导入,异步加载组件
          component: () => import('@/views/404')
        },
      ]
    })
    // 4、抛出路由对象
    export  default router;
    

    src/views/User-admin.vue

    <template>
        <div>
            <h3>User-admin页面</h3>
            <h4>{{$route.params.pathMatch}}</h4>
        </div>
    </template>
    
    <script>
        export default {
            
        }
    </script>
    
    <style lang="scss" scoped>
    
    </style>
    

    匹配优先级

    ​ 有时候,同⼀个路径可以匹配多个路由,此时,匹配的优先级就按照路由的定义顺序:谁先定义的,谁的优先级就最高。

    查询参数

    src/router/index.js

    import Vue from 'vue';
    // 1、导入
    import VueRouter from 'vue-router';
    // 2、模块化机制,使用Router
    Vue.use(VueRouter)
    import Home from '@/views/Home';
    import About from '@/views/About';
    import User from '@/views/User';
    
    // 3、创建路由器对象
    const router = new VueRouter({
      mode:'history', //历史模式,干净的网页地址
      routes:[
        {
          path: "/",
          name: 'home',
          component: Home
        },
        {
          path: '/about',
          name: 'about',
          component: About
        },
        {
          path: '/user/:id',
          name: 'user',
          component: User
        },
        {
          path: '/page',
          name:  'page',
          component: ()=> import('@/views/Page')
        },  
      ]
    })
    // 4、抛出路由对象
    export  default router;
    

    src/App.vue

    <template>
      <div id="app">
        <!--6、router-link访问对应的路由,通过router-view来渲染路由组件-->
        <!--router-link 相当于a标签 to属性相当于a标签的href-->
          <!--命名路由配置-->
            <router-link :to="{name:'home'}">首页</router-link> | 
            <router-link :to="{name:'about'}">关于</router-link> | 
            <router-link :to="{name:'user',params:{id:1}}">用户1</router-link> | 
            <router-link :to="{name:'user',params:{id:2}}">用户2</router-link> | 
            <router-link :to="{name:'page',query:{id:1,title:'foo'}}">page</router-link>
       
          <!--命名路由-->
        <!-- <router-link :to="{name:'home'}">首页</router-link>| 
        <router-link :to="{name:'about'}">关于</router-link> -->
        <!-- router-view 相当于路由组件的出口-->
        <router-view></router-view>
      </div>
    </template>
    
    <style>
    #app {
      font-family: Avenir, Helvetica, Arial, sans-serif;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      text-align: center;
      color: #2c3e50;
    }
    
    #nav {
      padding: 30px;
    }
    
    #nav a {
      font-weight: bold;
      color: #2c3e50;
    }
    
    #nav a.router-link-exact-active {
      color: #42b983;
    }
    </style>
    
    

    src/views/page.vue

    <template>
        <div>
            <h3>Page页面</h3>
        </div>
    </template>
    
    <script>
        export default {
            created () {
                // console.log(this.$route);
                // 获取参数
                const {id,title} = this.$route.query;
                console.log(id,title);
                // 与后端发生交互
            },
        }
    </script>
    
    <style lang="scss" scoped>
    
    </style>
    

    路由重定向和别名

    路由重定向:例⼦是从 / 重定向到 /home :

    路由起别名:例子 是访问/aaa显示初page的页面

    ​ 别名”的功能让你可以⾃由地将 UI 结构映射到任意的 URL,⽽不是受限于配置的嵌套路由结构。

    import Vue from 'vue';
    // 1、导入
    import VueRouter from 'vue-router';
    // 2、模块化机制,使用Router
    Vue.use(VueRouter)
    import Home from '@/views/Home';
    import About from '@/views/About';
    import User from '@/views/User';
    
    // 3、创建路由器对象
    const router = new VueRouter({
      mode:'history', //历史模式,干净的网页地址
      routes:[
        {
          path: '/',
          // --路由重定向---
          // redirect: '/home',
          redirect: {name:"home"},
        },
        {
          path: "/home",
          name: 'home',
          component: Home
        },
        {
          path: '/page',
          name:  'page',
          component: ()=> import('@/views/Page'),
          alias:'/aaa',  // ---路由起别名命名---
        },
      ]
    })
    // 4、抛出路由对象
    export  default router;
    

    路由组件传参

    ​ 在组件中使⽤ $route 会使之与其对应路由形成⾼度耦合,从⽽使组件只能在某些特定的 URL 上使⽤,限制了其灵活性。使⽤ props 将组件和路解耦:

    取代$route的耦合

    {
    	path: '/user/:id',
    	name: 'user',
    	component: User,
    	props:true
    },
    

    src/views/User.vue

    <template>
    	<div>
    		<h3>⽤户⻚⾯{{$route.params.id}}</h3>
    		<h3>⽤户⻚⾯{{id}}</h3>
    	</div>
    </template>
    <script>
    	export default{
    	//....
    		props: {
    			id: {
    				type: String,
    				default: ''
    		},
    	},
     }
    </script>
    

    编程式导航

    ​ 除了使⽤ 创建 a 标签来定义导航链接,我们还可以借助 router 的实例⽅法,通过编写代码来实现。

    注意:

    ​ 在 Vue 实例内部,你可以通过 $router 访问路由实例。因此你可以调用 this.$router.push。

    声明式 编程式
    <route-link :to="..."> route.push(...)

    该⽅法的参数可以是⼀个字符串路径,或者⼀个描述地址的对象。

    例如 :

    // 字符串
    	this.$router.push('home')
    // 对象
    	this.$router.push({ path: 'home' })
    // 命名的路由
    	this.$router.push({ name: 'user', params: { userId:'123' }})
    // 带查询参数,变成 /register?plan=private
    	this.$.push({ path: 'register', query: { plan: 'private' }})
    

    前进后退

    // 在浏览器记录中前进⼀步,等同于 history.forward()
    	this.router.go(1)
    // 后退⼀步记录,等同于 history.back()
    	this.router.go(-1)
    // 前进 3 步记录
    	this.router.go(3)
    // 如果 history 记录不够⽤,那就默默地失败呗
    	this.router.go(-100)
    	this.router.go(100)
    

    嵌套路由

    ​ 实际⽣活中的应⽤界⾯,通常由多层嵌套的组件组合⽽成。同样地,URL 中各段动态路径也按某种结构对应嵌套的各层组件

    /user/1/profile                          /user/1/posts
    +------------------+                   +-----------------
    + 
    | User             |                   | User             |
    |
    | +--------------+ |                   | +-------------+
    | |
    | Profile | |        +------------> |  | Posts |          |
    | 
    | |              | |                |  |                  |
    | 
    |+-------------- + |                |  +-------------+    |
    |
    +------------------+                   +-----------------
    

    src/router/index.js

    {
    	path: '/user/:id',
    	name: 'user',
    	component: User,
    	props: ({params,query})=>({
    		id: params.id,
    		title:query.title
    	}),
    	children:[
    		// 当 /user/:id/profile 匹配成功,
    		// Profile 会被渲染在 User 的 <router-view> 中
    		{
    			path:"profile",
    			component: Profile
    		},
    		// 当 /user/:id/posts 匹配成功,
    		// Posts 会被渲染在 User 的 <router-view> 中
    		{
    			path: "posts",
    			component: Posts
    		}
    	]
    }
    

    src/App.vue

    <template>
    	<div id='app'>
    		<!-- 嵌套理由 -->
    		<router-link to="/user/1/profile">User/profile</router-link> |
    		<router-link to="/user/1/posts">User/posts</routerlink> |
    	</div>
    </template>
    

    在User组件的模版添加一个<router-view>

    <template>
    	<div>
    		<h3>⽤户⻚⾯{{$route.params.id}}</h3>
    		<h3>⽤户⻚⾯{{id}}</h3>
    		<!--子路由的组件出口-->
    		<router-view></router-view>
    	</div>
    </template>
    

    命名视图

    ​ 有时候想同时 (同级) 展示多个视图,⽽不是嵌套展示,例如创建⼀个布局,有 sidebar (侧导航) 和 main (主内容) 两个视图,这个时候命名视图就派上⽤场了 。

    src/router/index.js

    {
    	path: '/home',
    	name: 'home',
    	//注意这个key是components
    	components: {
    		default: Home, //默认的名字
    		main: ()=>import('@/views/Main.vue'),
    		sidebar: () => import('@/views/Sidebar.vue')
    	}
    },
    

    src/App.vue

    <router-view/>
    <router-view name='main'/>
    <router-view name='sidebar'/>
    

    导航守卫

    “导航”表示路由正在发⽣改变。

    完整的导航解析流程

    1. 导航被触发。
    2. 在失活的组件⾥调⽤离开守卫。
    3. 调⽤全局的 beforeEach 守卫。
    4. 在重⽤的组件⾥调⽤ beforeRouteUpdate 守卫 (2.2+)。
    5. 在路由配置⾥调⽤ beforeEnter 。
    6. 解析异步路由组件。
    7. 在被激活的组件⾥调⽤ beforeRouteEnter 。
    8. 调⽤全局的 beforeResolve 守卫 (2.5+)。
    9. 导航被确认。
    10. 调⽤全局的 afterEach 钩⼦。
    11. 触发 DOM 更新。
    12. ⽤创建好的实例调⽤ beforeRouteEnter 守卫中传给 next 的回
      调函数。

    全局守卫

    你可以使⽤ router.beforeEach 注册⼀个全局前置守卫

    const router = new VueRouter({ ... })
                                  
    router.beforeEach((to, from, next) => {
    	// ...
    })
    

    ​ 有个需求,⽤户访问在浏览⽹站时,会访问很多组件,当⽤户跳转到 /notes ,发现⽤户没有登录,此时应该让⽤户登录之后才能查看,应该让⽤户跳转到登录⻚⾯,登录完成之后才可以查看我的笔记的内容,这个时候全局守卫起到了关键的作⽤

    ​ 有两个路由 /notes 和 /login

    route.vue

    const router = new VueRouter({
    	routes:[
    		{
    			path: '/notes',
    			name: 'notes',
    			component: () => import('@/views/Notes')
    		},
    		{
    			path: "/login",
    			name: "login",
    			component: () => import('@/views/Login')
    		},
         ]
    })
    
    //// 全局守卫
    router.beforeEach((to, from, next) => {
    	//⽤户访问的是'/notes'
    	if (to.path === '/notes') {
    		//查看⼀下⽤户是否保存了登录状态信息
    		let user = JSON.parse(localStorage.getItem('user'))
    		if (user) {
    			//如果有,直接放⾏
    			next();
    		} else {
    			//如果没有,⽤户跳转登录⻚⾯登录
                next('/login')
    		}
    	} else {
    		next();
    	}
    })
    

    Login.vue

    <template>
    <div>
    <input type="text" v-model="username">
    <input type="password" v-model="pwd">
    <button @click="handleLogin">提交</button>
    </div>
    </template>
    <script>
    export default {
    	data() {
    		return {
    			username: "",
    			pwd: ""
    		};
    	},
    	methods: {
    		handleLogin() {
    			// 1.获取⽤户名和密码
    			// 2.与后端发⽣交互
    			setTimeout(() => {
    				let data = {
    					username: this.username
    				};
    			//保存⽤户登录信息
    			localStorage.setItem("user", JSON.stringify(data));
    			// 跳转我的笔记⻚⾯
    			this.$router.push({ name: "notes" });
    		}, 1000);
    	},
      }
    };
    </script>
    

    App.vue

    <!-- 全局守卫演示 -->
    <router-link to="/notes">我的笔记</router-link> |
    <router-link to="/login">登录</router-link> |
    <button @click="handleLogout">退出</button>
    export default {
    	methods: {
    	handleLogout() {
    		//删除登录状态信息
    		localStorage.removeItem("user");
    		//跳转到⾸⻚
    		this.$router.push('/')
    	}
      },
    }
    

    组件内的守卫

    你可以在路由组件内直接定义以下路由导航守卫:

    • beforeRouteEnter
    • beforeRouteUpdate(2.2新增)
    • beforeRouteLeave

    src/router/index.js

    {
          path:'eaditor',
          name:'eaditor',
          component:()=>import('@/views/Eaditor')
    },
    

    src/App.vue

    添加 
    <router-link :to="{name:'eaditor'}">编辑</router-link>
    

    src/views/Eaditor.vue

    <template>
        <div>
            <h2>用户的编辑页面</h2>
            <textarea  v-model='content' cols="30" rows="10"></textarea>
            <button @click='saveContent'>保存</button>
            <ul>
                <li v-for='(item,index) in list' :key='index'>
                    <h3>{{item.title}}</h3>
                </li>
            </ul>
        </div>
    </template>
    
    <script>
        export default {
            data() {
                return {
                    content: '',
                    list: [],
                }
            },
            methods: {
                saveContent() {
                    this.list.push({
                        title:this.content
                    })
                    //清空文本的输入框
                    this.content = '';
                }
            },
            beforeRouteLeave(to,form,next){
                if(this.content){
                    // 用户体验
                    alert('请确保保存信息之后离开');
                    next(false);
                }else{
                    next();
                }
            }
        }
    </script>
    
    <style lang="scss" scoped>
    
    </style>
    

    路由元信息实现权限控制

    ​ 给需要添加权限的路由设置meta字段

    src/router/index.js

    {
          path: '/blog',
          name: 'blog',
          component: ()=>import('@/views/Blog'),
          meta:{
            // 把blog加到黑名单
            requireAuth:true
          }
        },
    

    src/view/Blog.vue

    <template>
        <div>
            <h3>我的博客页面</h3>
        </div>
    </template>
    
    <script>
        export default {
            
        }
    </script>
    
    <style lang="scss" scoped>
    
    </style>
    

    src/App.vue

    <router-link :to="{name:'blog'}">博客</router-link>
    

    src/main.js

    // 全局守卫
    router.beforeEach((to, from, next)=>{
      if(to.matched.some(record=>record.meta.requireAuth)){
        // 需要权限,在黑名单
        if(localStorage.getItem('user')){
            next({
              path: '/login',
              query: {
                redirect:to.fullPath //fullPath完整路径
              }
            })
        }else{
          next();
        }
      }
      // 下面的放行全部是在白名单
      next();
    })
    

    src/vies/Login.vue

    <template>
        <div>
            <h2>登陆页面</h2>
            <input type="text" v-model='user'>
            <input type="password" v-model='pwd'>
            <button @click='handleLogin'>登陆</button>
        </div>
    </template>
    
    <script>
        export default {
            data() {
                return {
                    user: '',
                    pwd: '',
                }
            },
            methods: {
                handleLogin() {
                    // 1、获取用户名和秘密
                    // 2、与后端发生交互
                    setTimeout(() => {
                        let data ={
                            // user:this.user
                            username: this.username
                        };
                        //保存用户名到本地
                        localStorage.setItem("user",JSON.stringify(data));
                        // 跳转到我的笔记
                        this.$router.push({
                            path:this.$route.query.redirect
                        });
                    }, 1000);
                }
            },
        }
    </script>
    
    <style lang="scss" scoped>
    
    </style>
    

    数据获取

    ​ 有时候,进⼊某个路由后,需要从服务器获取数据。例如,在渲染⽤户信息时,你需要从服务器获取⽤户的数据。我们可以通过两种⽅式来实现:

    • 导航完成之后获取:先完成导航,然后在接下来的组件⽣命周期
      钩⼦中获取数据。在数据获取期间显示“加载中”之类的指示。
    • 导航完成之前获取:导航完成前,在路由进⼊的守卫中获取数
      据,在数据获取成功后执⾏导航。

    导航完成之后获取数据

    ​ 当你使⽤这种⽅式时,我们会⻢上导航和渲染组件,然后在组件的 created 钩⼦中获取数据。这让我们有机会在数据获取期间展示⼀个 loading 状态,还可以在不同视图间展示不同的 loading 状态。

    Vuex

    ​ Vuex 是⼀个专为 Vue.js 应⽤程序开发的状态管理模式。它采⽤集中式存储管理应⽤的所有组件的状态,并以相应的规则保证状态以⼀种可预测的⽅式发⽣变化

    安装Vuex

    mapState辅助函数

    mapGetters辅助函数

    MapMutation

    MapAction辅助函数

    Module

    什么情况下我该使用Vuex?

    插件

  • 相关阅读:
    Mysql 时间操作
    curl 学习
    CURL详解
    mysql 获取当前时间戳
    php开启openssl的方法
    0,null,empty,空,false,isset
    ecshop微信扫描支付开发
    seaJs的简单应用
    js运动框架之掉落的扑克牌(重心、弹起效果)
    js运动框架完成块的宽高透明度及颜色的渐变
  • 原文地址:https://www.cnblogs.com/jiaxiaozia/p/13781727.html
Copyright © 2020-2023  润新知