每天一点VUE(DAY 10-VUE2篇)

目录

1、创建vue-router

2、使用vue-router

2.1、路由的基本使用

2.2、多级路由(嵌套路由)

2.3、路由的query参数

2.4、路由命名(简化里面to的长度)

2.5、路由的params参数

2.6、路由的props配置(简化在模版里获取query和params)

2.6.1、第一种传props方法

2.6.2、第二种传props的方式

2.6.3、第三种传props的方式

2.7、的replace属性

2.8、脱离router-link实现路由跳转(使用$router的push和replace)

2.9、缓存路由组件

2.10、路由组件的两个新的生命周期钩子(actived和deactivated(失活))

3、路由守卫

3.1、全局路由守卫

3.2、独享路由守卫

3.3、组件内的路由守卫

4、history模式和hash模式


1、创建vue-router

(1)首先下载vue-router,注意vue2只能用vue-router3版本,vue3只能用vue-router4版本

npm i vue-router@3

(2)在src文件夹下创建一个router的文件夹,再在里面创建一个index.js文件,用来做路由器,内容如下。

import VueRouter from "vue-router";

export default new VueRouter({
    routes:[]
})

(3)在main.js里面引入路由器,并且使用vue-router插件,并加入router配置项

import Vue from 'vue'
import App from './App.vue'
//引入
import VueRouter from "vue-router"
import router from "../src/router"

Vue.config.productionTip = false
//使用插件
Vue.use(VueRouter)

new Vue({
  render: h => h(App),
//配置项
  router,
}).$mount('#app')

当url的后面有个#时说明配置成果

2、使用vue-router

2.1、路由的基本使用

        在components文件夹下创建一个pages文件夹用于存放页码的组件,然后创建如下页面

<!--MyNav页面 -->
<template>
   <div class="row">
      <div class="col-xs-2 col-xs-offset-2">
        <div class="list-group">
<!--
    这是之前的,如果我们要实现单页面应用的话,就得用router-link代替a标签,并且吧active的        
    classname放在active-class里面,并且吧href改为to,注意不要在/前面加点,也不用加后缀
    <a class="list-group-item" href="./about.html">About</a>
     <a class="list-group-item active" href="./home.html">Home</a>
  -->
          <router-link class="list-group-item"  active-class="active" to="/about">About</router-link>
          <router-link class="list-group-item" active-class="active"  to="/home">Home</router-link>
        </div>
      </div>
      <div class="col-xs-6">
        <div class="panel">
          <div class="panel-body">
<!--
    这里的router-view是告诉vue-router路由跳转后的组件应该放在那个位置
-->
            <router-view></router-view>
          </div>
        </div>
      </div>
    </div>
</template>

<script>
export default {
    name:'MyNav'
}
</script>
<!-- components/pages MyAbout.vue -->
<template>
            <h2>我是About的内容</h2>
</template>

<script>
export default {
    name:"MyAbout"
}
</script>
<!-- components/pages MyHome.vue -->
<template>
            <h2>我是Home的内容</h2>
</template>

<script>
export default {
    name:"MyHome"
}
</script>

最后在App.vue里面使用组件MyNav.vue

//App.vue
<template>
  <div id="app">
    <my-nav/>
  </div>
</template>

<script>
import MyNav from './components/MyNav.vue'

export default {
  name: 'App',
  components: {
    MyNav 
  }
}
</script>

总结注意点:

        1、每个组件都有自己的$route属性,整个应用只有一个$router,组件也可以获取

        2、pages里面存放路由组建

        3、路由切换后,之前的组件是被销毁了的

        4、用router-link替换a,用to替换href,用active-class绑定动态属性,

        5、用router-view来放切换的路由 

2.2、多级路由(嵌套路由)

首先在创建两个路由组件作MyHome的子路由,然后在router/index.js里面的home路由下用children添加子路由

//pages/MessagePage.vue
<template>
     <div>
        <ul>
        <li>
            <a href="/message1">message001</a>&nbsp;&nbsp;
        </li>
        <li>
            <a href="/message2">message002</a>&nbsp;&nbsp;
        </li>
        <li>
            <a href="/message/3">message003</a>&nbsp;&nbsp;
        </li>
        </ul>
    </div>
</template>

<script>
export default {
    name:'MessagePage'
}
</script>
//pages/NewsPage.vue
<template>
    <ul>
        <li>news001</li>
        <li>news002</li>
        <li>news003</li>
    </ul>
</template>

<script>
export default {
    name:'NewsPage'

}
</script>

使用两个子组件

//MyHome.vue
<template>
     <div>
        <h2>Home组件内容</h2>
        <div>
        <ul class="nav nav-tabs">
            <li>
            <router-link class="list-group-item" active-class="active" to="/home/news">News</router-link>
            </li>
            <li>
            <router-link class="list-group-item " active-class="active" to="/home/message">Message</router-link>
            </li>
        </ul>
        <router-view></router-view>
        </div>
     </div>
</template>

<script>
export default {
    name:"MyHome"

}
</script>

配置多级路由

//src/router/index.js,配置多级路由
import VueRouter from "vue-router";

import MyAbout from '../components/pages/MyAbout'
import MyHome from '../components/pages/MyHome'

import NewsPage from '../components/pages/NewsPage'
import MessagePage from '../components/pages/MessagePage'

export default new VueRouter({
    routes:[
        {
            path:'/about',
            component:MyAbout
        },
        {
            path:'/home',
            component:MyHome,
            children:[
                {
                    path:'news',
                    component:NewsPage
                },
                {
                    path:'message',
                    component:MessagePage
                }
            ]
        }
    ]
})

2.3、路由的query参数

首先创建一个属于MessagePage的三级的路由DetailPage.vue,并用组件上的$route获取query上的id和name的值

// pages/DetailPage.vue
<template>
  <div>
      {{$route.query.id}}
      {{$route.query.name}}
  </div>
</template>

<script>
export default {
    name:'DetailPage',
}
</script>

再router里面配置路由

// src/router/index.js
import VueRouter from "vue-router";

import MyAbout from '../components/pages/MyAbout'
import MyHome from '../components/pages/MyHome'

import NewsPage from '../components/pages/NewsPage'
import MessagePage from '../components/pages/MessagePage'

import DetailPage from "../components/pages/DetailPage"

export default new VueRouter({
    routes:[
        {
            path:'/about',
            component:MyAbout
        },
        {
            path:'/home',
            component:MyHome,
            children:[
                {
                    path:'news',
                    component:NewsPage
                },
                {
                    path:'message',
                    component:MessagePage,
                    children:[
                        {
                            path:'detail',
                            component:DetailPage
                        }
                    ]
                }
            ]
        }
    ]
})

在MessagePage.vue里面传入query,有两种方式

<!-- MessagePage.vue -->
<template>
     <div>
        <ul>
            <li v-for="(item) in List" :key="item.id">
                <!-- 
                这是直接写的方式
<router-link :to="`/home/message/detail?id=${item.id}&name=${item.name}`" >{{item.name}}</router-link> -->
            <!--这是通过对象配置的方式-->
                <router-link :to="{
                    path:'/home/message/detail',
                    query:{
                        id:item.id,
                        name:item.name
                    }
                }" 
                >{{item.name}}</router-link>
            </li>
            <hr>
            <router-view></router-view>
        </ul>
    </div>
</template>
<script>
export default {
    name:'MessagePage',
    data(){
        return{
            List:[
                {
                    id:"001",
                    name:'松狮安库萨擦脚'
                },
                {
                    id:"002",
                    name:'阿宝空间囃看囃就睡吧'
                },
                {
                    id:"003",
                    name:'j a s n k ca'
                }
            ]
        }
    }
}
</script>

2.4、路由命名(简化<router-link>里面to的长度)

还是对上面的进行修改

// src/router/index.js
import VueRouter from "vue-router";

import MyAbout from '../components/pages/MyAbout'
import MyHome from '../components/pages/MyHome'

import NewsPage from '../components/pages/NewsPage'
import MessagePage from '../components/pages/MessagePage'

import DetailPage from "../components/pages/DetailPage"

export default new VueRouter({
    routes:[
        {
            path:'/about',
            component:MyAbout
        },
        {
            path:'/home',
            component:MyHome,
            children:[
                {
                    path:'news',
                    component:NewsPage
                },
                {
                    path:'message',
                    component:MessagePage,
                    children:[
                        {
                            //这里加了名字
                            name:'xijie',
                            path:'detail',
                            component:DetailPage
                        }
                    ]
                }
            ]
        }
    ]
})
<!--MessagePage.vue-->
<template>
     <div>
        <ul>
            <li v-for="(item) in List" :key="item.id">
                <!-- <router-link :to="{
                    path:'/home/message/detail',
                    query:{
                        id:item.id,
                        name:item.name
                    }
                }"   -->
                <router-link :to="{
                    //这里就可以直接使用name而不用那么长的path
                    name:'xijie',
                    query:{
                        id:item.id,
                        name:item.name
                    }
                }" 
                >{{item.name}}</router-link>
            </li>
            <hr>
            <router-view></router-view>
        </ul>
    </div>
</template>
<script>
export default {
    name:'MessagePage',
    data(){
        return{
            List:[
                {
                    id:"001",
                    name:'松狮安库萨擦脚'
                },
                {
                    id:"002",
                    name:'阿宝空间囃看囃就睡吧'
                },
                {
                    id:"003",
                    name:'j a s n k ca'
                }
            ]
        }
    }
}
</script>

2.5、路由的params参数

首先在router里面的要跳转的地方加上params参数的占位符

//src/router/index.js 
import VueRouter from "vue-router";

import MyAbout from '../components/pages/MyAbout'
import MyHome from '../components/pages/MyHome'

import NewsPage from '../components/pages/NewsPage'
import MessagePage from '../components/pages/MessagePage'

import DetailPage from "../components/pages/DetailPage"

export default new VueRouter({
    routes:[
        {
            path:'/about',
            component:MyAbout
        },
        {
            path:'/home',
            component:MyHome,
            children:[
                {
                    path:'news',
                    component:NewsPage
                },
                {
                    path:'message',
                    component:MessagePage,
                    children:[
                        {
                            //如果使用对象的形式传params参数的话需要用name,不能用path
                            name:'xijie',
                            //这里记得加上params的占位符
                            path:'detail/:id/:name',
                            component:DetailPage
                        }
                    ]
                }
            ]
        }
    ]
})
<!-- 用$route.params获取params参数 -->
<template>
  <div>
      {{$route.params.id}}
      {{$route.params.name}}
  </div>
</template>

<script>
export default {
    name:'DetailPage',
}
</script>
<!--MessagePage.vue-->
<template>
     <div>
        <ul>
            <li v-for="(item) in List" :key="item.id">
                <!-- 这是直接写的形式 -->
                <!-- <router-link :to="`/home/message/detail/${item.id}/${item.name}`" >{{item.name}}</router-link> -->
                 <!--这是对象形式 注意:使用对象形式传params参数,必须用name,不能用path -->
                <router-link :to="{
                    name:'xijie',
                    params:{
                        id:item.id,
                        name:item.name
                    }
                }" 
                >{{item.name}}</router-link>
            </li>
            <hr>
            <router-view></router-view>
        </ul>
    </div>
</template>
<script>
export default {
    name:'MessagePage',
    data(){
        return{
            List:[
                {
                    id:"001",
                    name:'松狮安库萨擦脚'
                },
                {
                    id:"002",
                    name:'阿宝空间囃看囃就睡吧'
                },
                {
                    id:"003",
                    name:'j a s n k ca'
                }
            ]
        }
    }
}
</script>

2.6、路由的props配置(简化在模版里获取query和params)

首先现在Detail.vue页面用props接受参数进行简写

//Detail.vue
<template>
  <div>
      {{id}}
      {{name}}
  </div>
</template>

<script>
export default {
    name:'DetailPage',
    props:['id','name'],
    mounted(){
      console.log(this.$route)
    }
}
</script>

2.6.1、第一种传props方法

弊端是穿的props是固定的

// router/index.js

import VueRouter from "vue-router";

import MyAbout from '../components/pages/MyAbout'
import MyHome from '../components/pages/MyHome'

import NewsPage from '../components/pages/NewsPage'
import MessagePage from '../components/pages/MessagePage'

import DetailPage from "../components/pages/DetailPage"

export default new VueRouter({
    routes:[
        {
            path:'/about',
            component:MyAbout
        },
        {
            path:'/home',
            component:MyHome,
            children:[
                {
                    path:'news',
                    component:NewsPage
                },
                {
                    path:'message',
                    component:MessagePage,
                    children:[
                        {
                            name:'xijie',
                            path:'detail/:id/:name',
                            component:DetailPage,
                            //这是第一种传props的方法,不好的地方是,穿的值是固定的
                            props:{id:"001",name:'我是第一种props'}
                        }
                    ]
                }
            ]
        }
    ]
})

2.6.2、第二种传props的方式

这种方式,只能吧params的参数通过props传给该组件,缺点是不能传query

// router/index.js
import VueRouter from "vue-router";

import MyAbout from '../components/pages/MyAbout'
import MyHome from '../components/pages/MyHome'

import NewsPage from '../components/pages/NewsPage'
import MessagePage from '../components/pages/MessagePage'

import DetailPage from "../components/pages/DetailPage"

export default new VueRouter({
    routes:[
        {
            path:'/about',
            component:MyAbout
        },
        {
            path:'/home',
            component:MyHome,
            children:[
                {
                    path:'news',
                    component:NewsPage
                },
                {
                    path:'message',
                    component:MessagePage,
                    children:[
                        {
                            name:'xijie',
                            path:'detail/:id/:name',
                            component:DetailPage,
//这种方式,只能吧params的参数通过props传给DetailPage.vue,缺点是不能传query
                            props:true,
                        }
                    ]
                }
            ]
        }
    ]
})

2.6.3、第三种传props的方式

通过函数的方式穿props,props函数会接收到一个$route,然后就可以返回query或者params

import VueRouter from "vue-router";

import MyAbout from '../components/pages/MyAbout'
import MyHome from '../components/pages/MyHome'

import NewsPage from '../components/pages/NewsPage'
import MessagePage from '../components/pages/MessagePage'

import DetailPage from "../components/pages/DetailPage"

export default new VueRouter({
    routes:[
        {
            path:'/about',
            component:MyAbout
        },
        {
            path:'/home',
            component:MyHome,
            children:[
                {
                    path:'news',
                    component:NewsPage
                },
                {
                    path:'message',
                    component:MessagePage,
                    children:[
                        {
                            name:'xijie',
                            path:'detail',
                            component:DetailPage,
//通过函数的方式穿props,props函数会接收到一个$route,然后就可以返回query或者params
                            props($route){
                                return {id:$route.query.id,name:$route.query.name}
                            }
                        }
                    ]
                }
            ]
        }
    ]
})

2.7、<router-link>的replace属性

在router-link上有一个replace属性,添加上以后,他就会替换到上一次的浏览地址,所以点浏览器返回上一次按钮时会到没加replace的那个路由上

<!--MessagePage.vue-->
<template>
     <div>
        <ul>
            <li v-for="(item) in List" :key="item.id">
<!--可以点一下这几个列表,然后再电浏览器的返回,看看结果-->
                <router-link replace :to="{
                    name:'xijie',
                    query:{
                        id:item.id,
                        name:item.name
                    }
                }" 
                >{{item.name}}</router-link>
            </li>
            <hr>
            <router-view></router-view>
        </ul>
    </div>
</template>
<script>
export default {
    name:'MessagePage',
    data(){
        return{
            List:[
                {
                    id:"001",
                    name:'松狮安库萨擦脚'
                },
                {
                    id:"002",
                    name:'阿宝空间囃看囃就睡吧'
                },
                {
                    id:"003",
                    name:'j a s n k ca'
                }
            ]
        }
    }
}
</script>

2.8、脱离router-link实现路由跳转(使用$router的push和replace)

push类似于没加replace,replace类似于加了replace,(什么鬼,哈哈哈)

<!--MessagePage.vue-->
<template>
     <div>
        <ul>
            <li v-for="(item) in List" :key="item.id">
                <button @click="goxijie(item)">{{item.id}}</button>
            </li>
            <hr>
            <router-view></router-view>
        </ul>
    </div>
</template>
<script>
export default {
    name:'MessagePage',
    methods:{
        goxijie(item){
            //这个类似于没加replace的router-link
            // if(this.$route.query.id != item.id){
            //     this.$router.push({
            //         name:'xijie',
            //         query:{
            //             id:item.id,
            //             name:item.name
            //         }
            //     })
            // }
            //这个类似于加了replace的router-link
            if(this.$route.query.id != item.id){
                this.$router.replace({
                    name:'xijie',
                    query:{
                        id:item.id,
                        name:item.name
                    }
                })
            }
        }
    },
    data(){
        return{
            List:[
                {
                    id:"001",
                    name:'松狮安库萨擦脚'
                },
                {
                    id:"002",
                    name:'阿宝空间囃看囃就睡吧'
                },
                {
                    id:"003",
                    name:'j a s n k ca'
                }
            ]
        }
    }
}
</script>

2.9、缓存路由组件

当我们切换路由的时候,上一次的路由页面就会被销毁,如果我们不想让他销毁,就可以使用一个keep-alive组件包裹一下router-view,用include属性可以指定那个路由不被销毁,不指定就是全部不销毁。

加:如果想缓存多个,前面加冒号里面写数组

<!--MyHome.vue-->
<template>
     <div>
        <h2>Home组件内容</h2>
        <div>
        <ul class="nav nav-tabs">
            <li>
            <router-link class="list-group-item" active-class="active" to="/home/news">News</router-link>
            </li>
            <li>
            <router-link class="list-group-item " active-class="active" to="/home/message">Message</router-link>
            </li>
        </ul>
    <!--用keep-alive指定缓存NewsPage这个页面,在被切出去时不被销毁-->

        <keep-alive include="NewsPage">
            <router-view></router-view>
        </keep-alive>
      <!--  
        缓存多个
        <keep-alive :include="['NewsPage']">
           <router-view></router-view>
       </keep-alive>
        -->
        </div>
     </div>
</template>

<script>
export default {
    name:"MyHome"

}
</script>
<!--NewsPage.vue-->
<template>
    <ul>
<!--我们可以在输入框输入文字,当我们切出去,再回来的时候,文字还在-->
        <li>news001<input/></li>
        <li>news002<input/></li>
        <li>news003<input/></li>
    </ul>
</template>

<script>
export default {
    name:'NewsPage'

}
</script>

<style>

</style>

2.10、路由组件的两个新的生命周期钩子(actived和deactivated(失活))

在这样的场景下,当我们在组件一挂载的时候产生一个定时器,当我们销毁页面之前时想让他吧定时器也销毁,这样是可以的,但是当我们这个页面放在了keep-alive里面的时候,就不会出发beforeDestory()这个钩子,这时我们就需要这两个专属于组件的钩子。

相当于当页面显示的时候触发actived钩子

当页面隐藏的时候出发deactived钩子

<!--NewsPage.vue-->
<template>
    <ul>
        <li>news001<input/></li>
        <li>news002<input/></li>
        <li>news003<input/></li>
    </ul>
</template>

<script>
export default {
    name:'NewsPage',
//页面显示的时候
    activated(){
        this.timer = setInterval(()=>{console.log("@")},500)
    },
//页面切走了,但是没被销毁的时候,不展示在屏幕上了
    deactivated(){
        clearInterval(this.timer)
    }
}
</script>

<style>

</style>

3、路由守卫

3.1、全局路由守卫

全局前置路由守卫(router.beforeEach()):
我们可以在route上的meta里面存放我们自己想放的属性
然后通过router的beforeEach判断这个路由需不需要校验权限,需要的话进行校验,不需要的话直接通过next放行。

全局后置路由守卫(afterEach()):
这个守卫没有next放行的权限,只有在页面完成了跳转才会执行,一般用在设置网页的title。

//src/router/index.js
import VueRouter from "vue-router";

import MyAbout from '../components/pages/MyAbout'
import MyHome from '../components/pages/MyHome'

import NewsPage from '../components/pages/NewsPage'
import MessagePage from '../components/pages/MessagePage'

import DetailPage from "../components/pages/DetailPage"

const router =  new VueRouter({
    routes:[
        {
            path:'/about',
            component:MyAbout
        },
        {
            path:'/home',
            component:MyHome,
            children:[
                {
                    name:'news',
                    path:'news',
                    component:NewsPage,
                    meta:{isAuth:true}
                },
                {
                    path:'message',
                    component:MessagePage,
                    children:[
                        {
                            name:'xijie',
                            path:'detail',
                            component:DetailPage,
                            // props:{id:"001",name:'我是第一种props'}
                            // props:true,
                            props($route){
                                return {id:$route.query.id,name:$route.query.name}
                            }
                        }
                    ]
                }
            ]
        }
    ]
})
/*
全局前置路由守卫:
我们可以在route上的meta里面存放我们自己想放的属性
然后通过router的beforeEach判断这个路由需不需要校验权限,需要的话进行校验,不需要的话直接通过next放行,
*/
router.beforeEach((to,from,next)=>{
    if(to.meta.isAuth){
        if(localStorage.getItem('pass') == "true"){
            next()
        }else{
            alert('无权查看')
        }
    }else{
        next()
    }
})
/*
全局后置路由守卫
这个守卫没有next放行的权限,只有在页面完成了跳转才会执行,一般用在设置网页的title
*/
router.afterEach((to,from)=>{
    document.title = to.name || '测试title' 
})

export default router

3.2、独享路由守卫

独享路由守卫只有beforeEnter,写法和全局路由守卫的前置守卫一样

//src/router/index.js
import VueRouter from "vue-router";

import MyAbout from '../components/pages/MyAbout'
import MyHome from '../components/pages/MyHome'

import NewsPage from '../components/pages/NewsPage'
import MessagePage from '../components/pages/MessagePage'

import DetailPage from "../components/pages/DetailPage"

const router =  new VueRouter({
    routes:[
        {
            path:'/about',
            component:MyAbout
        },
        {
            path:'/home',
            component:MyHome,
            children:[
                {
                    name:'news',
                    path:'news',
                    component:NewsPage,
                    meta:{isAuth:true},
//这里是局部路由守卫
                    beforeEnter(to,from,next){
                        if(to.meta.isAuth){
                        if(localStorage.getItem('pass') == "true"){
                            next()
                        }else{
                            alert('无权查看')
                        }
                        }else{
                            next()
                        }
                    }
                },
                {
                    path:'message',
                    component:MessagePage,
                    children:[
                        {
                            name:'xijie',
                            path:'detail',
                            component:DetailPage,
                            // props:{id:"001",name:'我是第一种props'}
                            // props:true,
                            props($route){
                                return {id:$route.query.id,name:$route.query.name}
                            }
                        }
                    ]
                }
            ]
        }
    ]
})

router.afterEach((to,from)=>{
    document.title = to.name || '测试title' 
})

export default router

3.3、组件内的路由守卫

这两个守卫是通过路由规则进入或者离开这个路由才会触发beforeRouteEnter(),

beforeRouteLeave()

//MyAbout.vue
<template>
            <h2>我是About的内容</h2>
</template>

<script>
export default {
    name:"MyAbout",
    beforeRouteEnter(to,from,next){
        if(localStorage.getItem('pass') === 'true'){
            next()
        }else{
            alert('权限不足')
        }
    },
    beforeRouteLeave(to,from,next){
        console.log("通过router跳走了")
        next()
    }
}
</script>

4、history模式和hash模式

路由器默认是hash模式,处于hash模式下会在ip后面加上一个“#”,hash模式的兼容性好,打包部署上线完成后,进行路由跳转后,刷新页面,不会产生页面404,而history模式下没有#,但是会出现404,需要后端去用nignx,或者用其他方法,nodejs部署的话在npm上有个connect-history-fallback,可以使用,也可以解决。

Vue2部分完结

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值