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中有我们传入的参数:

Vue.js学习(四)_第1张图片
在模板中中,我们可以用$route.query.id获得参数

<router-link to="/login?id=10&name=zs">登录router-link>
<script>
    var com1={
        template: '

登录模块----{{$route.query.id}}----{{$route.query.name}}

'
created(){ // 组件的生命周期钩子函数 console.log(this.$route) // console.log(this.$route.query.id) } };
script>
  • params
    params需要修改path属性,内部实现路由正则表达式设置
    Vue.js学习(四)_第2张图片
<router-link to="/login/12/ls">登录router-link>
<script>
    var com1={
        template: '

登录模块----{{$route.params.id}}----{{$route.params.name}}

'
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">Accountrouter-link>
    <router-view>router-view>

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

<script>
    var com1={
        template: '

登录模块

'
}; var com2={ template: '

注册模块

'
}; 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:'

header

'
}; var leftbox={ template:'

left

'
}; var mainbox={ template:'

main

'
}; 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: '

登录组件

'
}; var register = { template: '

注册组件

'
}; 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的结合体。适用于监听虚拟的

你可能感兴趣的:(Vue.js)