前端MVC Vue2學習總結(四)——條件渲染、列表渲染、事件處理器

1、條件渲染

1.一、v-if

在字符串模板中,如 Handlebars ,咱們得像這樣寫一個條件塊:javascript

<!-- Handlebars 模板 -->
{{#if ok}}
  <h1>Yes</h1>
{{/if}}

在 Vue.js ,咱們使用 v-if 指令實現一樣的功能:html

<h1 v-if="ok">Yes</h1>

也能夠用 v-else 添加一個 「else」 塊:前端

<h1 v-if="ok">Yes</h1>
<h1 v-else>No</h1>

1.1.一、template v-if

由於 v-if 是一個指令,須要將它添加到一個元素上。可是若是咱們想切換多個元素呢?此時咱們能夠把一個 <template> 元素當作包裝元素,並在上面使用 v-if,最終的渲染結果不會包含它。vue

<template v-if="ok">
  <h1>Title</h1>
  <p>Paragraph 1</p>
  <p>Paragraph 2</p>
</template>

示例:java

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title>條件渲染</title>
    </head>

    <body>
        <div id="app1">
            <p>
                <button type="button" @click="isShow=!isShow">Toggle isShow</button>
            </p>
            <h1 v-if="isShow">Yes</h1>
            <h1 v-else>No</h1>
            
            
            <template v-if="!isShow">
                <p>item1</p><p>item2</p><p>item3</p>
            </template>
            <template v-else>
                <p>item4</p><p>item5</p><p>item6</p>
            </template>
            
        </div>
        <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            var app1 = new Vue({
                el: "#app1",
                data: {
                    isShow: true
                }
            });
        </script>
    </body>

</html>

結果:webpack

切換git

1.1.二、v-else

能夠用 v-else 指令給 v-if 添加一個 「else」 塊:github

<div v-if="Math.random() > 0.5">
  Sorry
</div>
<div v-else>
  Not sorry
</div>

v-else 元素必須緊跟在 v-if 元素的後面——不然它不能被識別。web

1.1.三、v-else-if

2.1.0 新增v-else-if,顧名思義,充當 v-if 的「else-if 塊」,能夠連續使用:api

<div v-if="type === 'A'">
  A
</div>
<div v-else-if="type === 'B'">
  B
</div>
<div v-else-if="type === 'C'">
  C
</div>
<div v-else>
  Not A/B/C
</div>

相似於 v-elsev-else-if 也必須緊跟在帶 v-if 或者 v-else-if 的元素以後。

示例:

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title>條件渲染</title>
    </head>

    <body>
        <div id="app1">
            <div v-if="Math.random() > 0.5">
                Sorry
            </div>
            <div v-else>
                Not sorry
            </div>

            <div v-if="type === 'A'">
                A
            </div>
            <div v-else-if="type === 'B'">
                B
            </div>
            <div v-else-if="type === 'C'">
                C
            </div>
            <div v-else>
                Not A/B/C
            </div>
        </div>
        <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            var app1 = new Vue({
                el: "#app1",
                data: {
                    type:"C"
                }
            });
        </script>
    </body>

</html>

 

結果:

1.1.四、用 key 管理可複用的元素

Vue 會盡量高效地渲染元素,一般會複用已有元素而不是從頭開始渲染。這麼作除了使 Vue 變得很是快以外,還有其它一些好處。例如,若是你容許用戶在不一樣的登陸方式之間切換:

<template v-if="loginType === 'username'">
  <label>Username</label>
  <input placeholder="Enter your username">
</template>
<template v-else>
  <label>Email</label>
  <input placeholder="Enter your email address">
</template>

本身動手試一試,在輸入框中輸入一些文本,而後按下切換按鈕:那麼在上面的代碼中切換 loginType 將不會清除用戶已經輸入的內容。由於兩個模板使用了相同的元素,<input> 不會被替換掉——僅僅是替換了它的 placeholder

示例:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>條件渲染</title>
    </head>
    <body>
        <div id="app1">
            <template v-if="type==='username'">
                <label>賬號:</label>
                <input placeholder="請輸入您的賬號" />
            </template>
            <template v-else>
                <label>郵箱:</label>
                <input placeholder="請輸入您的電子郵箱" />
            </template>
            <p>
                <a href="" @click.prevent="type='username'">用戶名登陸</a> | <a href="" @click.prevent="type='email'">郵箱登陸</a> 
            </p>
        </div>
        <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            var app1 = new Vue({
                el: "#app1",
                data: {
                    isShow: true,
                    type: "username"
                }
            });
        </script>
    </body>
</html>

 

結果:

點擊郵箱登陸

這樣也不老是符合實際需求,因此 Vue 爲你提供了一種方式來表達「這兩個元素是徹底獨立的,不要複用它們」。只需添加一個具備惟一值的 key 屬性便可:

<template v-if="loginType === 'username'">
  <label>Username</label>
  <input placeholder="Enter your username" key="username-input">
</template>
<template v-else>
  <label>Email</label>
  <input placeholder="Enter your email address" key="email-input">
</template>

如今,每次切換時,輸入框都將被從新渲染。

        <div id="app1">
            <template v-if="type==='username'">
                <label>賬號:</label>
                <input placeholder="請輸入您的賬號" key="username"/>
            </template>
            <template v-else>
                <label>郵箱:</label>
                <input placeholder="請輸入您的電子郵箱" key="email"/>
            </template>
            <p>
                <a href="" @click.prevent="type='username'">用戶名登陸</a> | <a href="" @click.prevent="type='email'">郵箱登陸</a> 
            </p>
        </div>

注意,<label> 元素仍然會被高效地複用,由於它們沒有添加 key 屬性。

1.1.五、v-show

另外一個根據條件展現元素的選項是 v-show 指令。用法大致上同樣:

<h1 v-show="ok">Hello!</h1>

不一樣的是有 v-show 的元素會始終渲染並保持在 DOM 中。v-show 是簡單的切換元素的 CSS 屬性 display 。

注意 v-show 不支持 <template> 語法。

1.二、v-if vs. v-show

v-if 是真實的條件渲染,由於它會確保條件塊在切換當中適當地銷燬與重建條件塊內的事件監聽器和子組件。

v-if 也是惰性的:若是在初始渲染時條件爲假,則什麼也不作——在條件第一次變爲真時纔開始局部編譯(編譯會被緩存起來)。

相比之下, v-show 簡單得多——元素始終被編譯並保留,只是簡單地基於 CSS 切換。

通常來講, v-if 有更高的切換消耗而 v-show 有更高的初始渲染消耗。所以,若是須要頻繁切換使用 v-show 較好,若是在運行時條件不大可能改變則使用 v-if 較好。

官方文檔: http://vuejs.org/guide/conditional.html

2、列表渲染

2.一、v-for

咱們用 v-for 指令根據一組數組的選項列表進行渲染。 v-for 指令須要以item in items 形式的特殊語法, items 是源數據數組而且 item 是數組元素迭代的別名。

基本用法

<ul id="example-1">
  <li v-for="item in items">
    {{ item.message }}
  </li>
</ul>
var example1 = new Vue({
  el: '#example-1',
  data: {
    items: [
      {message: 'foo' },
      {message: 'Bar' }
    ]
  }
})

結果:

  • Foo
  • Bar

在 v-for 塊中,咱們擁有對父做用域屬性的徹底訪問權限。 v-for 還支持一個可選的第二個參數爲當前項的索引。

<ul id="example-2">
  <li v-for="(item, index) in items">
    {{ parentMessage }} - {{ index }} - {{ item.message }}
  </li>
</ul>
var example2 = new Vue({
  el: '#example-2',
  data: {
    parentMessage: 'Parent',
    items: [
      { message: 'Foo' },
      { message: 'Bar' }
    ]
  }
})

結果:

  • Parent - 0 - Foo
  • Parent - 1 - Bar

你也能夠用 of 替代 in 做爲分隔符,由於它是最接近 JavaScript 迭代器的語法:

<div v-for="item of items"></div>

2.1.一、Template v-for

如同 v-if 模板,你也能夠用帶有 v-for 的 <template> 標籤來渲染多個元素塊。例如:

<ul>
  <template v-for="item in items">
    <li>{{ item.msg }}</li>
    <li class="divider"></li>
  </template>
</ul>

2.1.二、對象迭代 v-for

你也能夠用 v-for 經過一個對象的屬性來迭代。

<ul id="repeat-object" class="demo">
  <li v-for="value in object">
    {{ value }}
  </li>
</ul>
new Vue({
  el: '#repeat-object',
  data: {
    object: {
      FirstName: 'John',
      LastName: 'Doe',
      Age: 30
    }
  }
})

結果:

  • John
  • Doe
  • 30

你也能夠提供第二個的參數爲鍵名:

<div v-for="(value, key) in object">
  {{ key }} : {{ value }}
</div>

第三個參數爲索引:

<div v-for="(value, key, index) in object">
  {{ index }}. {{ key }} : {{ value }}
</div>

在遍歷對象時,是按 Object.keys() 的結果遍歷,可是不能保證它的結果在不一樣的 JavaScript 引擎下是一致的。

2.1.三、整數迭代 v-for

v-for 也能夠取整數。在這種狀況下,它將重複屢次模板。

<div>
  <span v-for="n in 10">{{ n }}</span>
</div>

結果:

1 2 3 4 5 6 7 8 9 10
 
示例:
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>列表渲染</title>
    </head>

    <body>
        <div id="app1">
            <ul>
                <template v-for="(user,index) in users">
                    <li>{{index+1}} - {{user.name}}</li>
                    <li>
                        <hr/>
                    </li>
                </template>
            </ul>

            <h3>遍歷對象中的全部屬性value</h3>
            <p v-for="value in product">
                {{value}}
            </p>
            <h3>遍歷對象中的全部屬性value - key</h3>
            <p v-for="(value,key) in product">
                {{key}} - {{value}}
            </p>

            <h3>遍歷對象中的全部屬性value - key - index</h3>
            <p v-for="(value,key,index) in product">
                {{index}} - {{key}} - {{value}}
            </p>
            <h3>整數迭代 v-for</h3>
            <span v-for="n in 20">
                {{n}} - 
            </span>
        </div>
        <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            var app1 = new Vue({
                el: "#app1",
                data: {
                    users: [{
                            name: "tom",
                            age: 18
                        },
                        {
                            name: "rose",
                            age: 87
                        },
                        {
                            name: "mark",
                            age: 16
                        }
                    ],
                    product: {
                        name: "蘋果",
                        price: 5.8,
                        unit: '千克'
                    }
                }
            });
        </script>
    </body>

</html>
結果:

2.1.四、組件 和 v-for

瞭解組件相關知識,查看  組件 。Feel free to skip it and come back later.

在自定義組件裏,你能夠像任何普通元素同樣用 v-for 。

<my-component v-for="item in items"></my-component>

然而他不能自動傳遞數據到組件裏,由於組件有本身獨立的做用域。爲了傳遞迭代數據到組件裏,咱們要用 props :

<my-component
  v-for="(item, index) in items"
  v-bind:item="item"
  v-bind:index="index">
</my-component>

不自動注入 item 到組件裏的緣由是,由於這使得組件會緊密耦合到 v-for 如何運做。在一些狀況下,明確數據的來源可使組件可重用。

下面是一個簡單的 todo list 完整的例子:

<div id="todo-list-example">
  <input
    v-model="newTodoText"
    v-on:keyup.enter="addNewTodo"
    placeholder="Add a todo"
  >
  <ul>
    <li
      is="todo-item"
      v-for="(todo, index) in todos"
      v-bind:title="todo"
      v-on:remove="todos.splice(index, 1)"
    ></li>
  </ul>
</div>
Vue.component('todo-item', {
  template: '
    <li>
      {{ title }}
      <button v-on:click="$emit(\'remove\')">X</button>
    </li>',
  props: ['title']
})
new Vue({
  el: '#todo-list-example',
  data: {
    newTodoText: '',
    todos: [
      'Do the dishes',
      'Take out the trash',
      'Mow the lawn'
    ]
  },
  methods: {
    addNewTodo: function () {
      this.todos.push(this.newTodoText)
      this.newTodoText = ''
    }
  }
})

示例:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>列表渲染</title>
    </head>
    <body>
        <div id="app1">
            任務:<input v-model="newTask" @keyup.enter="addNew" placeholder="請輸入您要完成的任務" />
            <ul>
                <li is="todoitem" v-for="(task,index) in tasks" :title="task" @remove="removeItem(index)"></li>
            </ul>
        </div>
        <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            Vue.component("todoitem", {
                template: "<li>{{title}} <button @click='$emit(\"remove\")'>X</button></li>",
                props: ['title']
            });

            var app1 = new Vue({
                el: "#app1",
                data: {
                    newTask: '',
                    tasks: ["買一本書", "給爸媽打電話", "整理本身的硬盤"]
                },
                methods: {
                    addNew: function() {
                        this.tasks.unshift(this.newTask);
                        this.newTask = '';
                    },
                    removeItem: function(index) {
                        if(confirm('肯定要移除嗎?')) {
                            this.tasks.splice(index, 1);
                        }
                    }
                }
            });
        </script>
    </body>
</html>

結果:

2.二、key

當 Vue.js 用 v-for 正在更新已渲染過的元素列表時,它默認用 「就地複用」 策略。若是數據項的順序被改變,而不是移動 DOM 元素來匹配數據項的順序, Vue 將簡單複用此處每一個元素,而且確保它在特定索引下顯示已被渲染過的每一個元素。這個相似 Vue 1.x 的track-by="$index" 。

這個默認的模式是有效的,可是隻適用於不依賴子組件狀態或臨時 DOM 狀態(例如:表單輸入值)的列表渲染輸出。

爲了給 Vue 一個提示,以便它能跟蹤每一個節點的身份,從而重用和從新排序現有元素,你須要爲每項提供一個惟一 key 屬性。理想的 key 值是每項都有惟一 id。這個特殊的屬性至關於 Vue 1.x 的 track-by ,但它的工做方式相似於一個屬性,因此你須要用v-bind 來綁定動態值(在這裏使用簡寫):

<div v-for="item in items" :key="item.id">
  <!-- 內容 -->
</div>

建議儘量使用 v-for 來提供 key ,除非迭代 DOM 內容足夠簡單,或者你是故意要依賴於默認行爲來得到性能提高。

由於它是 Vue 識別節點的一個通用機制, key 並不特別與 v-for 關聯,key 還具備其餘用途,咱們將在後面的指南中看到其餘用途。

2.三、數組更新檢測

2.3.一、變異方法

Vue 包含一組觀察數組的變異方法,因此它們也將會觸發視圖更新。這些方法以下:

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()

你打開控制檯,而後用前面例子的 items 數組調用突變方法:example1.items.push({ message: 'Baz' }) 。

2.3.二、重塑數組

變異方法(mutation method),顧名思義,會改變被這些方法調用的原始數組。相比之下,也有非變異(non-mutating method)方法,例如: filter()concat()slice() 。這些不會改變原始數組,但老是返回一個新數組。當使用非變異方法時,能夠用新數組替換舊數組:

example1.items = example1.items.filter(function (item) {
  return item.message.match(/Foo/)
})

你可能認爲這將致使 Vue 丟棄現有 DOM 並從新渲染整個列表。幸運的是,事實並不是如此。 Vue 實現了一些智能啓發式方法來最大化 DOM 元素重用,因此用一個含有相同元素的數組去替換原來的數組是很是高效的操做。

示例:

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title>列表渲染</title>
    </head>

    <body>
        <div id="app1">
            <ul>
                <li v-for="n in items">
                    <h2>{{n}}</h2>
                </li>
            </ul>
            <button @click="items.splice(0,3)">修改數組(變異)</button>
            <button @click="items.slice(0,3)">修改數組(不變異)</button>
        </div>
        <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            var app1 = new Vue({
                el: "#app1",
                data: {
                    items:[1,3,5,7,9,2,4,6,8,0]
                }
            });
        </script>
    </body>

</html>

結果:

若是原數組發生了變化則View也會從新渲染,若是原數組未發生變化只是讀取後返回了新的數組對象則不會渲染。

2.3.三、觸發數組狀態更新

因爲 JavaScript 的限制, Vue 不能檢測如下變更的數組:

  1. 當你直接設置一個項的索引時,例如: vm.items[indexOfItem] = newValue
  2. 當你修改數組的長度時,例如: vm.items.length = newLength

爲了不第一種狀況,如下兩種方式將達到像 vm.items[indexOfItem] = newValue 的效果, 同時也將觸發狀態更新:

// Vue.set
Vue.set(example1.items, indexOfItem, newValue)
// Array.prototype.splice`
example1.items.splice(indexOfItem, 1, newValue)

避免第二種狀況,使用 splice

example1.items.splice(newLength)

splice數組詳解:

splice() 方法向/從數組中添加/刪除項目,而後返回被刪除的項目。

註釋:該方法會改變原始數組。

語法
arrayObject.splice(index,howmany,item1,.....,itemX)

index //規定添加/刪除項目的位置,使用負數可從數組結尾處規定位置。
howmany //要刪除的項目數量。若是設置爲 0,則不會刪除項目。
item1, ..., itemX //向數組添加的新項目。

返回值
Array    包含被刪除項目的新數組,若是有的話。

說明
//splice() 方法可刪除從 index 處開始的零個或多個元素,而且用參數列表中聲明的一個或多個值來替換那些被刪除的元素。

//若是從 arrayObject 中刪除了元素,則返回的是含有被刪除的元素的數組。
View Code

示例:

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title>列表渲染</title>
    </head>

    <body>
        <div id="app1">
            <ul>
                <li v-for="n in items">
                    <h2>{{n}}</h2>
                </li>
            </ul>
            <button @click="items[2]=55">修改第3個元素的值爲55(無效)</button>
            <button @click="setValue">Vue.set修改第3個元素的值爲55</button>
            <button @click="items.splice(2,1,55)">Vue.set修改第3個元素的值爲55</button>
        </div>
        <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            var app1 = new Vue({
                el: "#app1",
                data: {
                    items: [1, 3, 5, 7, 9, 2, 4, 6, 8, 0]
                },
                methods: {
                    setValue: function() {
                        Vue.set(this.items, 2, 55);
                    }
                }
            });
        </script>
    </body>

</html>

結果:

2.四、對象更改檢測注意事項

仍是因爲 JavaScript 的限制,Vue 不能檢測對象屬性的添加或刪除:

var vm = new Vue({
  data: {
    a: 1
  }
})
// `vm.a` 如今是響應式的

vm.b = 2
// `vm.b` 不是響應式的

對於已經建立的實例,Vue 不能動態添加根級別的響應式屬性。可是,可使用 Vue.set(object, key, value) 方法向嵌套對象添加響應式屬性。例如,對於:

var vm = new Vue({
  data: {
    userProfile: {
      name: 'Anika'
    }
  }
})

你能夠添加一個新的 age 屬性到嵌套的 userProfile 對象:

Vue.set(vm.userProfile, 'age', 27)

你還可使用 vm.$set 實例方法,它只是全局 Vue.set 的別名:

vm.$set(this.userProfile, 'age', 27)

有時你可能須要爲已有對象賦予多個新屬性,好比使用 Object.assign() 或 _.extend()。在這種狀況下,你應該用兩個對象的屬性建立一個新的對象。因此,若是你想添加新的響應式屬性,不要像這樣:

Object.assign(this.userProfile, {
  age: 27,
  favoriteColor: 'Vue Green'
})

你應該這樣作:

this.userProfile = Object.assign({}, this.userProfile, {
  age: 27,
  favoriteColor: 'Vue Green'
})

示例:

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title>對象更改檢測注意事項</title>
    </head>

    <body>
        <div id="app1">
            <h2>對象更改檢測注意事項</h2>
            {{stu.name}} - {{stu.age}}
            <p>
                <button @click="setAge">在stu對象中添加age屬性並設置值爲100</button>
            </p>
        </div>
        <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            var app1 = new Vue({
                el: "#app1",
                data: {
                    stu:{
                        name:"tom"
                    }
                },
                methods:{
                    setAge:function(){
                        Vue.set(this.stu,'age',100);
                    }
                },
                beforeUpdate:function(){
                    console.log("更新前"+this.name);
                },
                updated:function(){
                    console.log("更新後"+this.name);
                }
            });
        </script>
    </body>

</html>

結果:

注意:

若是data中數據沒有被綁定到DOM中,則修改後DOM不會更新,updated與beforeUpdate事件也不會執行(Hook function)

data 的根元素後加入無效,可使用Vue.set添加元素中的屬性,這樣會變成響應式的成員

2.五、顯示過濾/排序結果

有時,咱們想要顯示一個數組的過濾或排序副本,而不實際改變或重置原始數據。在這種狀況下,能夠建立返回過濾或排序數組的計算屬性。

例如:

<li v-for="n in evenNumbers">{{ n }}</li>
data: {
  numbers: [ 1, 2, 3, 4, 5 ]
},
computed: {
  evenNumbers: function () {
    return this.numbers.filter(function (number) {
      return number % 2 === 0
    })
  }
}

或者,您也可使用在計算屬性是不可行的 method 方法 (例如,在嵌套 v-for 循環中):

<li v-for="n in even(numbers)">{{ n }}</li>
data: {
  numbers: [ 1, 2, 3, 4, 5 ]
},
methods: {
  even: function (numbers) {
    return numbers.filter(function (number) {
      return number % 2 === 0
    })
  }
}

示例:

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title>列表渲染</title>
    </head>

    <body>
        <div id="app1">
            <p>
                <span v-for="n in items">
                    {{n}}
                </span>
            </p>
            <p>
                <span v-for="n in even">
                    {{n}}
                </span></p>
            <p>
                <span v-for="n in odd()">
                    {{n}}
                </span></p>
        </div>
        <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            var app1 = new Vue({
                el: "#app1",
                data: {
                    items: [1, 3, 5, 7, 9, 2, 4, 6, 8, 0]
                },
                computed: {
                    even: function() {
                        return this.items.filter(function(n) {
                            return n % 2 === 0;
                        });
                    }
                },
                methods: {
                    odd: function() {
                        return this.items.filter(function(n) {
                            return n % 2 === 1;
                        });
                    }
                }
            });
        </script>
    </body>

</html>

 

結果:

官方原文:  http://vuejs.org/guide/list.html

3、事件處理器

3.一、監聽事件

能夠用 v-on 指令監聽 DOM 事件來觸發一些 JavaScript 代碼。

示例:

<div id="example-1">
  <button v-on:click="counter += 1">增長 1</button>
  <p>這個按鈕被點擊了 {{ counter }} 次。</p>
</div>
var example1 = new Vue({
  el: '#example-1',
  data: {
    counter: 0
  }
})

結果:

這個按鈕被點擊了 0 次。

3.二、方法事件處理器

許多事件處理的邏輯都很複雜,因此直接把 JavaScript 代碼寫在 v-on 指令中是不可行的。所以 v-on 能夠接收一個定義的方法來調用。

示例:

<div id="example-2">
  <!-- `greet` 是在下面定義的方法名 -->
  <button v-on:click="greet">Greet</button>
</div>
var example2 = new Vue({
  el: '#example-2',
  data: {
    name: 'Vue.js'
  },
  // 在 `methods` 對象中定義方法
  methods: {
    greet: function (event) {
      // `this` 在方法裏指當前 Vue 實例
      alert('Hello ' + this.name + '!')
      // `event` 是原生 DOM 事件
      alert(event.target.tagName)
    }
  }
})
// 也能夠用 JavaScript 直接調用方法
example2.greet() // -> 'Hello Vue.js!'

 

示例:

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title>事件</title>
    </head>

    <body>
        <div id="app1">
            <button v-on:click="greet">問好</button>
        </div>
        <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            var app1 = new Vue({
                el: "#app1",
                data: {
                    name:"tom"
                },
                methods: {
                    greet:function(event){
                        console.log('Hello '+ this.name);
                        console.log('事件對象: '+ event.target.tagName);  //從事件對象中得到標籤名
                        console.log(event);
                        //在原生的事件中this指向的是當前事件對象,這裏是實例
                        event.target.innerHTML="問好了!";
                    }
                }
            });
        </script>
    </body>

</html>

 

結果:

 

3.三、內聯處理器方法

除了直接綁定到一個方法,也能夠用內聯 JavaScript 語句:

<div id="example-3">
  <button v-on:click="say('hi')">Say hi</button>
  <button v-on:click="say('what')">Say what</button>
</div>
new Vue({
  el: '#example-3',
  methods: {
    say: function (message) {
      alert(message)
    }
  }
})

結果:

 

有時也須要在內聯語句處理器中訪問原生 DOM 事件。能夠用特殊變量 $event 把它傳入方法:

<button v-on:click="warn('Form cannot be submitted yet.', $event)">Submit</button>
// ...
methods: {
  warn: function (message, event) {
    // 如今咱們能夠訪問原生事件對象
    if (event) event.preventDefault()
    alert(message)
  }
}

3.四、事件修飾符

在事件處理程序中調用 event.preventDefault() 或 event.stopPropagation() 是很是常見的需求。儘管咱們能夠在 methods 中輕鬆實現這點,但更好的方式是:methods 只有純粹的數據邏輯,而不是去處理 DOM 事件細節。

爲了解決這個問題, Vue.js 爲 v-on 提供了 事件修飾符。經過由點(.)表示的指令後綴來調用修飾符。

  • .stop
  • .prevent
  • .capture
  • .self
<!-- 阻止單擊事件冒泡 -->
<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>

3.五、按鍵修飾符

在監聽鍵盤事件時,咱們常常須要監測常見的鍵值。 Vue 容許爲 v-on 在監聽鍵盤事件時添加按鍵修飾符:

<!-- 只有在 keyCode 是 13 時調用 vm.submit() -->
<input v-on:keyup.13="submit">

記住全部的 keyCode 比較困難,因此 Vue 爲最經常使用的按鍵提供了別名:

<!-- 同上 -->
<input v-on:keyup.enter="submit">
<!-- 縮寫語法 -->
<input @keyup.enter="submit">

所有的按鍵別名:

  • enter
  • tab
  • delete (捕獲 「刪除」 和 「退格」 鍵)
  • esc
  • space
  • up
  • down
  • left
  • right

能夠經過全局 config.keyCodes 對象 自定義按鍵修飾符別名

// 可使用 v-on:keyup.f1
Vue.config.keyCodes.f1 = 112

3.六、爲何在 HTML 中監聽事件?

你可能注意到這種事件監聽的方式違背了關注點分離(separation of concern)傳統理念。沒必要擔憂,由於全部的 Vue.js 事件處理方法和表達式都嚴格綁定在當前視圖的 ViewModel 上,它不會致使任何維護上的困難。實際上,使用 v-on 有幾個好處:

  1. 掃一眼 HTML 模板便能輕鬆定位在 JavaScript 代碼裏對應的方法。

  2. 由於你無須在 JavaScript 裏手動綁定事件,你的 ViewModel 代碼能夠是很是純粹的邏輯,和 DOM 徹底解耦,更易於測試。

  3. 當一個 ViewModel 被銷燬時,全部的事件處理器都會自動被刪除。你無須擔憂如何本身清理它們。

原文: http://vuejs.org/guide/events.html

4、ES2015新增數組方法

ECMAScript2015中新增了9個方法,分別是:

  1. Array.prototype.indexOf
  2. Array.prototype.lastIndexOf
  3. Array.prototype.every
  4. Array.prototype.some
  5. Array.prototype.forEach
  6. Array.prototype.map
  7. Array.prototype.filter
  8. Array.prototype.reduce
  9. Array.prototype.reduceRight

4.一、indexOf()找到的元素位置

indexOf()方法返回在該數組中第一個找到的元素位置,若是它不存在則返回-1。
不使用indexOf時:

var arr = ['apple','orange','pear'],
found = false;
for(var i= 0, l = arr.length; i< l; i++){
if(arr[i] === 'orange'){
found = true;
}
}
console.log("found:",found);

使用後:

var arr = ['apple','orange','pear'];
console.log("found:", arr.indexOf("orange") != -1);

4.二、filter()過濾

該filter()方法建立一個新的匹配過濾條件的數組。
不用 filter() 時

var arr = [
{"name":"apple", "count": 2},
{"name":"orange", "count": 5},
{"name":"pear", "count": 3},
{"name":"orange", "count": 16},
];
var newArr = [];
for(var i= 0, l = arr.length; i< l; i++){
if(arr[i].name === "orange" ){
newArr.push(arr[i]);
}
}
console.log("Filter results:",newArr);

用了 filter():

var arr = [
{"name":"apple", "count": 2},
{"name":"orange", "count": 5},
{"name":"pear", "count": 3},
{"name":"orange", "count": 16},
];

var newArr = arr.filter(function(item){
return item.name === "orange";
});
console.log("Filter results:",newArr);

4.三、forEach()迭代

forEach爲每一個元素執行對應的方法

var arr = [1,2,3,4,5,6,7,8];

// Uses the usual "for" loop to iterate
for(var i= 0, l = arr.length; i< l; i++){
console.log(arr[i]);
}

console.log("========================");

//Uses forEach to iterate
arr.forEach(function(item,index){
console.log(item);
});

forEach是用來替換for循環的

4.四、map()映射

map()對數組的每一個元素進行必定操做(映射)後,會返回一個新的數組

不使用map:

var oldArr = [{first_name:"Colin",last_name:"Toh"},{first_name:"Addy",last_name:"Osmani"},{first_name:"Yehuda",last_name:"Katz"}];

function getNewArr(){

var newArr = [];

for(var i= 0, l = oldArr.length; i< l; i++){
var item = oldArr[i];
item.full_name = [item.first_name,item.last_name].join(" ");
newArr[i] = item;
}

return newArr;
}

console.log(getNewArr());

使用map後:

var oldArr = [{first_name:"Colin",last_name:"Toh"},{first_name:"Addy",last_name:"Osmani"},{first_name:"Yehuda",last_name:"Katz"}];

function getNewArr(){

return oldArr.map(function(item,index){
item.full_name = [item.first_name,item.last_name].join(" ");
return item;
});

}

console.log(getNewArr());

map()是處理服務器返回數據時是一個很是實用的函數。

4.五、reduce()累加器

reduce()能夠實現一個累加器的功能,將數組的每一個值(從左到右)將其下降到一個值。
說實話剛開始理解這句話有點難度,它太抽象了。
場景: 統計一個數組中有多少個不重複的單詞
不使用reduce時:

var arr = ["apple","orange","apple","orange","pear","orange"];

function getWordCnt(){
var obj = {};

for(var i= 0, l = arr.length; i< l; i++){
var item = arr[i];
obj[item] = (obj[item] +1 ) || 1;
}

return obj;
}

console.log(getWordCnt());

使用reduce()後

var arr = ["apple","orange","apple","orange","pear","orange"];

function getWordCnt(){
return arr.reduce(function(prev,next){
prev[next] = (prev[next] + 1) || 1;
return prev;
},{});
}

console.log(getWordCnt());

讓我先解釋一下我本身對reduce的理解。reduce(callback, initialValue)會傳入兩個變量。回調函數(callback)和初始值(initialValue)。假設函數它有個傳入參數,prev和next,index和array。prev和next你是必需要了解的。
通常來說prev是從數組中第一個元素開始的,next是第二個元素。可是當你傳入初始值(initialValue)後,第一個prev將是initivalValue,next將是數組中的第一個元素。
好比:

/*
* 兩者的區別,在console中運行一下便可知曉
*/

var arr = ["apple","orange"];

function noPassValue(){
return arr.reduce(function(prev,next){
console.log("prev:",prev);
console.log("next:",next);

return prev + " " +next;
});
}
function passValue(){
return arr.reduce(function(prev,next){
console.log("prev:",prev);
console.log("next:",next);

prev[next] = 1;
return prev;
},{});
}

console.log("No Additional parameter:",noPassValue());
console.log("----------------");
console.log("With {} as an additional parameter:",passValue());

示例:

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title>列表渲染</title>
    </head>

    <body>
        <div id="app1">
            <span v-for="n in items">
                    {{n}} 
                </span>
            <button @click="indexOfMethod">indexOf()找到的元素位置</button>
            <button @click="filterMethod">filter()過濾</button>
            <button @click="forEachMethod">forEach()迭代</button>
            <button @click="mapMethod">map()映射</button>
            <button @click="reduceMethod">reduce()累加器</button>
        </div>
        <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            var app1 = new Vue({
                el: "#app1",
                data: {
                    items: [1, 3, 7, 9, 2, 4, 6, 8, 3],
                    fruits: [{
                            "name": "apple",
                            "count": 2
                        },
                        {
                            "name": "orange",
                            "count": 5
                        },
                        {
                            "name": "pear",
                            "count": 3
                        },
                        {
                            "name": "orange",
                            "count": 16
                        }
                    ],
                    words: ["apple", "orange", "apple", "orange", "pear", "orange"]
                },
                methods: {
                    indexOfMethod: function() {
                        console.log("數字3第一次出現的位置是:" + this.items.indexOf(3));
                        console.log("數字5第一次出現的位置是:" + this.items.indexOf(5));
                    },
                    filterMethod: function() {
                        //得到數量不小於5的水果
                        var arr1 = this.fruits.filter(function(f) {
                            return f.count >= 5;
                        });
                        console.log(JSON.stringify(arr1));
                        //得到名稱中含有r的水果
                        var arr2 = this.fruits.filter(function(f) {
                            return f.name.match(/r/igm);
                        });
                        console.log(JSON.stringify(arr2));
                    },
                    forEachMethod: function() {
                        this.fruits.forEach(function(obj, index) {
                            console.log(index + "-" + obj.name + "-" + obj.count);
                        });
                    },
                    mapMethod: function() {
                        var arr3 = this.fruits.map(function(obj, index) {
                            obj.showInfo = index + "->水果:" + obj.name + ",數量:" + obj.count;
                            return obj;
                        });
                        console.log(JSON.stringify(arr3));
                    },
                    reduceMethod: function() {
                        var objs = {};
                        for(var i = 0, l = this.words.length; i < l; i++) {
                            var item = this.words[i];
                            objs[item] = (objs[item] + 1) || 1;
                        }
                        console.log(JSON.stringify(objs));

                        var objs2 = this.words.reduce(function(prev, next) {
                            console.log("prev:", JSON.stringify(prev));
                            console.log("next:", JSON.stringify(next));
                            prev[next] = (prev[next] + 1) || 1;
                            return prev;
                        }, {});
                        console.log(JSON.stringify(objs2));
                    }
                }
            });
        </script>
    </body>

</html>

結果:

結果

4.六、VUE UI框架

4.6.一、移動端

1. vonic 一個基於 vue.js 和 ionic 樣式的 UI 框架,用於快速構建移動端單頁應用,很簡約,是我喜歡的風格 star 2.3k

中文文檔 在線預覽

2.vux 基於WeUIVue(2.x)開發的移動端UI組件庫 star 10k

基於webpack+vue-loader+vux能夠快速開發移動端頁面,配合vux-loader方便你在WeUI的基礎上定製須要的樣式。

中文文檔 在線預覽

3.Mint UI 由餓了麼前端團隊推出的 Mint UI 是一個基於 Vue.js 的移動端組件庫 star 8.3k

中文文檔 github地址 在線預覽

4.MUI  最接近原生APP體驗的高性能前端框架 star 7.5k 

中文文檔 github地址

5.Muse-ui   基於 Vue 2.0 和 Material Design 的 UI 組件庫 star 4.9k

中文文檔 github地址 

6.Vant是有贊前端團隊基於有贊統一的規範實現的 Vue 組件庫,提供了一整套 UI 基礎組件和業務組件。star 1k

中文文檔 github地址

 

7.Cube UI star 3k

滴滴 WebApp 團隊 實現的 基於 Vue.js 實現的精緻移動端組件庫

github地址 中文文檔

特性

  • 質量可靠

    由滴滴內部組件庫精簡提煉而來,經歷了業務一年多的考驗,而且每一個組件都有充分單元測試,爲後續集成提供保障。

  • 體驗極致

    以迅速響應、動畫流暢、接近原生爲目標,在交互體驗方面追求極致。

  • 標準規範

    遵循統一的設計交互標準,高度還原設計效果;接口標準化,統一規範使用方式,開發更加簡單高效。

  • 擴展性強

    支持按需引入和後編譯,輕量靈活;擴展性強,能夠方便地基於現有組件實現二次開發

4.6.二、PC端

1)Element 餓了麼 vue 2.0後臺UI框架 (Star:18382)

https://github.com/ElemeFE/element

 

(2)iview組件庫 (Star:10186)

 iView 主要服務於 PC 界面的中後臺業務,很優秀的組件庫,惋惜不適合移動端
https://github.com/iview/iview
https://iviewui.com/

 

(3)vux 基於Vue和WeUI的移動UI組件 (Star:9762)
Vux是基於WeUI和Vue(2.x)開發的移動端UI組件庫,主要服務於微信頁面。
https://github.com/airyland/vux
https://vux.li/

 

(4)Mint-UI 餓了麼移動端組件庫 (Star:8062)
由餓了麼前端團隊推出的 Mint UI 是一個基於 Vue.js 的移動端組件庫
https://github.com/ElemeFE/mint-ui

 

(5)vue-admin 管理面板UI框架 (Star:6289)
https://github.com/vue-bulma/vue-admin

 

(6)vue-material爲 Vue.js 打造的 Material 風格的組件 (Star:4550)
https://github.com/vuematerial/vue-material
https://vuematerial.github.io/#/

 

(7)vue-strap基於 Vue.js 的 Bootstrap 組件 (Star:4400)
https://github.com/yuche/vue-strap
http://yuche.github.io/vue-strap/

 

(8)KeenUI 基於Material Design的UI (Star:3041)
https://josephuspaye.github.io/Keen-UI/

 

(9)vonic (Star:2276)
https://github.com/wangdahoo/vonic/
https://wangdahoo.github.io/vonic/docs/#/

 

(10)Radon-ui awe大神最近寫的一套UI (Star:791)
https://github.com/luojilab/radon-ui

 

(11)N3-components 基於N3ui (Star:781)
https://github.com/N3-components/N3-components

 

(12)vue-carbon (Star:739)
https://github.com/myronliu347/vue-carbon

4.七、數制轉換

JS中,經過利用js方法,能夠很方便的實現2,8,10,16進制之間的相互轉換

一、2,8,16進制格式的數據轉換到10進制數據

var num=parseInt(arg1,arg2);

第一個參數就是須要轉換爲10進制的數,arg2就是被轉換數據的進制值,能夠是2,8,16等。

如:將十六進制的數‘d9’轉爲十進制數:

var num=parseInt(d9,16);//num=217

二、將10進制格式的數據轉爲2,8,16進制格式數據

var num=parseInt(「217」);//若是這個數是字符串格式的,須要執行這一步
var oxNum=num.toString(16);//參數能夠是2,8,16.設置轉換10進制數據到對應進制格式,本例是將num轉成16進制數據 oxNum=d9

三、2,8,10,16任意進制之間轉化

經過10進製做爲媒介,即可以實現任意進制之間相互轉化了

5、示例下載

https://git.coding.net/zhangguo5/vue2.git

小紅書項目要求:

http://www.cnblogs.com/xsblog/p/8144290.html

6、視頻

https://www.bilibili.com/video/av17503637/

相關文章
相關標籤/搜索