zoukankan      html  css  js  c++  java
  • 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?

    插件

  • 相关阅读:
    Java实现 LeetCode 735 行星碰撞(栈)
    Java实现 LeetCode 735 行星碰撞(栈)
    Java实现 LeetCode 887 鸡蛋掉落(动态规划,谷歌面试题,蓝桥杯真题)
    Java实现 LeetCode 887 鸡蛋掉落(动态规划,谷歌面试题,蓝桥杯真题)
    Java实现 LeetCode 887 鸡蛋掉落(动态规划,谷歌面试题,蓝桥杯真题)
    Java实现 蓝桥杯算法提高 求最大值
    Java实现 蓝桥杯算法提高 求最大值
    Java实现 蓝桥杯算法提高 求最大值
    Python eval() 函数
    Python repr() 函数
  • 原文地址:https://www.cnblogs.com/jiaxiaozia/p/13781727.html
Copyright © 2011-2022 走看看