zoukankan      html  css  js  c++  java
  • Day 85 VUE——路由

    路由

    安装:npm i vue-router -S,
    推荐使用 vue add router 添加组件(记得提前把代码提交到 git)

    在 main,js 中

    import Vue from ‘vue’
    import VueRouter from ‘vue-router’
    
    Vue.use(VueRouter)

    vue-router的基本使用

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

    命名路由

    const routes = [
      {
        path: '/',
        name: 'Home',    // 对路由命名
        component: Home
      }
    ]
    index.js
    <template>
        <div id="nav">
           // :to="{name:'Home'}"  使用命名路由
          <router-link :to="{name:'Home'}">Home</router-link> | 
          <router-link :to="{name:'About'}">About</router-link> | 
        </div>
        <router-view/>
    </template>
    App.vue

    动态路由匹配和路由组件复用

    路由 监听、导航守卫

    import User from '@/views/User.vue'
    
    const routes = [
      {
        path: '/',
        name: 'Home',
        component: Home
      },
       // 准备重用的路由
      {
        path:'/user',
        name:'User',
        component:User
      }
    ]
    index.js
    <template>
      <div id="app">
        <!--  :to="{params:{id:2}}  params 是对路由的重用设置 -->
        <div id="nav">
          <router-link :to="{name:'Home'}">Home</router-link> | 
          <router-link :to="{name:'User',params:{id:1}}">User_1</router-link> | 
          <router-link :to="{name:'User',params:{id:2}}">User_2</router-link>
        </div>
        <router-view/>
      </div>
    </template>
    App.vue
    <template>
        <div>
            我是用户界面{{ $route.params.id }}
        </div>
    </template>
    
    <script>
    export default {
        // 路由组件会复用的情况
    
        // 当路由参数变化时,/user/1 切换到 /user/2 时,原来的组件实例会被复用
        // 因为两个路由渲染了同个组件,复用高效
        // created(){
        //         console.log(this.$route.params.id)
        // },
        // 监听
        // 相应路由参数变化
        watch:{
            $route:function(to){
                console.log(to.params.id)
                // 发起 ajax 请求后端接口数据 数据驱动视图
            }
        },
        // 导航守卫
        // beforeRouteUpdate(to,form,next){
        //     console.log(to.params.id)
        //     // 放行,一定要调用 next,不然会柱塞整个路由 
        //     next() 
        // }
    }
    </script>
    
    <style>
    
    </style>
    USER.vue

    404路由和路由匹配优先级

     404 的路由要放到最下面,不然影响正常使用

    export default new VueRouter({
      routes:[
        {
          path:'/user:id',
          name:'user',
          component:()=>import('@/views/User')
        },
        {
          // 404 路由
          path:'*',
          component:()=>import('@/views/404')
        },
      ]
    })
    404
    同一个路径可以匹配多个路由,匹配的优先级按照路由的定义顺序
    谁先定义,谁的优先级高
    export default new VueRouter({
      routes:[
        // 同一个路径可以匹配多个路由,匹配的优先级按照路由的定义顺序
        // 谁先定义,谁的优先级高
        // {
        //   path:'/about',
        //   name:'about',
        //   component:()=>import('@/views/User')
        // },
        {
          path:'/about',
          name:'about',
          component:About
        },
      ]
    })
    路由的优先级

    路由查询参数

    history 模式,干净的网页地址,没有 # 
    // 3.创建路由器对象
    export default new VueRouter({
      mode:'history',   // history 模式,干净的网页地址
      routes:[
        {
          path:'/',
          name:'home',
          component:Home
        },
        {
          path:'/page',
          name:'page',
          component:()=>import('@/views/Page')
        },
      ]
    })
    index.js
    <template>
      <div id="app">
        <div id="nav">
          <router-link :to="{name:'user',params:{id:2}}">User_2</router-link> | 
          <router-link :to="{name:'page',query:{id:2,foo:'title'}}">Page</router-link>
        </div>
        <router-view/>
      </div>
    </template>
    App.vue
    <template>
        <div>
            <h3>这是一个 Page 界面</h3>
        </div>
    </template>
    
    <script>
    export default {
        created(){
            const {id,foo} = this.$route.query
            console.log(id,foo)     // 拿到这些信息就可以与后端进行交互了
        }
    }
    </script>
    
    <style>
    
    </style>
    Page.vue

    路由重定向和别名

    export default new VueRouter({
      mode:'history',   // history 模式,干净的网页地址
      routes:[
        {
          path:'/',
          // 重定向
          // redirect:'home'
          redirect:{name:'home'}
        },
        {
          path:'/home',
          name:'home',
          component:Home,
          // 别名
          alias:'/hhh'
        },
        {
          path:'/about',
          name:'about',
          component:About
        },
      ]
    })
    index.js

    路由组件传值

    // 3.创建路由器对象
    export default new VueRouter({
        {
          path:'/user:id',
          name:'user',
          component:()=>import('@/views/User'),
          // 路由组件传值
          // 方法一
          // props:true
          // 方法二
          props:(route)=>({
            id:route.params.id,
            title:route.query.title,
          })
        },
      ]
    })
    index.js
    <template>
        <div>
            <h2>这个是 User {{ $route.params.id }}</h2>
            <h2>使用 props 传值 {{ id }} --- {{ title }}</h2>
        </div>
    </template>
    
    <script>
    export default {
        props:['id','title'],
    }
    </script>
    
    <style>
    
    </style>
    User.vue

    如何使用编程式导航

    <template>
        <div>
            <button @click="goHome">界面跳转</button>
            <button @click="goBack">后退</button>
        </div>
    </template>
    
    <script>
    export default {
        methods:{
            goBack(){
                // 正数 前进    0 刷新界面     负数 后退
                this.$router.go(-1)    
            },
            goHome(){
                // 编程时导航
                // 方法一
                // this.$router.push('/')
                // 方法二
                this.$router.push({
                    path:'/'
                })
                // 方法三
                // this.$router.push({
                //     name:'user',
                //     params:{id:2}
                // })
                // 方法四
                // this.$router.push({
                //     path:'/reg',
                //     query:{plan:'123'}
                // })
            }
        }
    }
    </script>
    
    <style>
    
    </style>
    User.vue

    嵌套路由的使用

    // 3.创建路由器对象
    export default new VueRouter({
      mode:'history',   // history 模式,干净的网页地址
      routes:[
        {
          path:'/user:id',
          name:'user',
          component:()=>import('@/views/User'),
          // 路由组件传值
          // 方法一
          // props:true
          // 方法二
          props:(route)=>({
            id:route.params.id,
            title:route.query.title,
          }),
          children:[
            {
              path:'App1',
              component:()=>import('@/views/App1')
            },
            {
              path:'App2',
              component:()=>import('@/views/App2')
             },
         ]
        },
      ]
    })
    index.js
    <template>
      <div id="app">
        <div id="nav">
          <!-- 声明式跳转 -->
          <router-link :to="{name:'user',params:{id:1}}">User_1</router-link> | 
          <router-link :to="{name:'user',params:{id:2}}">User_2</router-link> | 
          
          <!-- 路由嵌套 -->
          <router-link to='/user1/App1'>user_1/App1</router-link> | 
          <router-link to='/user2/App2'>user_2/App2</router-link> | 
        </div>
        <router-view/>
      </div>
    </template>
    App.vue
    <template>
        <div>
            <h2>这个是 User {{ $route.params.id }}</h2>
    
            <!-- 子路由的文件出口 -->
            <router-view></router-view>
        </div>
    </template>
    User.vue

    命名视图的使用

    // 3.创建路由器对象
    export default new VueRouter({
      mode:'history',   // history 模式,干净的网页地址
      routes:[
        {
          path:'/about',
          name:'about',
          // component:About
          // 设置命名视图
          components:{
            default:About,  // 默认的名字
            right:()=>import('@/views/right'),
            left:()=>import('@/views/left'),
          }    
        },
      ]
    })
    index.js
    <template>
      <div id="app">
        <!-- 渲染 Home 的 -->
        <router-view/>
        <router-view name='right' class="right"></router-view>
        <router-view name='left' class="left"></router-view>
      </div>
    </template>
    App.vue

    使用全局守卫做登录操作

    // 1.导入
    import Vue from 'vue'
    import router from 'vue-router'
    import VueRouter from 'vue-router'
    import Home from '../views/Home.vue'
    import About from '../views/About.vue'
    
    // 2.模块化机制 使用 Router
    Vue.use(router)
    
    // 3.创建路由器对象
    export default new VueRouter({
      mode:'history',   // history 模式,干净的网页地址
      routes:[
        {
          path:'/note',
          name:'note',
          component:()=>import('@/views/Note')
        },
        {
          path:'/login',
          name:'login',
          component:()=>import('../views/Login')
        },
        {
          path:'*',
          component:()=>import('@/views/404')
        },
      ]
    })
    index.js
    <template>
      <div id="app">
        <div id="nav">
          <!-- 声明式跳转 -->
          <router-link :to="{name:'home'}">Home</router-link> |
          <router-link :to="{name:'about'}">About</router-link> | 
          <router-link :to="{name:'note'}">我的笔记</router-link> | 
        </div>
      </div>
    </template>
    App.vue
    import Vue from 'vue'
    import App from './App.vue'
    import router from './router'
    import store from './store'
    
    Vue.config.productionTip = false
    
    
    // 全局守卫
    router.beforeEach((to,from,next)=>{
      // 判断用户是否访问了 note
      if(to.path === '/note'){
        const user = JSON.parse(localStorage.getItem('user'))
        if (user) {
          // 用户已登录
          next()
        }else{
          // 用户没有登录  跳转到登录界面
          next('/login')
        }
      }
      next()
    })
    
    new Vue({
      router,
      store,
      render: h => h(App)
    }).$mount('#app')
    main.js
    <template>
        <div>
            <h2>登录界面</h2>
            账号:<input type="text" v-model="user">
            密码:<input type="password" v-model="pawd">
            <input type="button" value='登录' @click="login">
        </div>
    </template>
    
    <script>
    export default {
        data(){
            return{
                user:'',
                pawd:''
            }
        },
        methods:{
            login(){
                // 1.获取账号密码
                // 2.模拟后端交互
                setTimeout(() => {
                    let data = {
                        user:this.user
                    }
                    // 保存用户名到本地
                    localStorage.setItem('user',JSON.stringify(data));
                    // 跳转到 note
                    this.$router.push('/note')
                }, 1000);
            }
        }
    
    }
    </script>
    
    <style>
    
    </style>
    Login.vue

    组件内部的守卫的应用

    // 1.导入
    import Vue from 'vue'
    import router from 'vue-router'
    import VueRouter from 'vue-router'
    import Home from '../views/Home.vue'
    import About from '../views/About.vue'
    
    // 2.模块化机制 使用 Router
    Vue.use(router)
    
    // 3.创建路由器对象
    export default new VueRouter({
      mode:'history',   // history 模式,干净的网页地址
      routes:[
        {
          path:'/edit',
          name:'edit',
          component:()=>import('../views/Edit')
        },
        {
          path:'*',
          component:()=>import('@/views/404')
        },
      ]
    })
    index.js
    <template>
      <div id="app">
        <div id="nav">
          <router-link :to="{name:'edit'}">编辑</router-link> | 
        </div>
      </div>
    </template>
    App.vue
    <template>
        <div>
            <textarea v-model="edit" id="" cols="30" rows="10"></textarea>
            <button @click='save'>保存</button>
            <ul>
                <li v-for="(item,index) in list" :key="index">
                    <h4>{{ item.title }}</h4>
                </li>
            </ul>
        </div>
    </template>
    
    <script>
    export default {
        data(){
            return{
                edit:'',
                list:[]
            }
        },
        methods:{
            save(){
                this.list.push({
                    title:this.edit
                })
                // 清空文本框
                this.edit = '';
            }
        },
        // beforeRouteUpdate(to,from,next){
        //     // 组件重用时 这个方法才起作用
        //     next();
        // },
        beforeRouteLeave(to,from,next){
            if (this.edit) {
                alert('请保存后在离开')
                next(false)
            }else{
                next()
            }
        }
    }
    </script>
    
    <style>
    
    </style>
    Edit.vue

    路由meta元信息实现权限控制

    // 3.创建路由器对象
    export default new VueRouter({
      mode:'history',   // history 模式,干净的网页地址
      routes:[
        {
          path:'/page',
          name:'page',
          component:()=>import('@/views/Page'),
          meta:{
            // 加入到黑名单
            requireAuth:true
          }
        },
        {
          path:'/edit',
          name:'edit',
          component:()=>import('../views/Edit'),
          meta:{
            // 加入到黑名单
            requireAuth:true
          }
        },
        {
          path:'*',
          component:()=>import('@/views/404')
        },
      ]
    })
    index.js
    <template>
        <div>
            <h2>登录界面</h2>
            账号:<input type="text" v-model="user">
            密码:<input type="password" v-model="pawd">
            <input type="button" value='登录' @click="login">
        </div>
    </template>
    
    <script>
    export default {
        data(){
            return{
                user:'',
                pawd:''
            }
        },
        methods:{
            login(){
                // 1.获取账号密码
                // 2.模拟后端交互
                setTimeout(() => {
                    let data = {
                        user:this.user
                    }
                    // 保存用户名到本地
                    localStorage.setItem('user',JSON.stringify(data));
                    // 跳转到 note
                    this.$router.push({
                        path:this.$route.query.redirect
                    })
                }, 1000);
            }
        }
    
    }
    </script>
    
    <style>
    
    </style>
    Login.vue
    import Vue from 'vue'
    import App from './App.vue'
    import router from './router'
    import store from './store'
    
    Vue.config.productionTip = false
    
    // 全局守卫
    router.beforeEach((to,from,next)=>{
      if(to.matched.some(record=>record.meta.requireAuth)){
        // 需要权限  在黑名单中
        if (!localStorage.getItem('user')) {
          next({
            path:'/login',
            query:{
              redirect:to.fullPath
            }
          })
        }else{
          next();
        }
      }
      // 在白名单中
      next();
    })
    
    
    new Vue({
      router,
      store,
      render: h => h(App)
    }).$mount('#app')
    main.js

    路由组件内在什么时机获取数据

    module.exports = {
        devServer:{
            before:(app,serve)=>{
                app.get('/api/post',(req,res)=>{
                    res.json({
                        title:'vue-router 的数据获取',
                        body:'在导航完成之后获取数据'
                    })
                })
            }
        }
    }
    vue.config.js 在根目录创建用于模拟数据
    // 1.导入
    import Vue from 'vue'
    import router from 'vue-router'
    import VueRouter from 'vue-router'
    
    // 2.模块化机制 使用 Router
    Vue.use(router)
    
    // 3.创建路由器对象
    export default new VueRouter({
      mode:'history',   // history 模式,干净的网页地址
      routes:[
       {
          path:'/post',
          name:'post',
          component:()=>import('../views/Post')
        },
        {
          path:'*',
          component:()=>import('@/views/404')
        },
      ]
    })
    index.js
    <template>
      <div id="app">
        <div id="nav">
          <!-- 声明式跳转 -->
          <router-link :to="{name:'home'}">Home</router-link> |
          <router-link :to="{name:'about'}">About</router-link> | 
          <router-link :to="{name:'note'}">我的笔记</router-link> | 
          <router-link :to="{name:'edit'}">编辑</router-link> | 
          <router-link :to="{name:'post'}">Post</router-link> | 
        </div>
      </div>
    </template>
    App.vue
    <template>
        <div class="post">
            <div v-if="loading" class="loading">Loading...</div>
            <div v-if="error" class="error">{{ error }}</div>
            <div v-if="post">
                <h2>标题:{{ post.title }}</h2>
                <h2>内容:{{ post.body }}</h2>
            </div>
        </div>
    </template>
    
    <script>
    export default {
        data(){
            return{
                post:null,
                error:null,
                loading:false
            }
        },
        // 导航完成之后获取数据
        created(){
            console.log(this.$https)
            this.getPostData()
        },
        watch:{
            $route:"getPostData"
        },
        methods:{
            async getPostData(){
                try {
                    this.loading = true
                    const {data} = await this.$https.get('/api/post')
                    this.loading = false
                    this.post = data;
                } catch (error) {
                    console.log(error);
                    this.error = error.toString()
                }
            }
        }
    }
    </script>
    
    <style>
    
    </style>
    Post.vue
  • 相关阅读:
    一步步介绍如何给项目添加单元测试
    日期格式化在移动端的问题
    使用VW时,图片的问题
    转:vw适配中使用伪类选择器遇到的问题
    ES6模块的import和export用法总结
    转:如何在Vue项目中使用vw实现移动端适配
    PhpStrom添加调试功能
    小程序商城笔记
    使用TortoiseGit对android studio工程进行代码版本控制
    Android Studio 常见异常解决办法
  • 原文地址:https://www.cnblogs.com/ysging/p/13515679.html
Copyright © 2011-2022 走看看