Vue.js入门笔记

MVVM模式

MVVM模式(Model-View-ViewModel),ViewModel是Vue.js的核心,它是一个Vue实例。Vue实例是作用于某一个HTML元素上的,这个元素可以是HTML的body元素,也可以是指定了id的某个元素。从View侧看,ViewModel中的DOM Listeners工具会帮我们监测页面上DOM元素的变化,如果有变化,则更改Model中的数据;从Model侧看,当我们更新Model中的数据时,Data Bindings工具会帮我们更新页面中的DOM元素。
双向绑定:

<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <!--这是我们的View-->
        <div id="app">
            <p>{{ message }}</p>
            <input type="text" v-model="message">
        </div>
    </body>
    <script src="../js/vue/vue.min.js"></script>
    <script>
        // 这是我们的Model
        var exampleData = {
            message: 'hello world!'
        }

        // 创建一个 Vue 实例或 "ViewModel"
        // 它连接 View 与 Model
        new Vue({
            el: '#app',
            data:exampleData
        })
    </script>
</html>
常用指令

Vue.js的指令是以v-开头的,它们作用于HTML元素,指令提供了一些特殊的特性,将指令绑定在元素上时,指令会为绑定的目标元素添加一些特殊的行为,我们可以将指令看作特殊的HTML特性(attribute)。
Vue.js提供了一些常用的内置指令:

  • v-if指令
  • v-show指令
  • v-else指令
  • v-for指令
  • v-bind指令
  • v-on指令

1、v-if是条件渲染指令,它根据表达式的真假来删除和插入元素,它的基本语法:v-if=”expression”
expression是一个返回bool值的表达式,表达式可以是一个bool属性,也可以是一个返回bool的运算式。

<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head> 
    <body>
        <div id="app">
            <h1>hello,vue</h1>
            <h1 v-if="yes">yes</h1>
            <h1 v-if="no">no</h1>
            <h1 v-if="age >= 22">age: {{ age }}</h1>
            <h1 v-if="name.indexOf('james') >= 0">name: {{ name }}</h1>
        </div>
    </body>
    <script src="../js/vue/vue.min.js"></script>
    <script>
       new Vue({
           el:'#app',
           data:{
               yes: true,
               no: false,
               age: 26,
               name: 'curry'
           }
       })
    </script>
</html>

v-if指令是根据条件表达式的值来执行元素的插入或者删除行为。

2、v-show也是条件渲染指令,和v-if指令不同的是,使用v-show指令的元素始终会被渲染到HTML,它只是简单地为元素设置CSS的style属性。

<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head> 
    <body>
        <div id="app">
            <h1>hello,vue</h1>
            <h1 v-show="yes">yes</h1>
            <h1 v-show="no">no</h1>
            <h1 v-show="age >= 22">age: {{ age }}</h1>
            <h1 v-show="name.indexOf('james') >= 0">name: {{ name }}</h1>
        </div>
    </body>
    <script src="../js/vue/vue.min.js"></script>
    <script>
       new Vue({
           el:'#app',
           data:{
               yes: true,
               no: false,
               age: 26,
               name: 'curry'
           }
       })
    </script>
</html>

表达式为false的元素被设置了style=”display:none”样式。

3、v-else指令为v-if或v-show添加一个“else块”。v-else元素必须立即跟在v-if或v-show元素的后面——否则它不能被识别。

<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head> 
    <body>
        <div id="app">
            <h1 v-if="age >= 25">
                age: {{ age }}
            </h1>
            <h1 v-else>name: {{ name }}</h1>
            <hr/>
            <h1 v-show="name.indexOf('keep') >= 0">name: {{ name }}</h1>
            <h1 v-else>sex: {{ sex }}</h1>
        </div>
    </body>
    <script src="../js/vue/vue.min.js"></script>
    <script>
       new Vue({
           el: '#app',
           data:{
               age: 28,
               name: 'keepfool',
               sex: 'male'
           }
       })
    </script>
</html>

4、v-for指令基于一个数组渲染一个列表,语法:v-for=”item in items”。
items是一个数组,item是当前被遍历的数组元素。

<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script src="https://cdn.jsdelivr.net/npm/vue"></script>
    </head>
    <body>
        <div id="app">
            <table>
                <thead>
                    <tr>
                        <th>name</th>
                        <th>age</th>
                        <th>sex</th>
                    </tr>
                </thead>
                <tbody>
                    <tr v-for="person in people">
                        <td>{{ person.name }}</td>
                        <td>{{ person.age }}</td>
                        <td>{{ person.sex }}</td>
                    </tr>
                </tbody>
            </table>
        </div>
    </body>
    <script>
        var vm = new Vue({
            el:'#app',
            data:{
                people:[{
                    name: 'James',
                    age: 33,
                    sex:'male'
                },
                {
                    name: 'curry',
                    age: 27,
                    sex: 'female'
                },
                {
                    name: 'jack',
                    age: 22,
                    sex: 'male'
                }]
            }
        })
    </script>
</html>

5、v-bind指令可以在其名称后面带一个参数,中间放一个冒号隔开,这个参数通常是HTML元素的特性(attribute),
v-bind:argument=”expression”。v-bind指令作用于元素的class特性上。

6、v-on指令用于给监听DOM事件,它的用语法和v-bind是类似的,例如监听<a>元素的点击事件:<a v-on:click="doSomething">
有两种形式调用方法:绑定一个方法(让事件指向方法的引用),或者使用内联语句。
Greet按钮将它的单击事件直接绑定到greet()方法,而Hi按钮则是调用say()方法。

<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script src="https://cdn.jsdelivr.net/npm/vue"></script>
    </head>
    <body>
        <div id="app">
          <p><input type="text" v-model="message"></p>
          <p>
              <button v-on:click="greet">Greet</button>
          </p>
          <p>
              <button v-on:click="say('Hi')">Hi</button>
          </p>
        </div>
    </body>
    <script>
       new Vue({
           el: '#app',
           data: {
               message:'Hello,Vue.js!'
           },
           methods:{
               greet: function(){
                   alert(this.message)
               },
               say:function(msg){
                   alert(msg);
               }
           }
       })
    </script>
</html>

7、Vue.js为最常用的两个指令v-bind和v-on提供了缩写方式。v-bind指令可以缩写为一个冒号,v-on指令可以缩写为@符号。

<a href="javascript:void(0)" :class="activeNumber === n + 1 ? 'active' : ''">{{ n + 1 }}</a>
<button @click="greet">Greet</button>

8、v-model指令来实现双向数据绑定。

<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script src="https://cdn.jsdelivr.net/npm/vue"></script>
    </head>
    <body>
        <div id="app">
            <p>{{ message }}</p>
            <input v-model="message">
        </div>
    </body>
    <script>
      new Vue({
          el: '#app',
          data: {
              message: 'hello world!'
          }
      })
    </script>
</html>
过滤器

Vue.js 允许你自定义过滤器,被用作一些常见的文本格式化,由”管道符”指示。
过滤器可以串联:{{ message | filterA | filterB }}
过滤器是JavaScript函数,可以接受参数:{{ message | filterA('arg1',arg2) }},message是第一个参数,字符串’arg1”将传给过滤器作为第二个参数,arg2表达式的值将被求值然后传给过滤器作为第三个参数。

<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script src="https://cdn.jsdelivr.net/npm/vue"></script>
    </head>
    <body>
        <div id="app">
           {{ message | capitalize }}
        </div>
    </body>
    <script>
       new Vue({
           el: '#app',
           data: {
               message: 'james'
           },
           filters: {
               capitalize : function(value){
                   if(!value){
                       return '';
                   }
                   value = value.toString();
                   return value.charAt(0).toUpperCase() + value.slice(1);
               }
           }
       })
    </script>
</html>
Vue实例

每个 Vue.js 应用都是通过构造函数 Vue 创建一个 Vue 的根实例来启动的。

var vm = new Vue({
    // 选项
})

每个 Vue 实例都会代理其 data 对象里所有的属性,除了 data 属性, Vue 实例暴露了一些有用的实例属性与方法。这些属性与方法都有前缀 $,以便与代理的 data 属性区分。

var data = { a: 1 }
var vm = new Vue({
  el: '#example',
  data: data
})
vm.$data === data // -> true
vm.$el === document.getElementById('example') // -> true
// $watch 是一个实例方法
vm.$watch('a', function (newVal, oldVal) {
  // 这个回调将在 `vm.a`  改变后调用
})

给一个比如 props 中,或者 data 中被观测的对象添加一个新的属性的时候,不能直接添加,必须使用 Vue.set 方法。

Vue.set 方法用来新增对象的属性。如果要增加属性的对象是响应式的,那该方法可以确保属性被创建后也是响应式的,同时触发视图更新。

计算属性

methods和computed,效果上两个都是一样的,但是 computed 是基于它的依赖缓存,只有相关依赖发生改变时才会重新取值。而使用 methods ,在重新渲染的时候,函数总会重新调用执行。
可以说使用 computed 性能会更好,但是如果你不希望缓存,你可以使用 methods 属性。

<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script src="https://cdn.jsdelivr.net/npm/vue"></script>
    </head>
    <body>
        <div id="app">
            <p>原始字符串:{{ message }}</p>
            <p>计算后反转字符串:{{ reversedMessage }}</p>
            <p>使用方法后反转字符串:{{ reversedMethodMessage() }}</p>
        </div>
    </body>
    <script>
        new Vue({
            el: '#app',
            data: {
                message: 'hello world!'
            },
            computed: {
                //计算属性的getter
                reversedMessage: function(){
                    //this指向vm实例
                    return this.message.split('').reverse().join('');
                }
            },
            methods:{
                reversedMethodMessage: function(){
                    return this.message.split('').reverse().join('');
                }
            }
        })
    </script>
</html>

computed 属性默认只有 getter ,不过在需要时你也可以提供一个 setter :

<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script src="https://cdn.jsdelivr.net/npm/vue"></script>
    </head>
    <body>
        <div id="app">
           <p>{{ site }}</p>
        </div>
    </body>
    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                name: 'Google',
                url:'http://www.google.com'
            },
            computed: {
               site:{
                   // getter
                   get: function(){
                       return this.name + ' ' + this.url;
                   },
                   //setter
                   set: function(newValue){
                       var names = newValue.split(' ');
                       this.name = names[0];
                       this.url = names[names.length - 1];
                   }
               }
            }
        })
        //调用setter,vm.name和vm.url也会被对应更新
        vm.site = '百度 http://www.baidu.com';
        document.write('name:' + vm.name);
        document.write('<br>');
        document.write('url' + vm.url);
    </script>
</html>
样式绑定

class 与 style 是 HTML 元素的属性,用于设置元素的样式,我们可以用 v-bind 来设置样式属性。
Vue.js v-bind 在处理 class 和 style 时, 专门增强了它。表达式的结果类型除了字符串之外,还可以是对象或数组。

<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script src="https://cdn.jsdelivr.net/npm/vue"></script>
        <style>
            .active {
                width: 100px;
                height: 100px;
                background: green;
            }
            .text-danger {
                background: red;
            }
        </style>
    </head>
    <body>
        <div id="app">
            <div class="static"
                v-bind:class="{ active: isActive, 'text-danger': hasError }">
            </div>
        </div>
    </body>
    <script>
       new Vue({
           el:'#app',
           data: {
               isActive: true,
               hasError: true
           }
       })
    </script>
</html>

直接绑定对象:

<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script src="https://cdn.jsdelivr.net/npm/vue"></script>
        <style>
            .active {
                width: 100px;
                height: 100px;
                background: green;
            }
            .text-danger {
                background: red;
            }
        </style>
    </head>
    <body>
        <div id="app">
            <div class="static"
                v-bind:class="classObject">
            </div>
        </div>
    </body>
    <script>
       new Vue({
           el:'#app',
           data: {
               classObject: {
                     active: true,
                     'text-danger': true
               }
           }
       })
    </script>
</html>

数组语法:

<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script src="https://cdn.jsdelivr.net/npm/vue"></script>
        <style>
            .active {
                width: 100px;
                height: 100px;
                background: green;
            }
            .text-danger {
                background: red;
            }
        </style>
    </head>
    <body>
        <div id="app">
            <div v-bind:class="[activeClass, errorClass]"></div>
        </div>
    </body>
    <script>
       new Vue({
           el:'#app',
           data: {
                    activeClass: 'active',
                    errorClass: 'text-danger'
               }
       })
    </script>
</html>

三元表达式:

<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script src="https://cdn.jsdelivr.net/npm/vue"></script>
        <style>
            .text-danger {
                width:100px;
                height: 100px;
                background: red;
            }
            .active {
                width: 100px;
                height: 100px;
                background: green;
            }       
        </style>
    </head>
    <body>
       <div id="app">
            <div v-bind:class="[errorClass ,isActive ? activeClass : '']"></div>
        </div>
    <script>
        new Vue({
        el: '#app',
        data: {
            isActive: true,
            activeClass: 'active',
            errorClass: 'text-danger'
        }
        })
    </script>
</html>

v-bind:style设置样式:

<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script src="https://cdn.jsdelivr.net/npm/vue"></script>
    </head>
    <body>
       <div id="app">
           <div v-bind:style="{ color: activeColor,fontSize: fontSize + 'px' }">hello world!</div>
        </div>
    <script>
        new Vue({
        el: '#app',
        data: {
           activeColor: 'red',
           fontSize: 30
         }
        })
    </script>
</html>

使用数组将多个样式应用到一个元素上:

<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script src="https://cdn.jsdelivr.net/npm/vue"></script>
    </head>
    <body>
       <div id="app">
           <div v-bind:style="[baseStyles,overridingStyles]">hello world!</div>
        </div>
    <script>
        new Vue({
        el: '#app',
        data: {
          baseStyles:{
              color: 'green',
              fontSize: '30px'
          },
          overridingStyles: {
              'font-weight':'bold'
          }
         }
        })
    </script>
</html>

其他说明:
1:v-bind动态绑定指令,默认情况下标签自带属性的值是固定的,在为了能够动态的给这些属性添加值,可以使用v-bind:你要动态变化的值=”表达式”
2:v-bind用于绑定属性和数据 ,其缩写为” : ” 也就是v-bind:id === :id
3:v-model用在表单控件上的,用于实现双向数据绑定,所以如果你用在除了表单控件以外的标签是没有任何效果的。

事件修饰符

Vue.js 为 v-on 提供了事件修饰符来处理 DOM 事件细节,如:event.preventDefault() 或 event.stopPropagation()。

Vue.js通过由点(.)表示的指令后缀来调用修饰符。
- .stop
- .prevent
- .capture
- .self
- .once

 <!-- 阻止单击事件冒泡 -->
<a v-on:click.stop="doThis"></a>
<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- 修饰符可以串联 -->
<a v-on:click.stop.prevent="doThat"></a>
<!-- 只有修饰符 -->
<form v-on:submit.prevent></form>
<!-- 添加事件侦听器使用事件捕获模式 -->
<div v-on:click.capture="doThis">...</div>
<!--只有事件在该元素本身(而不是子元素)触发回调-->
<div v-on:click.self="doThat">...</div>
<!--click事件只能点击一次,2.1.4版本新增-->
<a v-on:click.once="doThis"></a>

按键修饰符:
按键别名:
- .enter
- .tab
- .delete (捕获 “删除” 和 “退格” 键)
- .esc
- .space
- .up
- .down
- .left
- .right
- .ctrl
- .alt
- .shift
- .meta

<input @keyup.enter="submit">
表单

可以用 v-model 指令在表单控件元素上创建双向数据绑定。
输入框:

<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script src="https://cdn.jsdelivr.net/npm/vue"></script>

    </head>
    <body>
       <div id="app">
           <p>input 元素:</p>
           <input v-model="message" placeholder="请输入">
           <p>消息是:{{ message }}</p>

           <p>textarea元素</p>
           <p style="white-space:pre">{{ message2 }}</p>
           <textarea v-model="message2" placeholder="多行文本输入"></textarea>
        </div>
    <script>
        new Vue({
            el: '#app',
            data: {
                message: 'hello world',
                message2: '百度地址:www.baidu.com'
            }
        })
    </script>
</html>

多选框:

<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script src="https://cdn.jsdelivr.net/npm/vue"></script>

    </head>
    <body>
       <div id="app">
           <p>单个复选框:</p>
           <input type="checkbox" id="checkbox" v-model="checked">
           <label for="checkbox">{{ checked }}</label>

           <p>多个复选框:</p>
           <input type="checkbox" id="baidu" value="baidu" v-model="checkedNames" >
           <label for="baidu">baidu</label>
           <input type="checkbox" id="ali" value="ali" v-model="checkedNames">
           <label for="ali">ali</label>
           <input type="checkbox" id="qq" value="qq" v-model="checkedNames">
           <label for="qq">qq</label>
           <br>
           <span>选择的值为: {{ checkedNames }}</span>
        </div>     
    <script>
        new Vue({
            el: '#app',
            data: {
                checked: false,
                checkedNames: []
            }
        })
    </script>
</html>

select列表

<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script src="https://cdn.jsdelivr.net/npm/vue"></script>

    </head>
    <body>
       <div id="app">
          <select name="fruit" v-model="selected">
              <option value="">请选择</option>
              <option value="baidu">baidu</option>
              <option value="google">google</option>
          </select>

          <div id="output">
              选择是:{{ selected }}
          </div>
        </div>     
    <script>
        new Vue({
            el: '#app',
            data: {
                selected: ''
            }
        })
    </script>
</html>

修饰符:
1、 .lazy

在默认情况下, v-model 在 input 事件中同步输入框的值与数据,但你可以添加一个修饰符 lazy ,从而转变为在 change 事件中同步:

<!-- 在 "change" 而不是 "input" 事件中更新 -->
<input v-model.lazy="msg" >

2、.number

如果想自动将用户的输入值转为 Number 类型(如果原值的转换结果为 NaN 则返回原值),可以添加一个修饰符 number 给 v-model 来处理输入值:

<input v-model.number="age" type="number">

这通常很有用,因为在 type=”number” 时 HTML 中输入的值也总是会返回字符串类型。
3、.trim

如果要自动过滤用户输入的首尾空格,可以添加 trim 修饰符到 v-model 上过滤输入:

<input v-model.trim="msg">
组件

组件可以扩展 HTML 元素,封装可重用的代码。
注册全局组件语法格式:

Vue.component(tagName,options)

tagName为组件名,options为配置选项。注册后,使用以下方式来调用组件:

<tagName></tagName>

全局组件

<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script src="https://cdn.jsdelivr.net/npm/vue"></script>

    </head>
    <body>
        <div id="app">
            <hello></hello>    
        </div>
    <script>
        //注册组件
        Vue.component('hello',{
            template: '<h1>hello,vue!</h1>'
        })
        new Vue({
         el: '#app',
        })
    </script>
</html>

局部组件

<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script src="https://cdn.jsdelivr.net/npm/vue"></script>      
    </head>
    <body>
        <div id="app">
            <hello></hello>    
        </div>
    <script>
        //注册组件
        var Child = {
            template: '<h1>hello world,vue!</h1>'
        }
        new Vue({
         el: '#app',
         components: {
             // <hello>只在父模板可用
             'hello': Child
         }
        })
    </script>
</html>

Prop
prop 是父组件用来传递数据的一个自定义属性。父组件的数据需要通过 props 把数据传给子组件,子组件需要显式地用 props 选项声明 “prop”。

<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script src="https://cdn.jsdelivr.net/npm/vue"></script>      
    </head>
    <body>
        <div id="app">
            <child message="hello!"></child>
        </div>
    <script>
        //注册组件
        Vue.component('child',{
            //声明props
            props:['message'],
            //也可以在vm实例中像“this.message”这样使用
            template: '<span>{{ message }}</span>'
        })
        new Vue({
            el: '#app'
        })
    </script>
</html>

动态prop

<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script src="https://cdn.jsdelivr.net/npm/vue"></script>      
    </head>
    <body>
        <div id="app">
            <div>
                <input v-model="parentMsg">
                <br>
                <child v-bind:message="parentMsg"></child>
            </div>
        </div>
    <script>
        //注册组件
        Vue.component('child',{
            //声明props
            props:['message'],
            //也可以在vm实例中像“this.message”这样使用
            template: '<span>{{ message }}</span>'
        })
        new Vue({
            el: '#app',
            data:{
                parentMsg: '父组件内容'
            }
        })
    </script>
</html>

prop 是单向绑定的:当父组件的属性变化时,将传导给子组件,但是不会反过来。
v-bind 指令将 todo 传到每一个重复的组件中:

 ```
  <html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script src="https://cdn.jsdelivr.net/npm/vue"></script>      
    </head>
    <body>
        <div id="app">
           <ol>
               <todo-item v-for="item in sites" v-bind:todo="item"></todo-item>
           </ol>
        </div>
    <script>
        //注册组件
        Vue.component('todo-item',{
            props:['todo'],
            template: '<li>{{ todo.text }}</li>'
        })
        new Vue({
            el: '#app',
            data:{
                sites: [
                    {text: 'baidu'},
                    {text: 'ali'},
                    {text: 'qq'}
                ]
            }
        })
    </script>
</html>
```

Prop验证,组件可以为 props 指定验证要求。
prop 是一个对象而不是字符串数组时,它包含验证要求:

Vue.component('example', {
  props: {
    // 基础类型检测 (`null` 意思是任何类型都可以)
    propA: Number,
    // 多种类型
    propB: [String, Number],
    // 必传且是字符串
    propC: {
      type: String,
      required: true
    },
    // 数字,有默认值
    propD: {
      type: Number,
      default: 100
    },
    // 数组/对象的默认值应当由一个工厂函数返回
    propE: {
      type: Object,
      default: function () {
        return { message: 'hello' }
      }
    },
    // 自定义验证函数
    propF: {
      validator: function (value) {
        return value > 10
      }
    }
  }
})

自定义事件
父组件是使用 props 传递数据给子组件,但如果子组件要把数据传递回去,就需要使用自定义事件!

我们可以使用 v-on 绑定自定义事件, 每个 Vue 实例都实现了事件接口(Events interface),即:

  • 使用 $on(eventName) 监听事件
  • 使用 $emit(eventName) 触发事件

另外,父组件可以在使用子组件的地方直接用 v-on 来监听子组件触发的事件。

<div id="app">
    <div id="counter-event-example">
      <p>{{ total }}</p>
      <button-counter v-on:increment="incrementTotal"></button-counter>
      <button-counter v-on:increment="incrementTotal"></button-counter>
    </div>
</div>

<script>
Vue.component('button-counter', {
  template: '<button v-on:click="incrementHandler">{{ counter }}</button>',
  data: function () {
    return {
      counter: 0
    }
  },
  methods: {
    incrementHandler: function () {
      this.counter += 1
      this.$emit('increment')
    }
  },
})
new Vue({
  el: '#counter-event-example',
  data: {
    total: 0
  },
  methods: {
    incrementTotal: function () {
      this.total += 1
    }
  }
})
</script>

如果你想在某个组件的根元素上监听一个原生事件。可以使用 .native 修饰 v-on 。例如:

<myComponent v-on:click.native="doSomething"></myComponent>
自定义指令

除了默认设置的核心指令( v-model 和 v-show ), Vue 也允许注册自定义指令。

<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script src="https://cdn.jsdelivr.net/npm/vue"></script>      
    </head>
    <body>
        <div id="app">
            <p>页面载入时,input元素自动获取焦点</p>
            <input v-focus>
        </div>
    <script>
        //注册一个全局自定义指令 v-focus
        Vue.directive('focus',{
            //当绑定元素插入到dom中
            inserted:function(el){
                //聚焦元素
                el.focus()
            }
        })
        new Vue({
            el: '#app'
        })
    </script>
</html>

注册局部指令,指令只能在这个实例中使用

<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script src="https://cdn.jsdelivr.net/npm/vue"></script>      
    </head>
    <body>
        <div id="app">
            <p>页面载入时,input元素自动获取焦点</p>
            <input v-focus>
        </div>
    <script>
        new Vue({
            el: '#app',
            directives: {
                //注册一个局部的自定义指令 v-focus
                focus: {
                    //指令的定义
                    inserted: function(el){
                        //聚焦元素
                        el.focus()
                    }
                }
            }
        })
    </script>
</html>

钩子
指令定义函数提供了几个钩子函数(可选):

  • bind: 只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作。

  • inserted: 被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于 document 中)。

  • update: 被绑定元素所在的模板更新时调用,而不论绑定值是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新(详细的钩子函数参数见下)。

  • componentUpdated: 被绑定元素所在模板完成一次更新周期时调用。

  • unbind: 只调用一次, 指令与元素解绑时调用。

钩子函数参数:

  • el: 指令所绑定的元素,可以用来直接操作 DOM 。
  • binding: 一个对象,包含以下属性:
    • name: 指令名,不包括 v- 前缀。
    • value: 指令的绑定值, 例如: v-my-directive=”1 + 1”, value 的值是 2。
    • oldValue: 指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
    • expression: 绑定值的字符串形式。 例如 v-my-directive=”1 + 1” , expression 的值是 “1 + 1”。
    • arg: 传给指令的参数。例如 v-my-directive:foo, arg 的值是 “foo”。
    • modifiers: 一个包含修饰符的对象。 例如: v-my-directive.foo.bar, 修饰符对象 modifiers 的值是 { foo: true, bar: true }。
  • vnode: Vue 编译生成的虚拟节点,查阅 VNode API 了解更多详情。
  • oldVnode: 上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script src="https://cdn.jsdelivr.net/npm/vue"></script>      
    </head>
    <body>
        <div id="app"  v-aric:hello.a.b="message">
        </div>
<script>
    Vue.directive('aric', {
    bind: function (el, binding, vnode) {
        var s = JSON.stringify ;
        el.innerHTML =
        'name: '       + s(binding.name) + '<br>' +
        'value: '      + s(binding.value) + '<br>' +
        'expression: ' + s(binding.expression) + '<br>' +
        'argument: '   + s(binding.arg) + '<br>' +
        'modifiers: '  + s(binding.modifiers) + '<br>' +
        'vnode keys: ' + Object.keys(vnode).join(', ')
    }
    })
    new Vue({
    el: '#app',
    data: {
        message: 'hello vue!'
    }
    })
</script>
</html>

不需要其他钩子函数,可以简写函数。

<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script src="https://cdn.jsdelivr.net/npm/vue"></script>      
    </head>
    <body>
        <div id="app">
            <div v-aric="{ color: 'red', text: 'vue 案例'}"></div>
        </div>
<script>
    Vue.directive('aric', function(el,binding){
        //简写方式设置文本及背景颜色
        el.innerHTML = binding.value.text;
        el.style.backgroundColor = binding.value.color;
    })
    new Vue({
        el: '#app'
    })
</script>
</html>
路由

Vue.js 路由允许我们通过不同的 URL 访问不同的内容。通过 Vue.js 可以实现多视图的单页Web应用)。
Vue.js 路由需要载入 vue-router 库.

安装
1、直接下载
https://unpkg.com/vue-router/dist/vue-router.js
NPM,淘宝镜像:
cnpm install vue-router

Vue.js + vue-router,将vue-router加进来,然后配置组件和路由映射,再告诉vue-router在哪里渲染它们。

<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script src="https://cdn.bootcss.com/vue/2.4.2/vue.min.js"></script>
        <script src="https://cdn.bootcss.com/vue-router/2.7.0/vue-router.min.js"></script>    
    </head>
    <body>
        <div id="app">
           <h1>hello vue!</h1>
           <p>
               <!-- 使用router-link组件来导航 -->
               <!-- 通过传入'to'属性指定链接 -->
               <!-- <rounter-link>默认会被渲染成一个<a>标签 -->
               <router-link to="/foo">go to foo</router-link>
               <router-link to="/bar">go to bar</router-link>
           </p>
           <!-- 路由出口 -->
           <!-- 路由匹配到的组件将渲染到这里 -->
           <router-link></router-link>
        </div>
    <script>
        // 1.定义(路由)组件
        // 可以从其他文件 import进来
        const foo = { template: '<div>foo</div>'};
        const bar = { template: '<div>bar</div>'};

        // 2.定义路由
        // 每个路由应该映射一个组件。 其中"component" 可以是
        // 通过 Vue.extend() 创建的组件构造器,
        // 或者,只是一个组件配置对象。
        const routes = [
            { path: '/foo',component: foo},
            { path: '/bar',component: bar}
        ]

        // 3.创建 router 实例,然后传 `routes` 配置
        const router = new VueRouter({
            routes //相当于 routes: routes
        })

        // 4. 创建和挂载根实例。
        // 要通过 router 配置参数注入路由,
        // 从而让整个应用都有路由功能
        const app = new Vue({
            router
        }).$mount('#app')
    </script>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值