vue路由使用以及组件扩展

  1. 定义vue组件

什么是组件: 组件的出现,就是为了拆分Vue实例的代码量的,能够让我们以不同的组件,来划分不同的功能模块,将来我们需要什么样的功能,就可以去调用对应的组件即可。

组件化和模块化的不同:

  1. 模块化:是从代码逻辑的角度进行划分的;方便代码分层开发,保证每个功能模块的职能单一
  2. 组件化:是从UI界面的角度进行划分的;前端的组件化,方便UI组件的重用
  3. 1.1 全局组件定义的种方式

    1.使用 Vue.extend 配合 Vue.component 方法:

    var login = Vue.extend({

        template: '<h1>登录</h1>'
      });
      Vue.component('login', login);

    2.直接使用 Vue.component 方法:

    Vue.component('register', {

        template: '<h1>注册</h1>'
      });

    3.将模板字符串,定义到script标签

    <script id="tmpl" type="x-template">

        <div><a href="#">登录</a> | <a href="#">注册</a></div>
      </script>

    同时,需要使用 Vue.component 来定义组件:

    Vue.component('account', {

        template: '#tmpl'
      });

    4.将模板字符串,定义到template标签

    < template id="tmpl">

        <div><a href="#">登录</a> | <a href="#">注册</a></div>
      </ template >

    同时,需要使用 Vue.component 来定义组件:

    Vue.component('account', {

        template: '#tmpl'
      });

    注意:组件中的DOM结构,有且只能有唯一的根元素(Root Element)来进行包裹!

    1.2 组件中展示数据和响应事件

在组件中,data需要被定义为一个方法,例如:

Vue.component('account', {

    template: '#tmpl',
    data() {
      return {
        msg: '大家好!'
      }
    },
    methods:{
      login(){
        alert('点击了登录按钮');
      }
    }
  });

在子组件中,如果将模板字符串,定义到了script标签中,那么,要访问子组件身上的data属性中的值,需要使用this来访问;

【重点】为什么组件中的data属性必须定义为一个方法并返回一个对象

示例:

<!DOCTYPE html>

<html lang="en">

<head>

  <meta charset="UTF-8">

  <meta name="viewport" content="width=device-width, initial-scale=1.0">

  <meta http-equiv="X-UA-Compatible" content="ie=edge">

  <title>Document</title>

  <script src="./lib/vue-2.4.0.js"></script>

</head>

<body>

  <div id="app">

    <counter></counter>

    <hr>

    <counter></counter>

    <hr>

    <counter></counter>

  </div>

  <template id="tmpl">

    <div>

      <input type="button" value="+1" @click="increment">

      <h3>{{count}}</h3>

    </div>

  </template>

  <script>

    var dataObj = { count: 0 }

    // 这是一个计数器的组件, 身上有个按钮,每当点击按钮,让 data 中的 count 值 +1

    Vue.component('counter', {

      template: '#tmpl',

      data: function () {

        // return dataObj

        return { count: 0 }

      },

      methods: {

        increment() {

          this.count++

        }

      }

    })

    // 创建 Vue 实例,得到 ViewModel

    var vm = new Vue({

      el: '#app',

      data: {},

      methods: {}

    });

  </script>

</body>

</html>

1.3 使用components属性定义局部组件

组件实例定义方式:

<script>

  // 创建 Vue 实例,得到 ViewModel
  var vm = new Vue({
    el: '#app',
    data: {},
    methods: {},
    components: { // 定义子组件
      account: { // account 组件
        template: '<div><h1>这是Account组件{{name}}</h1><login></login></div>', // 在这里使用定义的子组件
        components: { // 定义子组件的子组件
          login: { // login 组件
            template: "<h3>这是登录组件</h3>"
          }
        }
      }
    }
  });
</script>

引用组件:

<div id="app">

 <account></account>
</div>

使用flag标识符结合v-ifv-else切换组件

页面结构:

<div id="app">

  <input type="button" value="toggle" @click="flag=!flag">
  <my-com1 v-if="flag"></my-com1>
  <my-com2 v-else="flag"></my-com2>
</div>

Vue实例定义:

<script>

  Vue.component('myCom1', {
    template: '<h3>奔波霸</h3>'
  })
  Vue.component('myCom2', {
    template: '<h3>霸波奔</h3>'
  })

  // 创建 Vue 实例,得到 ViewModel
  var vm = new Vue({
    el: '#app',
    data: {
      flag: true
    },
    methods: {}
  });
</script>

1.4 使用:is属性来切换不同子组件,添加切换动画

组件实例定义方式:

// 登录组件

  const login = Vue.extend({
    template: `<div>
      <h3>登录组件</h3>
    </div>`
  });
  Vue.component('login', login);

  // 注册组件
  const register = Vue.extend({
    template: `<div>
      <h3>注册组件</h3>
    </div>`
  });
  Vue.component('register', register);

  // 创建 Vue 实例,得到 ViewModel
  var vm = new Vue({
    el: '#app',
    data: { comName: 'login' },
    methods: {}
  });

使用component标签,来引用组件,并通过:is属性来指定要加载的组件:

<div id="app">

<a href="#" @click.prevent="comName='login'">登录</a>
  <a href="#" @click.prevent="comName='register'">注册</a>
  <hr>
  <transition mode="out-in">
    <component :is="comName"></component>
  </transition>
</div>

添加切换样式:

<style>

.v-enter,
  .v-leave-to {
    opacity: 0;
    transform: translateX(30px);
  }

  .v-enter-active,
  .v-leave-active {
    position: absolute;
    transition: all 0.3s ease;
  }
​  h3{
    margin: 0;
  }
</style>

1.5 父组件传值子组件

  1. 接受父组件传值

设置props属性就可以接受父组件传值

示例:

// html部分

<son :parent-msg='msg' :list='list'></son>

<template id='myComTemp'>

    <div>

        <button @click='changeMsg'>修改parentMsg</button>

        <h1>你好{{parentMsg}}</h1>

        <ul>

            <li v-for='item in list'>{{item.name}}</li>

        </ul>

    </div>

</template>

// 组件定义部分

var vm = new Vue({

    el: '#app',

    components: {

        son: {

            template: '#myComTemp',

            // 定义父组件传过来的值

            props: ['parentMsg', 'list']

        }

    }

})

  1. 设置传递类型

props: {

     // 规定了父组件只能传对象类型

     prop1:Object

// 可以设置多个类型,可以传Number也可以传String

  parentMsg: [Number, String],

list: {

            // 设置类型

type: Array,// [Array,String]

// 设置默认值的时候必须使用函数,原理和data必须使用函数是一样的

default: function () {

return [{

name: '这个一个默认的名字'

}]

}

},

}

  1. 属性的继承和传递

属性继承的特征:

父组件的属性会覆盖子组件的属性

class 和 style 会进行合并,不会覆盖

设置禁用继承

加在子组件上的属性,使用了这个属性之后会阻止组件继承父组件的属性,但是class和style除外

inheritAttrs: false

在组件内可以使用$attrs获取父组件传过来的属性

示例:

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <meta http-equiv="X-UA-Compatible" content="ie=edge">

    <title>Document</title>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

    <style>

        .parent-class {

            background-color: bisque;

            color: red

        }

        .son-class {

            color: aquamarine

        }

    </style>

</head>

<body>

    <div id='app'>

        <!-- 如果想传递一个非字符串类型,必须用数据绑定的方式 -->

        <!--

            属性继承的特征:

                父组件的属性会覆盖子组件的属性

                class 和 style 会进行合并,不会覆盖

        -->

        <!-- 通过这种方式就可以为子组件设置一些属性 -->

        <son :parent-msg='msg' required class="parent-class" name='fuzujian'></son>

    </div>

    <template id='myComTemp'>

        <div name='zizujian' class='son-class'>

            <button @click='changeMsg'>修改parentMsg</button>

            <input type="text" :name='$attrs.name' >

            <h1>你好{{parentMsg}}</h1>

            <ul>

                <li v-for='item in list'>{{item.name}}</li>

            </ul>

        </div>

    </template>

    <script>

        var vm = new Vue({

            el: '#app',

            data: {

                msg: '这个父组件的数据',

                list: [{

                        name: '张三'

                    },

                    {

                        name: '李四'

                    },

                    {

                        name: '王五'

                    },

                ]

            },

            components: {

                son: {

                    template: '#myComTemp',

                    // 使用了这个属性之后会阻止组件继承父组件的属性,但是class和style除外

                    inheritAttrs: false,

                    data() {

                        return {

                            sonMsg: '你好'

                        }

                    },

                    methods: {

                        changeMsg() {

                            console.log(this.$attr)

                            console.log(this.parentMsg);

                        }

                    },

                    props: {

                        // 可以设置多个类型

                        parentMsg: [Number, String],

                        list: {

                            type: Array,

                            // 设置默认值的时候必须使用函数,原理和data必须使用函数是一样的

                            default: function () {

                                return [{

                                    name: '这个一个默认的名字'

                                }]

                            }

                        },

                    }

                }

            }

        })

    </script>

</body>

</html>

  1. 注意事项 

data和props的区别

data是组件私有的,props是父组件传过来的

data是可以修改的,props是只读的

1.6 子组件传值父组件

子组件调用父组件的方法

  1. 在父组件中给引用的子组件注册一个事件(这个事件的名字是自定义的)
  2. 子组件可以触发这个事件$emit('事件名字')

子组件给父组件传递数据

  1. $emit方法第二个参数可以定义子组件给父组件传递的内容
  2. 在父组件中怎么拿到这内容

2.1 父组件这个方法没有自定参数,在父组件的方法直接加这个参数就可以拿到

2.2 父组件有自定义参数,可以传入$event也可以拿到子组件传递的数据。通过$event只能传递第一个参数。

示例:

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <meta http-equiv="X-UA-Compatible" content="ie=edge">

    <title>组件自定义事件</title>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

</head>

<body>

    <!-- 1.给组件添加事件 -->

    <div id="app">

        <son v-on:click-son='clickParent($event,"自定义参数")' v-on:click-son2='clickParent2'></son>

    </div>

    <template id='sonTemp'>

        <div>

            <button @click='clickSon'>点击事件</button>

            <button @click='clickSon2'>点击事件2</button>

            <h3>这是子组件的内容</h3>

        </div>

    </template>

    <script>

        var son = {

            template: '#sonTemp',

            methods: {

                clickSon() {

                    console.log('子组件的方法');

                    // 2. 在子组件中触发这个事件

                    // 发射,触发

                    // 通过这种方式,子组件也可以给父组件传值

                    this.$emit('click-son', {

                        name: '张三'

                    })

                },

                clickSon2(){

                    console.log('子组件的方法2');

                    this.$emit('click-son2', 'nihao')

                }

            },

        }

        var vm = new Vue({

            el: '#app',

            data: {},

            methods: {

                // e是接受子组件传过来的参数,msg是这个方法自己参数

                clickParent(e, msg) {

                    console.log(e);

                    console.log('父组件的方法,数据为:' + msg);

                },

                clickParent2(e) {

                    console.log(e);

                }

            },

            components: {

                son

            }

        })

    </script>

</body>

</html>

1.8 ref的使用

  1. 获取dom节点
  1. 给dom节点记上ref属性,可以理解为给dom节点起了个名字。
  2. 加上ref之后,在$refs属性中多了这个元素的引用。
  3. 通过vue实例的$refs属性拿到这个dom元素。

  1. 获取组件
  1. 给组件记上ref属性,可以理解为给组件起了个名字。
  2. 加上ref之后,在$refs属性中多了这个组件的引用。
  3. 通过vue实例的$refs属性拿到这个组件的引用,之后可以通过这个引用调用子组件的方法,或者获取子组件的数据。

示例:

<!DOCTYPE html>

<html lang="en">

<head>

  <meta charset="UTF-8">

  <meta name="viewport" content="width=device-width, initial-scale=1.0">

  <meta http-equiv="X-UA-Compatible" content="ie=edge">

  <title>Document</title>

  <script src="./lib/vue-2.4.0.js"></script>

</head>

<body>

  <div id="app">

    <input type="button" value="获取元素" @click="getElement" ref="mybtn">

    <h3 id="myh3" ref="myh3">哈哈哈, 今天天气太好了!!!</h3>

    <hr>

    <login ref="mylogin"></login>

  </div>

  <script>

    var login = {

      template: '<h1>登录组件</h1>',

      data() {

        return {

          msg: 'son msg'

        }

      },

      methods: {

        show() {

          console.log('调用了子组件的方法')

        }

      }

    }

    // 创建 Vue 实例,得到 ViewModel

    var vm = new Vue({

      el: '#app',

      data: {},

      methods: {

        getElement() {

          // console.log(document.getElementById('myh3').innerText)

          // console.log(this.$refs.myh3.innerText)

          // console.log(this.$refs.mylogin.msg)

          // this.$refs.mylogin.show()

        }

      },

      components: {

        login

      }

    });

  </script>

</body>

</html>

2. Vue中路由的使用

2.1 什么是路由

  1. 后端路由:对于普通的网站,所有的超链接都是URL地址,所有的URL地址都对应服务器上对应的资源
  2. 前端路由:对于单页面应用程序来说,主要通过URL中的hash(#号)来实现不同页面之间的切换,同时,hash有一个特点:HTTP请求中不会包含hash相关的内容;所以,单页面程序中的页面跳转主要用hash实现;
  3. 在单页面应用程序中,这种通过hash改变来切换页面的方式,称作前端路由(区别于后端路由)

官网

2.2 如何使用路由

  1. 路由的安装

直接引用官网提供的cdn

路由的基本使用

  1. 引入js文件,这个js需要放在vue的js后面,自动安装(提供了一个VueRouter的构造方法)
  2. 创建路由new VueRouter(),接受的参数是一个对象
  3. 在实例化的对象里配置属性routes:[],这个数组里的对象包含path属性和component属性
  4. path属性是url的地址,component属性就是显示的组件(传组件的对象)
  5. 创建的路由需要和vue实例关联一下
  6. 路由到的组件显示在哪个位置<router-view></router-view>

示例:

<body>

    <div id="app">

        <!-- 通过路由切换的组件会被放在这里 -->

        <router-view></router-view>

    </div>

    <script>

        const login = {

            template: '<h2>登录</h2>'

        }

        // 这里实例化了一个路由

        const router = new VueRouter({

            routes: [{

                path: '/login',

                //这里需要注意的是我们直接组件的对象放在这里

                component: login

            }]

        });

        var vm = new Vue({

            el: '#app',

            // 把路由挂在到实例上

            router: router

        })

    </script>

</body>

路由的跳转

  1. router-link标签可以设置to属性
  2. 默认是a标签,可以通过tag设置包裹标签

示例:

<router-link to='/login'>登录</router-link>

<router-link to='/registry'>注册</router-link>

路由重定向

redirect可以进行路由的重定向

选中路由高亮

  1. 使用默认的样式

直接设置router-link-active

  1. 自定义样式

配置 linkActiveClass:'自定义的类名'

定义参数

通过query的方式在url后加?参数名=参数的值

获取参数:$route.query.参数名

示例:

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <meta http-equiv="X-UA-Compatible" content="ie=edge">

   <title>路由传递参数</title>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

    <!-- 引入这个路由组件之后提供了一个VueRouter的构造方法 -->

    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>

    <style>

        .router-link-active {

            background-color: aquamarine;

            font-size: 20px;

        }

        .my-active {

            background-color: aquamarine;

            font-size: 20px;

        }

    </style>

</head>

<body>

    <div id="app">

        <!-- 通过路由切换的组件会被放在这里 -->

        <!-- <a href="#/login">登录</a> -->

        <!-- <a href="#/registry">注册</a> -->

        <!-- 通过router-link 进行路由的跳转 -->

        <!-- 通过tag可以指定router-link渲染的界面元素 -->

        <!-- <router-link to='/login' tag='div'>登录</router-link> -->

        <router-link to='/login?id=123&name=张三'>登录</router-link>

        <router-link to='/registry'>注册</router-link>

        <router-link to='/detail?id=999'>某一篇新闻</router-link>

        <router-view></router-view>

    </div>

    <script>

        // 实现简单路由功能的步骤

        // 1. 引入js文件,这个js需要放在vue的js后面,自动安装(提供了一个VueRouter的构造方法)

           // 2. 创建路由new VueRouter(),接受的参数是一个对象

           // 3. 在实例化的对象里配置属性 routes :[],这个数组里的对象包含path属性和component属性

           // 4. path属性是url的地址,component属性就是显示的组件(传组件的对象)

           // 5. 创建的路由需要和vue实例关联一下

           // 6. 路由到的组件显示在哪个位置<router-view></router-view>

        const login = {

            template: '<h2>登录,父组件传递过来的id{{$route.query.id}},name:{{$route.query.name}}</h2>'

        }

        const registry = {

            template: '<h2>注册</h2>'

        }

        const newsDetail = {

            template: '<h2>文章的详情</h2>',

            created() {

                console.log(this.$route.query.id);

                // 根据这个id去请求后台数据,获取完整的新闻内容,之后进行展示

            },

        }

        // 这里实例化了一个路由

        const router = new VueRouter({

            linkActiveClass: 'my-active',

            routes: [{

                path: '/',

                // 通过这种方式,在访问/路径的时候会重定向到/login路径

                redirect: '/login'

            }, {

                path: '/login',

                //这里需要注意的是我们直接组件的对象放在这里

                component: login

            }, {

                path: '/registry',

                component: registry

            }, {

                path: '/detail',

                component: newsDetail

            }]

        });

        var vm = new Vue({

            el: '#app',

            // 把路由挂在到实例上

            router: router

        })

    </script>

</body>

</html>

使用浏览器参数的方式传递参数

  1. 设置路由的时候/路由地址/:参数名
  2. 获取参数$route.params.参数名

示例:

<body>

    <div id="app">

        <!-- 通过路由切换的组件会被放在这里 -->

        <!-- <a href="#/login">登录</a> -->

        <!-- <a href="#/registry">注册</a> -->

        <!-- 通过router-link 进行路由的跳转 -->

        <!-- 通过tag可以指定router-link渲染的界面元素 -->

        <!-- <router-link to='/login' tag='div'>登录</router-link> -->

        <router-link to='/login?id=123&name=张三'>登录</router-link>

        <router-link to='/registry'>注册</router-link>

        <router-link to='/detail/1000'>某一篇新闻</router-link>

        <router-view></router-view>

    </div>

    <script>

      // 实现简单路由功能的步骤

        // 1. 引入js文件,这个js需要放在vue的js后面,自动安装(提供了一个VueRouter的构造方法)

        // 2. 创建路由new VueRouter(),接受的参数是一个对象

        // 3. 在实例化的对象里配置属性 routes :[],这个数组里的对象包含path属性和component属性

        // 4. path属性是url的地址,component属性就是显示的组件(传组件的对象)

        // 5. 创建的路由需要和vue实例关联一下

        // 6. 路由到的组件显示在哪个位置<router-view></router-view>

        const login = {

            template: '<h2>登录,父组件传递过来的id{{$route.query.id}},name:{{$route.query.name}}</h2>'

        }

        const registry = {

            template: '<h2>注册</h2>'

        }

        const newsDetail = {

            template: '<h2>文章的详情</h2>',

            created() {

                console.log(this.$route.params.id);

                // 根据这个id去请求后台数据,获取完整的新闻内容,之后进行展示

            },

        }

        // 这里实例化了一个路由

        const router = new VueRouter({

            linkActiveClass: 'my-active',

            routes: [{

                path: '/',

                // 通过这种方式,在访问/路径的时候会重定向到/login路径

                redirect: '/login'

            }, {

                path: '/login',

                //这里需要注意的是我们直接组件的对象放在这里

                component: login

            }, {

                path: '/registry',

                component: registry

            }, {

                path: '/detail/:id/:name',

                component: newsDetail

            }]

        });

        var vm = new Vue({

            el: '#app',

            // 把路由挂在到实例上

            router: router

        })

    </script>

</body>

组件的嵌套

  1. 声明路由的时候设置children,这是children是一个数组,数组里是路由对象
  2. 这个children的组件就会渲染在它父组件的<router-view>中

示例:

<body>

    <!-- 通过这个路由的嵌套,我们可以实现一些布局 -->

    <div id="app">

        <router-view></router-view>

    </div>

    <template id="parentCompTemp">

  <div>

            <h1>登录注册页面</h1>

            <router-link to='/parent/login'>登录</router-link>

            <router-link to='/parent/registry'>注册</router-link>

            <router-view></router-view>

        </div>

    </template>

    <script>

        const parentComp = {

            template: '#parentCompTemp'

        }

        const login = {

            template: '<h2>登录</h2>'

        }

        const registry = {

            template: '<h2>注册</h2>'

        }

        const newsDetail = {

            template: '<h2>文章的详情</h2>',

            created() {

                console.log(this.$route.query.id);

                // 根据这个id去请求后台数据,获取完整的新闻内容,之后进行展示

            },

        }

        // 这里实例化了一个路由

        const router = new VueRouter({

            linkActiveClass: 'my-active',

            routes: [{

                path: '/',

                // 通过这种方式,在访问/路径的时候会重定向到/login路径

                redirect: '/parent'

            }, {

                path: '/parent',

                component: parentComp,

                // 涉及到了子路由的内容

                children: [{

                        // 这就是用相对路径,相对于父组件的,这个实际路径就是/parent/login

                        path: 'login',

                        component: login

                    }, {

                        // 这就是用相对路径,相对于父组件的,这个实际路径就是/parent/login

                        path: 'registry',

                        component: registry

                    },

                ]

            }]

        });

        var vm = new Vue({

            el: '#app',

            // 把路由挂在到实例上

            router: router

        })

    </script>

</body>

命名视图

  1. 我们之前只能一个地址对应一个组件,现在可以一个地址对应多个组件
  2. components属性设置的
  3. 给router-view设置名字,这个名字和components组件名字是对应的
  4. 设置默认值default对应组件可以设置名字也可以访问

示例:

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <meta http-equiv="X-UA-Compatible" content="ie=edge">

    <title>命名视图</title>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

    <!-- 引入这个路由组件之后提供了一个VueRouter的构造方法 -->

    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>

    <style>

        .router-link-active {

            background-color: aquamarine;

            font-size: 20px;

        }

        .my-active {

            background-color: aquamarine;

            font-size: 20px;

        }

        .header {

            width: 100%;

            height: 80px;

            background-color: red;

        }

        .my-container {

            height: calc(100vh - 80px);

        }

        .sidebar {

            height: 100%;

            float: left;

            width: 200px;

            background-color: gray;

        }

        .main {

            height: 100%;

            margin-left: 200px;

            background-color: khaki;

        }

        body {

            margin: 0

        }

    </style>

</head>

<body>

    <!-- 通过这个路由的嵌套,我们可以实现一些布局 -->

    <div id="app">

        <!-- router-view可以设置名字,指定渲染的组件 -->

        <router-view></router-view>

        <div class='my-container'>

            <router-view name='sidebar'></router-view>

            <router-view name='main'></router-view>

        </div>

    </div>

    <script>

        // 头部

        const header = {

            template: '<div class="header">头部内容</div>'

        }

        // 侧边栏

        const sidebar = {

            template: '<div class="sidebar">侧边栏</div>'

        }

        // 主体

        const main = {

            template: '<div  class="main"> <router-view></router-view>内容</div>'

        }

        const test={

            template: '<div >测试</div>'

        }

        // 这里实例化了一个路由

        const router = new VueRouter({

            linkActiveClass: 'my-active',

            routes: [{

                path: '/',

                // 使用compones可以定义多个组件

                components: {

                // 通过default属性可以设置默认的组件,默认组件只有一个,不写名字也可以渲染

                    default: header,

                    sidebar: sidebar,

                    main

                },

                children:[

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

                ]

            }]

        });

        var vm = new Vue({

            el: '#app',

            // 把路由挂在到实例上

            router: router

        })

    </script>

</body>

</html>

3. 计算属性和监听器

名称案例

  1. 获取完整的名字,需要把姓和名字拼接在一起
  2. 什么时候去拼接在一起(input值改变的时候)
  3. 监听keyup知道input什么时候改变了,在这里就可以获取完整的名字

3.1 Method实现

3.2 Watch用法

监听data中属性的改变:

<div id="app">

  <input type="text" v-model="firstName"> +
  <input type="text" v-model="lastName"> =
  <span>{{fullName}}</span>
</div>

<script>
  // 创建 Vue 实例,得到 ViewModel
  var vm = new Vue({
    el: '#app',
    data: {
      firstName: 'jack',
      lastName: 'chen',
      fullName: 'jack - chen'
    },
    methods: {},
    watch: {
      'firstName': function (newVal, oldVal) { // 第一个参数是新数据,第二个参数是旧数据
        this.fullName = newVal + ' - ' + this.lastName;
      },
      'lastName': function (newVal, oldVal) {
        this.fullName = this.firstName + ' - ' + newVal;
      }
    }
  });
</script>

监听路由对象的改变:

<div id="app">

  <router-link to="/login">登录</router-link>
  <router-link to="/register">注册</router-link>

  <router-view></router-view>
</div>
​<script>
  var login = Vue.extend({
    template: '<h1>登录组件</h1>'
  });

  var register = Vue.extend({
    template: '<h1>注册组件</h1>'
  });

  var router = new VueRouter({
    routes: [
      { path: "/login", component: login },
      { path: "/register", component: register }
    ]
  });

  // 创建 Vue 实例,得到 ViewModel
  var vm = new Vue({
    el: '#app',
    data: {},
    methods: {},
    router: router,
    watch: {
      '$route': function (newVal, oldVal) {
        if (newVal.path === '/login') {
          console.log('这是登录组件');
        }
      }
    }
  });
</script>

3.3 Computed用法

默认只有getter的计算属性:

<div id="app">

  <input type="text" v-model="firstName"> +
  <input type="text" v-model="lastName"> =
  <span>{{fullName}}</span>
</div>

<script>
  // 创建 Vue 实例,得到 ViewModel
  var vm = new Vue({
    el: '#app',
    data: {
      firstName: 'jack',
      lastName: 'chen'
    },
    methods: {},
    computed: { // 计算属性; 特点:当计算属性中所以来的任何一个 data 属性改变之后,都会重新触发 本计算属性 的重新计算,从而更新 fullName 的值
      fullName() {
        return this.firstName + ' - ' + this.lastName;
      }
    }
  });
</script>

定义有getter和setter的计算属性:

<div id="app">

  <input type="text" v-model="firstName">
  <input type="text" v-model="lastName">
  <!-- 点击按钮重新为 计算属性 fullName 赋值 -->
  <input type="button" value="修改fullName" @click="changeName">

  <span>{{fullName}}</span>
</div>

<script>
  // 创建 Vue 实例,得到 ViewModel
  var vm = new Vue({
    el: '#app',
    data: {
      firstName: 'jack',
      lastName: 'chen'
    },
    methods: {
      changeName() {
        this.fullName = 'TOM - chen2';
      }
    },
    computed: {
      fullName: {
        get: function () {
          return this.firstName + ' - ' + this.lastName;
        },
        set: function (newVal) {
          var parts = newVal.split(' - ');
          this.firstName = parts[0];
          this.lastName = parts[1];
        }
      }
    }
  });
</script>

3.4 method、computed和watch的区别

  1. computed属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算。主要当作属性来使用,使用的时候不加();
  2. methods方法表示一个具体的操作,主要书写业务逻辑;
  3. watch一个对象,键是需要观察的表达式,值是对应回调函数。主要用来监听某些特定数据的变化,从而进行某些具体的业务逻辑操作;可以看作是computedmethods的结合体

拓展:nrm的安装使用

作用:提供了一些最常用的NPM包镜像地址,能够让我们快速的切换安装包时候的服务器地址; 什么是镜像:原来包刚一开始是只存在于国外的NPM服务器,但是由于网络原因,经常访问不到,这时候,我们可以在国内,创建一个和官网完全一样的NPM服务器,只不过,数据都是从人家那里拿过来的,除此之外,使用方式完全一样;

如何使用

  1. 运行npm i nrm -g全局安装nrm包;
  2. 使用nrm ls查看当前所有可用的镜像源地址以及当前所使用的镜像源地址;
  3. 使用nrm use npm或nrm use taobao切换不同的镜像源地址;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值