Vue.js学习(四)

上一篇Vue.js(三)主要学习了Vue组件的基本知识,这节主要是学习一下Vue路由

什么是路由?
  • 后端路由:对于普通网站,所有的超链接都是URL地址,所有的URL地址都对应服务器上的对应的资源
  • 前端路由:对于单页面程序来说,主要通过URL中的hash(#)来实现不同页面之间的切换,同时,hash有一个特点:HTTP请求中不会包含hash相关的内容,所以,单页面程序的页面跳转主要用hash来实现。在单页面应用程序中,这种通过hash改变来切换页面的方式,称作前端路由(区别于后端路由)
在vue中使用vue-router
  1. 导包:
    导入vue-router 组件类库,当导入包之后,在window全局对象中,就有了一个路由构造函数,叫做VueRouter
<script src="lib/vue-2.4.0.js"></script>
<script src="lib/vue-router-3.0.1.js"></script>
  1. 创建一个路由对象实例
    先定义两个模板对象
    routes:路由匹配规则,必有两个属性
    + path:监听 哪个路由地址
    + component:如果路由是前面匹配到的path,则表示component对应那个组件。component存放的是组件模板那对象
 var router = new VueRouter({
      routes: [
        { path: '/login', component: login },
        { path: '/register', component: register }
      ]
 });
  1. 关联vue对象
    用来监听URL的变化,然后展示对应组件
 var vm = new Vue({
        el: '#app',
        data: {},
        methods: {},
        router: routerObj 
  1. 使用 router-view 组件来显示匹配到的组件
    router-view相当于占位符
<router-view></router-view>
  1. 使用 router-link 组件来导航
    router-link默认渲染成a标签,有点击触发事件,可以用tag属性设置
<router-link to="/login">登录</router-link>
<router-link to="/register">注册</router-link>
  1. redirect重定向
    由以上代码运行出来的页面,刚渲染出时,页面没有组件模块,只有router-link所显示的内容,只有点击之后,根据事件才有组件显示,这是因为页面进去是根路径,不是我们想要的登录组件,所以我们就需要定义进入页面是要显示的路径

以下是第一种办法,可以用,但是不推荐

  { path: '/', component: login},

这是第二种办法,借用redirect

 var router = new VueRouter({
      routes: [
        { path: '/', redirect: '/login' },
        { path: '/login', component: login },
        { path: '/register', component: register }
      ]
 });
  1. 设置选中路由高亮的方法
    我们可以在Chrome控制台上看到,当选中的导航上有个router-link-active class样式,我们可以修改他,来设置我们的样式
    有两种方法:
    + router-link-active
    重写router-link-active样式
    + linkActiveClass
    定义一个样式名称,写样式

第一种:

.router-link-active{
            color: red;
            font-weight: 800;
            font-style: italic;
            font-size: 80px;
            text-decoration: underline;
 }

第二种:

 var router = new VueRouter({
      routes: [
        { path: '/', redirect: '/login' },
        { path: '/login', component: login },
        { path: '/register', component: register }
      ],
      linkActiveClass:'myActive'
 });
 .myactive {
            color: red;
            font-weight: 800;
            font-style: italic;
            font-size: 80px;
            text-decoration: underline;
        }
  1. 路由切换启动动画
    transition包裹起来,再写上样式,注意加mode
<style>
        .v-enter,
        .v-leave-to {
            opacity: 0;
            transform: translateX(140px);
        }

        .v-enter-active,
        .v-leave-active {
            transition: all 0.5s ease;
        }
    </style>
    <transition mode="out-in">
        <router-view></router-view>
    </transition>
路由规则中定义参数

两种方式:

  • query
    如果在路由中,使用查询字符串,给路由传递参数,则不需要修改路由规则的 path 属性
    通过this.$route(在生命周期函数created中调用)可以获得路由相关的内容,例如,fullPath;我们可以发现,query中有我们传入的参数:

在这里插入图片描述
在模板中中,我们可以用$route.query.id获得参数

<router-link to="/login?id=10&name=zs">登录</router-link>
<script>
    var com1={
        template: '<h1>登录模块----{{$route.query.id}}----{{$route.query.name}}</h1>'created(){ // 组件的生命周期钩子函数
             console.log(this.$route)
            // console.log(this.$route.query.id)
        }
    };
</script>
  • params
    params需要修改path属性,内部实现路由正则表达式设置
    在这里插入图片描述
<router-link to="/login/12/ls">登录</router-link>
<script>
    var com1={
        template: '<h1>登录模块----{{$route.params.id}}----{{$route.params.name}}</h1>'created(){ // 组件的生命周期钩子函数
             console.log(this.$route)
            // console.log(this.$route.query.id)
        }
    };
     var routerObj=new VueRouter({
        routes:[
            {path:'/login/:id/:name',component:com1},
            {path:'/register',component:com2}
        ],
        linkActiveClass:'myactive'
    });
</script>
路由嵌套

实际生活中的应用界面,通常由多层嵌套的组件组合而成。同样地,URL 中各段动态路径也按某种结构对应嵌套的各层组件
应用场景:在选项卡中,顶部有数个导航栏,中间的主体显示的是内容;这个时候,整个页面是一个路由,然后点击选项卡切换不同的路由来展示不同的内容,这个时候就是路由中嵌套路由。
我们使用children属性实现路由嵌套

<div id="app">

    <router-link to="/account">Account</router-link>
    <router-view></router-view>

</div>
<template id="tmpl">
    <div>
        <h1>这是一个Account</h1>
        <router-link to="/account/login">登录</router-link>
        <router-link to="/account/register">注册</router-link>
        <router-view></router-view>
    </div>
</template>

<script>
    var com1={
        template: '<h1>登录模块</h1>'
    };
    var com2={
        template: '<h1>注册模块</h1>'
    };
    var account={
        template:'#tmpl'
    };
    var routerObj=new VueRouter({
        routes:[
           // {path:'/',redirect:'/account'},
            {
                path:'/account',
                component:account,
                children:[
                    {path:'login',component:com1},
                    {path:'register',component:com2}
                ]

            },

        ],
        linkActiveClass:'myactive'
    });
    var vm=new Vue({
        el:'#app',
        data:{},
        methods:{},
        router:routerObj
    })
</script>

注意:1. 子路由path之前不加/,否则永远一根路径开始请求,不方便理解URL地址 2. 在router-link中,路径要写全,写绝对路径

命名视图实现经典布局

通过vue实现上左右经典布局

  • 首先,我们先写三个模板,分别是header、leftbox、mainbox;将这三个模板放在页面上(router-view)
  • 我们需要思考的是:路由规则应该怎么写。我们在进入页面时,三个模板都存在,我们要实现的是,根路径情况下,显示三个模板。vue-router提供了components属性,区别于component,他可以匹配多个组件。components中提供了一个属性default默认匹配。我们在components中定义视图名称:模板对象,通过在HTML标签中的属性name来实现对应
  • 设置各个模板的样式,采用flex布局
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        h1{
            margin: 0;
            padding: 0;
        }
        .headbox{
            background-color: lightgreen;
            height: 80px;
        }
        .content{
            display: flex;
            height: 520px;
        }
        .leftbox{
            background-color: lightblue;
            flex: 2;
        }
        .mainbox{
            background-color: lightgoldenrodyellow;
            flex: 8;
        }
    </style>
<div id="app">
    <router-view></router-view>
    <div class="content">
        <router-view name="left"></router-view>
        <router-view name="main"></router-view>
    </div>

</div>
<script>
    var header={
        template:'<h1 class="headbox">header</h1>'
    };
    var leftbox={
        template:'<h1 class="leftbox">left</h1>'
    };
    var mainbox={
        template:'<h1 class="mainbox">main</h1>'
    };
    var router=new VueRouter({
        routes:[
            {path:'/',components:{
                'default':header,
                    'left':leftbox,
                    'main':mainbox
                }}
        ]
    });
    var vm=new Vue({
        el:'#app',
        data:{},
        router,
        methods:{}
    })
</script>
案例-名称案例

实现firstname+lastname=fullname

  1. 以methods中注册事件实现
    绑定keyup事件
<div id="app">
    <input type="text" v-model="firstname" @keyup="getFullName">+
    <input type="text" v-model="lastname" @keyup="getFullName">=
    <input type="text" v-model="fullname">
</div>

<script>
    var vm=new Vue({
        el:'#app',
        data:{
            firstname:'',
            lastname:'',
            fullname:''
        },
        methods:{
            getFullName(){
                this.fullname=this.firstname+'-'+this.lastname;
            }
        }
    })
</script>
  1. 使用watch属性实现
    watch属性:可以监听data中指定数据的变化,然后触发watch中对应的处理函数
    watch中的处理函数提供了两个参数:nValue、oValue
<div id="app">
    <input type="text" v-model="firstname">+
    <input type="text" v-model="lastname">=
    <input type="text" v-model="fullname">
</div>

<script>
    var vm=new Vue({
        el:'#app',
        data:{
            firstname:'',
            lastname:'',
            fullname:''
        },
        methods:{},
        watch:{
            firstname(nVaule){
                this.fullname=nVaule+'-'+this.lastname;
            },
            'lastname'(nVaule){
                this.fullname=this.firstname+'-'+nVaule;
            }
        }
    })
</script>
  1. computed实现
    computed:在computed中,可以定义一些属性,这些属性叫做计算属性,计算属性的本质就是一个方法,只不过,我们在使用计算属性的时候,是把他们的名称值直接当属性来使用,并不会当作方法来使用
<div id="app">
    <input type="text" v-model="firstname">+
    <input type="text" v-model="lastname">=
    <input type="text" v-model="fullname">
    <p>{{fullname}}</p>
    <p>{{fullname}}</p>
    <p>{{fullname}}</p>
</div>

<script>
    var vm=new Vue({
        el:'#app',
        data:{
            firstname:'',
            lastname:'',
        },
        methods:{},
        computed:{
            'fullname':function () {
                console.log("ok");
                return this.firstname+'-'+this.lastname
            }
        }
    })
</script>
watch监听路由地址的改变

watch适合监听非DOM元素事件(虚拟的)
以下就是借助$route.path监听路由地址的改变

<style>
        .v-enter,
        .v-leave-to {
            opacity: 0;
            transform: translateX(140px);
        }

        .v-enter-active,
        .v-leave-active {
            transition: all 0.5s ease;
        }
    </style>

<body>
<div id="app">
    <router-link to="/login" tag="span">登录</router-link>
    <router-link to="/register">注册</router-link>
   
    <transition mode="out-in">
        <router-view></router-view>
    </transition>
</div>
</body>
<script>
    var login = {
        template: '<h1>登录组件</h1>'
    };

    var register = {
        template: '<h1>注册组件</h1>'
    };
    var routerObj = new VueRouter({
        routes: [ 
            { path: '/login', component: login },
            { path: '/register', component: register }
        ]
    });
    var vm=new Vue({
        el:'#app',
        data:{},
        methods:{},
        watch:{
            '$route.path'(nValue){
                if (nValue==='/login'){
                    console.log('欢迎来到登录页面')
                } else if (nValue==='/register') {
                    console.log('欢迎来到注册页面');
                }
    }
        },
        router: routerObj
    })
</script>
computed 3个注意点
  • 计算属性在引用的时候,一定不加(),直接把它当作属性使用
  • 只要计算属性function内部所用到的任何data数据发生了变化,就会立即重新计算这个计算属性的值
  • 计算属性的求值结果,会被缓存起来,方便下次直接使用。如果计算属性方法内部所有的任何数据都没有发生改变,则不会重新对计算属性求值
watch、methods、computed对比
  • 三者内部定义的都是function,在computed中要return一个值,methods更注重业务逻辑,computed适合数据计算
  • computed:结果会被缓存,除非依赖的属性变化才会重新计算。计算属性当作属性来使用。适用于数据操作
  • methods:表示一个具体的操作,主要是业务逻辑。适用于方法调用
  • watch:一个对象,键是需要观察的表达式,值对应回调函数,主要用来监听某些特定的数据的变化,从而进行某些具体的业务逻辑操作,可看作是computed和methods的结合体。适用于监听虚拟的
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值