Vue现代化使用方法(五)--vue-router

vue-router是vue全家桶中,用来控制路由的插件

安装

依然使用npm进行安装

npm install vue-router --save

基本使用方式

// 在项目目录建立两个文件pageA.vue和pageB.vue
// pageA.vue内容如下
<template>
    <div>
        <p>{{content}}</p>
    </div>
</template>
<script>
    export default {
        data () {
            return {
                content: '这是页面A'
            }
        }
    }
</script>
...
// pageB.vue内容如下
<template>
    <div>
        <p>{{content}}</p>
    </div>
</template>
<script>
    export default {
        data () {
            return {
                content: '这是页面B'
            }
        }
    }
</script>
...
// index.js内容调整如下
import Vue from 'vue';
import app from './index.vue';
import VueRouter from 'vue-router'; // 引入vue-router
Vue.use(VueRouter); // 引用VueRouter

import pageA from './pageA.vue';
import pageB from './pageB.vue';

const routes =  [
    { path: '/pageA', component: pageA },
    { path: '/pageB', component: pageB }
];

const router = new VueRouter({
    routes // (简写)相当于 routes: routes,所以这个变量名在简写下是固定的不可修改,如果用key:value的形式,key值保持这个名词,value对应的变量名可变(routes: newName)
});

let vm = new Vue({
    el: "#app",
    router,
    render: h => h(app) 
});
...
// index.vue内容调整如下
// 因为我们在index.js中设置render渲染区域是index.vue,所以在index.vue中router-view针对是当前组件
// 如果你在index.js的初始化函数中设定render: h => h('router-view'),同时在routes中设置一个默认展示{ path: '/', component: app },那么此时index.vue中的router-view是无效
// to="/pageA"和to="pageA"跳转结果是不一致的,'/pageA'是在路由的根目录替换路由,'pageA'是在当前路由添加路由
<template>
    <div class="wrap">
        <div class="title">
            <router-link to="/pageA">Go to pageA</router-link>
            <router-link to="/pageB">Go to pageB</router-link>
        </div>
        <div class="content">
            <router-view></router-view>
        </div>
    </div>
</template>
<script>
    export default {
        data () {
            return {

            }
        },
        computed: {

        },
        methods: {

        },
        mounted () {
             console.log(this.$router); // 在组件内可以使用this.$router访问路由信息
        },
        created () {

        },
        components: {

        }
    }
</script>

router-link: 是设定路由的导航区域

// 基本参数
to: 路由的指向地址,点击时,默认会把to中参数传给router.push()方法,实现页面跳转
replace: 修改默认跳转的方法,把默认的router.push()替换为router.replace(),这样页面在跳转时,不会有历史记录 
tag: router-link默认会渲染为a标签,使用这个参数可以指定渲染为何标签,而且一样会监听点击事件

router-view: 设定路由内容展示的区域

路由传参

在实际开发中,页面通过URL获取一定参数是比较常见的需求,vue-router可以在routes中设定这些信息

// index.js添加一个可以接收相关参数的匹配
const routes =  [
    { path: '/pageA', component: pageA },
    { path: '/pageA/:id', component: pageA },
    { path: '/pageB', component: pageB }
];
...
// index.vue添加相关参数
<div class="title">
    <router-link to="/pageA">Go to pageA</router-link>
    <router-link to="/pageA/900864">Go to pageA ID</router-link>
    <router-link to="/pageB">Go to pageB</router-link>
</div>
...
// pageA.vue添加对这个参数的处理
<div>
    <p>{{content}} {{ $route.params.id }}</p>
</div>
...
// 在pageA.vue的mounted钩子函数中,查看相关传参数
// this.$route.params输出的就是参数的对象形式,{id: '900864'}
mounted () {
    console.log(this.$route.params);
}
...
// params这个信息只在路由匹配时,才会有输出,默认没有值
// 比如这个例子中的pageA和接收参数的pageA,其实调用是同一个组件,当处在不同的URL下,只有在到了含参数的pageA链接时,mounted才会有输出
// 此时你应该留意到了一个问题,就是我们在对pageA和包含id的pageA进行切换时,mounted这个钩子函数只会执行一次
// 那是因为vue处在这种情况下会尽可能的复用当前组件,并不会销毁重建,所以钩子函数只执行一次
// 如果想要对这种变化进行监听,可以使用beforeRouteEnter,beforeRouteUpdate,beforeRouteLeave这几个钩子函数来进行监听
// 代码做如下改造,next方法是必要的,保证路由可以正常调用
// to是要进入路由的信息,from是离开的路由信息
beforeRouteEnter (to, from, next) {
    console.log('beforeRouteEnter');
    console.log(to);
    console.log(from);
    next();
},
beforeRouteUpdate (to, from, next) {
    console.log('beforeRouteUpdate');
    console.log(to);
    console.log(from);
    next();
},
beforeRouteLeave (to, from, next) {
    console.log('beforeRouteLeave');
    console.log(to);
    console.log(from);
    next();
},

这样在进到路由相关页面这几个钩子函数就会执行,执行时机如函数字名的意思

  • beforeRouteEnter是进入到路由时执行
  • beforeRouteLeave是离开路由时执行
  • beforeRouteUpdate是路由更新时执行

beforeRouteEnter, beforeRouteLeave(上一个路由的beforeRouteLeave是下一个路由的beforeRouteEnter)基本一看就知道如何执行,beforeRouteUpdate是在针对同一路由数据更新时触发

// 在index.vue进行如下调整
<router-link to="/pageA">Go to pageA</router-link>
<router-link to="/pageA/900864">Go to pageA ID:900864</router-link>
<router-link to="/pageA/9527">Go to pageA ID:9527</router-link>
<router-link to="/pageB">Go to pageB</router-link>

这样在点击两个pageA ID进行切换时就会发现,只会触发beforeRouteUpdate的钩子函数,官方还提供了watch方法来监听同一路由的变化,估计是之前没有beforeRouteUpdate才有的方法

路由嵌套

Vue本身可以进行多层组件嵌套,路由为了适配这种多层嵌套,路由本身也可以进行嵌套。

// 在项目目录下新建childPageB-A.vue和childPageB-B.vue
// childPageB-A.vue内容如下
<template>
    <div>
        <p>{{content}}</p>
    </div>
</template>
<script>
    export default {
        data () {
            return {
                content: '这是页面B的子页面A'
            }
        }
    }
</script>
...
// childPageB-B.vue内容如下
<template>
    <div>
        <p>{{content}}</p>
    </div>
</template>
<script>
    export default {
        data () {
            return {
                content: '这是页面B的子页面B'
            }
        }
    }
</script>
...
// index.js路由修改
// 路由中children是用来设置嵌套的子路由,在子路由中path如果添加"/"会被当作根路由
import pageA from './pageA.vue';
import pageB from './pageB.vue';
import pageBA from './childPageB-A.vue';
import pageBB from './childPageB-B.vue';

const routes =  [
    { path: '/pageA', component: pageA },
    { path: '/pageA/:id', component: pageA },
    { path: '/pageB', component: pageB, children:[
        { path: 'pageBA', component: pageBA},
        { path: 'pageBB', component: pageBB}
    ] }
];
...
// index.vue做如下修改,添加到子路由的链接
<router-link to="/pageB">Go to pageB</router-link>
<router-link to="/pageB/pageBA">Go to pageBA</router-link>
<router-link to="/pageB/pageBB">Go to pageBB</router-link>

此时在页面端点击最后两个链接就会发现通过嵌套路由,pageB.vue的组件中也具备路由切换能力

路由命名

路由可以进行多层嵌套而且也可以接受参数,这就意味着在某些情况下路由会变的非常冗长,不如下面这种情况。

// 项目目录下新建childPageA-A.vue,内容如下
<template>
    <div>
        <p>{{content}} {{ $route.params.info }}</p>
    </div>
</template>
<script>
    export default {
        data () {
            return {
                content: '这是页面A的子页面A'
            }
        }
    }
</script>
...
// pageA.vue添加路由渲染区域
<p>{{content}} {{ $route.params.id }}</p>
<router-view></router-view>
...
// index.js添加如下内容
// 引入新建组件
import pageAA from './childPageA-A.vue';
...
// pageA路由添加children
 { path: '/pageA/:id', component: pageA, children: [
    {path: ':info', component: pageAA}
] },
...
// index.vue添加如下内容
<router-link to="/pageA/9527/info">Go to pageA ID:9527 info:info</router-link>

上例中 to="/pageA/9527/info" 其实并不是一种很好的代码体验,这种代码逻辑给别人看的时候,或者一段时间以后自己会看代码时,根本就弄不清路由中相关参数的意义,针对这种情况,我们可以对路由进行命名,并且通过对象的形式传递相关参数

// 在index.js下代码做如下调整
// 在pageA的子路由添加name属性
const routes =  [
    { path: '/pageA', component: pageA },
    { path: '/pageA/:id', component: pageA, children: [
        {path: ':info', name: 'pageA', component: pageAA}
    ] },
    { path: '/pageB', component: pageB, children:[
        { path: 'pageBA', component: pageBA},
        { path: 'pageBB', component: pageBB}
    ] }
];
...
// index.vue下路由做调整
// 注意这里的name属性设定在子路由中,是因为我们期望的URL是"/pageA/9527/info",params会按'value/value'的形式进行拼接,如果我们这时把name属性定义在page: 'pageA/:id'这一层,会因为没有形参接收info值,忽略info的传参,我们这时把name设定在子路由上,此时完整的路由如:'/pageA/:id/:info'
<router-link :to="{ name: 'pageA', params: { id: '9527', info: 'info'} }">Go to pageA ID:9527 info:info</router-link>

使用这种命名路由可以很清晰的看出我们传递的参数是什么

命名视图

通过上面的例子,我们可以看出,借助router-view我们可以实现,在不同区域展示不同的内容,如果我们在对视图进行命名,可以很容易实现类似iframe的页面组合的效果。

// 项目目录下body.vue和footer.vue
// header.vue内容修改如下
<template>
    <div>
        <p>{{ title }}</p>
    </div>
</template>
<script>
    export default {
        data () {
            return {
                title: '这是头部'
            }
        }
    }
</script>
...
// body.vue内容如下
<template>
    <div>
        <p>{{ content }}</p>
    </div>
</template>
<script>
    export default {
        data () {
            return {
                content: '这是body'
            }
        }
    }
</script>
...
// footer.vue内容如下
<template>
    <div>
        <p>{{ footer }}</p>
    </div>
</template>
<script>
    export default {
        data () {
            return {
                footer: '这是footer'
            }
        }
    }
</script>
...
// index.js引入新建组件
import header from './header.vue';
import body from './body.vue';
import footer from './footer.vue';
...
// index.js路由做相关调整
const routes =  [
    { path: '/', components: {
        default: pageA,
        header: header,
        body: body,
        footer: footer
    }},
...
// index.vue页面做相关调整
<div class="content">
    <router-view></router-view>
    <router-view name="header"></router-view>
    <router-view name="body"></router-view>
    <router-view name="footer"></router-view>
</div>

这样在指定的视图中,就会渲染指定内容,如果router-view没有设置name就会默认为default

编程式导航

上面我们都是通过router-link的方式进行页面跳转,除了使用这种方式,我们还可以通过router的相关方法来进行跳转。

router.push(location, onComplete?, onAbort?)

这是插入一条历史记录的跳转方式,类似location.href,参数location是跳转地址,可以是字符形式,也可以是对象形式

// index.vue添加如下代码
<button @click="goPage">Go to pageA</button>
...
// methods下添加goPage方法
goPage () {
    // 效果和to="/pageA"一致
    // 字符形式
    this.$router.push('/pageA');
    // 对象形式
    // 渲染为/pageA/9527/info
    // 要留意使用path时,需不需要添加'/',这个会影响最终渲染的路由路径
    // this.$router.push({ name: 'pageA', params: { id: '9527', info: 'info'} });
    // 使用对象形式,如果使用了path,就会忽略params属性
    // 渲染结果为/pageA
    // this.$router.push({ path: '/pageA', params: { id: '9527', info: 'info'} });
    // 使用path时,可以使用query属性
    // 渲染为/pageA?id=9527&info=info
    // this.$router.push({ path: '/pageA', query: { id: '9527', info: 'info'} });
    // 对象形式使用name时,params和query都可以使用
    // 渲染为/pageA/9527/info?id=9527&info=info
    // this.$router.push({ name: 'pageA', params:{id: '9527', info: 'info'}, query: { id: '9527', info: 'info'} });
}   

至于onComplete和onAbort是在路由跳转完成和失败时分别执行的回调函数

// 添加onComplete方法
// 此时页面完成跳转后触发onComplete
// onAbort应该是在路由被终止时触发,没想到怎么写这例子...
goPage () {
    this.$router.push({ path: '/pageA' }, this.onComplete);
},
onComplete () {
    console.log('页面完成跳转')
}

router.replace(location, onComplete?, onAbort?)

使用方式和push一致,区别在于replace不会产生新的浏览器历史记录,和location.replace类似

router.go

和history.go类似,接收一个数字表示进行历史记录前进几个后退几个

重定向

把某个路由指向到指定路由,使用redirect参数设定

// 在index.js的路由中添加如下信息
// 下面表示如果用户访问'/goPageA'会指向'/pageA'
{ path: '/goPageA', redirect: '/pageA' },
...
// index.vue的模板中添加如下信息
<router-link to="/goPageA">Go to goPageA</router-link>

这时当我们点击页面中这个按钮时,页面会自动重定向到'/pageA',重定向还可以使用对象形式,并且可以传参数

// index.js中路由信息修改
// 下面信息重定向到/pageA/9527/info
{ path: '/goPageA', redirect: {name: 'pageA', params: {id: 9527, info: 'info'}} },

别名

把某些比较长的路由信息设定一个访问别名

// 在index.js的路由进行如下修改
// 对'/pageB/pageBB'这个路由设定一个'/BB'的别名
{ path: '/pageB', component: pageB, children:[
    { path: 'pageBA', component: pageBA},
    { path: 'pageBB', component: pageBB, alias: '/BB'}
] }
...
// 在index.vue代码修改如下
<router-link to="/BB">Go to BB</router-link>

这时如果我们点击该按钮,页面会切换到pageBB的组件中,并且URL上路由为'/BB',当我们点击"Go to pageBB"链接,页面URL会变成'/pageB/pageBB',但页面内容不变,比较有意思的是这时vue-router会触发beforeRouteUpdate的钩子函数

组件与路由的解耦

回看我们之前设定的pageA组件

// $route.params.id是从路由上取id参数来使用,这样很方便,但也限制了这个组件的复用 
<p>{{content}} {{ $route.params.id }}</p>
...
// 通过以下修改,我们把路由相关的参数提出props
// pageA.vue页面修改如下
<div>
    <p>{{content}} {{ id }}</p>
    <router-view></router-view>
</div>
...
props: ['id'],
// childPageA-A.vue页面修改如下
<p>{{content}} {{ info }}</p>
...
props: ['info']
...
// index.js中路由做如下修改
// props设为true把$route.params转为了组件属性,
 { path: '/pageA/:id', component: pageA, props: true, children: [
    {path: ':info', name: 'pageA', props: true, component: pageAA}
] },
// 如果把props设为一个对象,就会直接像组件传递这个对象中的数据,而忽略传递的参数
// 比如下面这样写,则页面中所有的id都会被设为9876,这个特性在设定一些静态参数时比较好用
{ path: '/pageA/:id', component: pageA, props: { id: 9876 }, children: [
    {path: ':info', name: 'pageA', props: true, component: pageAA}
] },

这时我们点击相关链接,发现路由传递的参数依然可以正常使用,而且通过上面的改造,上面的两个组件也与路由进行了解耦,可以当作普通组件使用

导航的跳转监听

vue-router提供了不少钩子函数来监听导航的跳转

在实例化对象上的监听:beforeEach、beforeResolve、afterEach

// 更改index.js路由配置信息
// 添加在路由配置中调用的钩子函数beforeEnter
{ path: '/pageA/:id', component: pageA, props: true, beforeEnter: (to, from, next) => {
    console.log('beforeEnter');
    next();
}, children: [
    {path: ':info', name: 'pageA', props: true, component: pageAA}
] },
...
// 在index.js添加相关钩子函数
const router = new VueRouter({
    routes // (简写)相当于 routes: routes
});
// beforeEach是要进入某个路由时最先执行的钩子函数
router.beforeEach((to, from, next) => {
    console.log('beforeEach');
    console.log(to);
    console.log(from);
    next();
});
// beforeResolve是在组件路由的钩子函数执行完成后,执行这个钩子函数
router.beforeResolve((to, from, next) => {
    console.log('beforeResolve');
    console.log(to);
    console.log(from);
    next();
});
// afterEach是在实例化路由和组件路由都执行完成后,最后执行的钩子函数,这个钩子函数不包含next
router.afterEach((to, from) => {
    console.log('afterEach');
    console.log(to);
    console.log(from);
});
...
// 这时路由相关的钩子函数执行如下
// 进入页面默认执行
beforeEach -> beforeEnter -> beforeRouteEnter -> beforeResolve -> afterEach
...
// 随意切换路由
beforeRouteLeave -> beforeEach -> beforeEnter -> beforeRouteEnter -> beforeResolve -> afterEach
// 在同一级路由切换,这时路由模块并没有切换所以不会触发beforeRouteLeave
beforeEach -> beforeRouteUpdate -> beforeResolve -> afterEach
...
// 按官方文档的解析,整个路由在进行解析时,执行过程如下
1. 导航被触发
2. 如果路由进行切换时是准备进到一个新的路由,并且这个新的路由准备渲染的组件和之前路由的渲染组件不一致,就会尝试去执行旧组件中的beforeRouteLeave函数,如果是在同一个路由下,只是传参不同(比如"/pageA/9527"和"/pageA/900864"),这时并不会执行beforeRouteLeave而是直接执行第3步
3. 尝试执行路由实例化对象beforeEach函数
4-1. 如果路由只是参数不同,这时会尝试执行组件内beforeRouteUpdate函数
4-2-1. 如果路由不同,这时会尝试执行路由配置项中的beforeEnter
4-2-2. 解析异步路由组件(???没看明白指的是什么)
4-2-3. 尝试调用被激活组件的beforeRouteEnter函数
5. 尝试调用路由实例化对象的beforeResolve函数
6. 导航解析完成
7. 尝试调用路由实例化对象的afterEach
8. 触发DOM更新
9. 执行next回调

next用来表示当前路由状态已经被解析,可以继续执行下面的逻辑,next默认不传参,如果传入不同参数,会对路由的执行产生不同的阻断或者跳转。

next(false): 会阻断后续函数执行,并且停留在from路由
next('/') 或 next('{ path: "/" }'): 阻断后续函数执行,并把路由指向要重定向的页面
...
// 在index.js的路由中做如下修改
// 这时你点击与pageA相关的导航,会自动定向到pageB,并且会把路由解析过程重修执行
{ path: '/pageA/:id', component: pageA, props: true, beforeEnter: (to, from, next) => {
    console.log('beforeEnter');
    next('/pageB');
}, children: [
    {path: ':info', name: 'pageA', props: true, component: pageAA}
] },
...
// 在pageA.vue下路由信息添加如下
// next中接收的是一个错误的路由信息
beforeRouteEnter (to, from, next) {
    console.log('beforeRouteEnter');
    console.log(to);
    console.log(from);
    next(this.printInfo);
},
...
// 如果你在路由对象实例化时注册了这个函数
let errMsg = function () {
    console.log('路由解析发生错误,可以在这里进行异常处理');
};

router.onError(() => {
    console.log('onError');
    errMsg();
});

meta信息

在定义路由时,可以设置meta信息来设置一些额外的信息。

// 在index.js的定义路由中,设定相关meta信息
{ path: '/pageA', component: pageA, meta: { requiresAuth: true } },
...
// 在pageA.vue中mounted获取定义的meta信息
mounted () {
    console.log(this.$route.matched[0].meta);
}

过渡

借用transition标签使router-view在切换内容时,能形成类似app切换的效果

统一过渡效果

// 在index.vue模板中做如下修改
<div class="content">
    <transition name="fade" mode="out-in">
        <router-view></router-view>
    </transition>
...
// 在index.vue的样式文件中添加如下样式
<style>
    .fade-enter-active, .fade-leave-active {
        transition: all 1s;
        position: relative;
    }
    .fade-enter, .fade-leave-to {
        opacity: 0;
    }
    .fade-enter {
        left: 50px;
    }
    .fade-leave-to {
        left: -50px;
    }
    .fade-enter-to, .fade-leave {
        opacity: 1;
        left: 0;
    }
</style>

这样在切换不同组件时就会有app切入切出的效果

不同路由组件的过渡效果

// 清除index.vue下的模板过渡效果
<div class="content">
    <router-view></router-view>
...
// pageA.vue下,页面做下面调整
<template>
    <transition name="silde">
        <div>
...
// pageA.vue下添加下面样式
<style>
    .silde-enter-active, .silde-leave-active {
        transition: all 1s;
        position: relative;
    }
    .silde-enter {
        left: 50px;
    }
    .silde-leave-to {
        left: -50px;
    }
    .silde-enter-to, .silde-leave {
        left: 0;
    }
</style>
...
// pageB.vue下添加过渡
<template>
    <transition name="opacity">
        <div>
...
// pageB.vue添加下面样式
<style>
    .opacity-enter-active, .opacity-leave-active {
        transition: all 1s;
        position: relative;
    }
    .opacity-enter, .opacity-leave-to {
        opacity: 0;
    }
    .opacity-enter-to, .opacity-leave {
        opacity: 1;
    }
</style>

这样在切换pageA与pageB的相关路由页面时,会发现pageA与pageB会有不同的过渡效果

滚动行为

在切换页面时,可能会碰到滚动到指定位置的需求,vue-router对此进行了相关封装,使用scrollBehavior使页面滚动到指定位置

// 在index.js中修改代码逻辑
// 在scrollBehavior中return需要跳转的坐标,这样在路由切换时就会跳转到指定位置
const router = new VueRouter({
    routes, // (简写)相当于 routes: routes
    scrollBehavior (to, from, savedPosition) {
        // return 期望滚动到哪个的位置
        return { x: 0, y: 200 }
    }
});
...
// 可以通过promise设置延时滚动
scrollBehavior (to, from, savedPosition) {
    // return 期望滚动到哪个的位置
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve({ x: 0, y: 200 })
        }, 500)
    })
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,602评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,442评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,878评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,306评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,330评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,071评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,382评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,006评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,512评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,965评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,094评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,732评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,283评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,286评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,512评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,536评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,828评论 2 345

推荐阅读更多精彩内容

  • 1路由,其实就是指向的意思,当我点击页面上的home按钮时,页面中就要显示home的内容,如果点击页面上的abou...
    你好陌生人丶阅读 1,613评论 0 6
  • vue-router 基本使用 路由,其实就是指向的意思,当我点击页面上的home按钮时,页面中就要显示home的...
    Jony0114阅读 1,241评论 0 0
  • 用Vue.js + vue-router创建单页应用,是非常简单的,基本是这样的: 组件 → 路由 → 渲染地方 ...
    阿go阅读 1,395评论 0 0
  • vue概述 在官方文档中,有一句话对Vue的定位说的很明确:Vue.js 的核心是一个允许采用简洁的模板语法来声明...
    li4065阅读 7,191评论 0 25
  • 安装 直接下载 在Vue后面加载vue-router,它会自动安装的: NPM 如果在一个模块化工程中使用它,必须...
    oWSQo阅读 762评论 0 0