Vue.js 2.x筆記:基本語法(2)

1. Vue實例及選項

1.1 建立Vue實例(new Vue instance)

  每一個Vue Application必須建立一個root Vue Instance。html

<script>
    var vm = new Vue({

    });
</script>

  一個Vue實例至關於一個MVVM模式中的ViewModel。在建立Vue實例時,能夠傳入一個選項對象,包含數據、模板、掛載元素、方法、生命週期鉤子等選項。vue

  Vue.js經過構造函數Vue{ option }建立一個Vue實例:node

var vm = new Vue({ option });

1.2 元素選項(The Element Option)

<div id="app"></div>
<script>
    var vm = new Vue({
        el: "#app"
    });
</script>

1.3 數據選項(The Data Option)

<div id="app">{{ title }}</div>
<script>
    var vm = new Vue({
        el: "#app",
        data: {
            title: "標題"
        }
    });
</script>

1.4 生命週期鉤子

  每一個Vue實例建立時,都會經歷一些列的初始化過程,調用相應的生命週期鉤子。npm

  Vue生命週期鉤子:數組

  ◊ created:實例建立完成後調用,此階段完成數據監測等,但還沒有掛載,$el 還不可用。緩存

  ◊ mounted:el 掛載到實例後調用。app

<div id="app">{{ title }}</div>
<script>
    var vm = new Vue({
        el: "#app",
        data: {
            title: "標題"
        },
        created: function () {
            console.log("Vue instance has been created!");
        }
    });
</script>
<div id="app">{{ title }}</div>
<script>
    var vm = new Vue({
        el: "#app",
        data: {
            title: "標題"
        },
        created() {
            console.log("Vue instance has been created!");
        },
        mounted() {
            console.log("mounted:" + this.$el); // <div id="app"></div>
            // console.log("mounted:" + this.$el.id);
        }
    });
</script>

2. 模板語法

  Vue.js建立實例對象的選項中影響模板或DOM的選項:el 和 template。函數

    ◊ el :類型爲字符串,DOM 元素或函數。其做用是爲實例提供掛載元素。性能

    ◊ template:類型爲字符串。默認會將template 值替換掛載元素(即el 值對應的元素),併合並掛載元素和模板根節點的屬性。this

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>libing.vue</title>
    <script src="node_modules/vue/dist/vue.min.js"></script>
</head>

<body>
    <div id="app">
        <h1>將被模板內容替換</h1>
    </div>
    <template id="tpl">
        <div class="tpl">Todo List</div>
    </template>
    <script>
        var vm = new Vue({
            el: "#app",
            template: "#tpl"
        });
    </script>
</body>

</html>

  渲染輸出HTML:

<body>
    <div class="tpl">Todo List</div>
    <template id="tpl">
        <div class="tpl">Todo List</div>
    </template>
    <script>
        var vm = new Vue({
            el: "#app",
            template: "#tpl"
        });
    </script>
</body>

 

  Vue.js使用基於HTML的模版語法,容許聲明式地將DOM綁定至Vue實例的數據。

  Vue.js的核心:採用模板語法聲明式的將數據渲染到DOM。

2.1 插值(Interpolations)

2.1.1 文本(Text)

  Vue.js 實例中經過 data 屬性定義數據,這些數據能夠在實例對應的模板中進行綁定並使用。

  數據綁定:{{ }}

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>libing.vue</title>
  <script src="node_modules/vue/dist/vue.min.js"></script>
</head>

<body>
  <div id="app">
    <h1>{{ title }}</h1>
  </div>
  <script>
    var vm = new Vue({
      el: "#app",
      data: {
        title: "Todo List"
      }
    });
  </script>
</body>

</html>

2.1.2 原始HTML(Raw HTML)

  {{ }}:將數據中的 HTML 轉爲純文本後再進行插值。

  v-html :輸出 HTML 代碼

<div id="app">
    <div v-html="title"></div>
</div>
<script>
    var vm = new Vue({
        el: "#app",
        data: {
            title: "<h1>Todo List</h1>"
        }
    });
</script>

2.1.3 屬性(Attributes)

  不能在 Vue 模板中的 HTML 屬性上使用{{}}語法。

  HTML 屬性中的值應使用 v-bind 指令。

<div id="app">
  <div v-bind:title="title">Content</div>
</div>
<script>
  var vm = new Vue({
    el: "#app",
    data: {
      title: "Todo List"
    }
  });
</script>

2.1.4 表達式

<div id="app">
  {{ status ? "是" : "否" }}
  <div v-bind:title="status?'是':'否'">Content</div>
</div>
<script>
  var vm = new Vue({
    el: "#app",
    data: {
      status: true
    }
  });
</script>

2.2 過濾器(Filters)

2.2.1 註冊過濾器

  Vue.js 容許在表達式後添加可選的過濾器,以管道符 「|」 指示。

<div id="app">
    <h1>{{ title | uppercase }}</h1>
</div>
<script>
    var vm = new Vue({
        el: "#app",
        data: {
            title: "Todo List"
        },
        filters: {
            uppercase: function (value) {
                return value.toUpperCase();
            }
        }
    });
</script>

  多個過濾器鏈式使用:

{{ name | filterA | filterB }}

  傳入多個參數:

{{ name | filterA arg1 arg2}}

  此時,filterA 將 name 的值作爲第一個參數,arg1,arg2 作爲第2、第三個參數傳入過濾器函數中。

 

  Vue.js 提供全局方法Vue.filter() 註冊一個自定義過濾器,接受過濾器ID 和過濾器函數兩個參數。

  過濾器註冊語法格式:

Vue.filter( id, [definition] )

  示例:日期格式過濾器

  引入moment.js:

npm install -S moment
import Vue from 'vue'
import moment from 'moment'

Vue.filter('datefmt', function (input, fmtstring) {
  return moment(input).format(fmtstring);
});

new Vue({
  el: '#app',
  data: {
    now: new Date()
  }
})
{{ now | datefmt('YYYY-MM-DD HH:mm:ss') }}

2.3 指令(Directives)

  指令是帶有 v- 前綴的特殊屬性。

  指令用於在表達式的值改變時,將某些行爲應用到 DOM 上。

  v-bind指令:用於響應式地更新 HTML 屬性。

  v-on 指令:用於監聽 DOM 事件。

<div id="app">
    <h1 v-if="status">{{ title }}</h1>
</div>
<script>
    var vm = new Vue({
        el: "#app",
        data: {
            title: "Todo List",
            status: true
        }
    });
</script>

2.3.1 參數(Arguments)

  一些指令可以接受一個參數,參數在指令後以冒號(:)表示。

<div id="app">
    <a v-bind:href="url">libingql</a>
</div>
<script>
    var vm = new Vue({
        el: "#app",
        data: {
            url: "https://www.cnblogs.com/libingql"
        }
    });
</script>

2.3.2 修飾符(Modifiers)

  修飾符:以句號 . 表示的特殊後綴,用於指出一個指定應該以特殊方式綁定。

  示例:.prevent 修飾符告訴 v-on 指令對於觸發的事件調用 event.preventDefault()

<form v-on:submit.prevent="onSubmit"></form>

2.4 用戶輸入

  在 input 輸入框中使用 v-model 指令來實現雙向數據綁定。

<div id="app">
    <div>{{ title }}</div>
    <input type="text" v-model="title" />
</div>
<script>
    var vm = new Vue({
        el: "#app",
        data: {
            title: "Todo List"
        }
    });
</script>

2.5 簡寫(Shorthands)

  Vue.js 爲 v-bind 和 v-on 這兩個最經常使用的指令,提供特定簡寫。

2.5.1 v-bind 簡寫

<!-- 完整語法 -->
<a v-bind:href="url"> ... </a>

<!-- 簡寫 -->
<a :href="url"> ... </a>

2.5.2 v-on 簡寫

<!-- 完整語法 -->
<a v-on:click="doSomething"> ... </a>

<!-- 簡寫 -->
<a @click="doSomething"> ... </a>

3. 條件語句

3.1 v-if

  v-if指令:條件判斷

  在 <template> 上使用 v-if 進行條件分組

<div id="app">
    <h1 v-if="seen">Todo List</h1>
    <template v-if="ok">
        <ul>
            <li>Todo Item</li>
            <li>Todo Item</li>
            <li>Todo Item</li>
        </ul>
    </template>
</div>
<script>
    var vm = new Vue({
        el: "#app",
        data: {
            seen: true,
            ok: true
        }
    });
</script>

3.2 v-else

  v-if / v-else語句塊:

<div id="app">
    <h1 v-if="ok"></h1>
    <h1 v-else></h1>
</div>
<script>
    var vm = new Vue({
        el: "#app",
        data: {
            ok: true
        }
    });
</script>

3.3 v-if-else

  v-if-else:v-if 以後的「else-if 塊」,能夠屢次鏈式地調用。

<div id="app">
    <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>
    new Vue({
        el: '#app',
        data: {
            type: 'C'
        }
    });
</script>

3.4 v-show

  v-show:根據條件展現元素

  v-show 的元素會始終渲染並保留在 DOM 中。v-show 只會切換元素的 display 這個 CSS 屬性。

<div id="app">
    <h1 v-show="ok">Todo List</h1>
</div>
<script>
    var vm = new Vue({
        el: "#app",
        data: {
            ok: true
        }
    });
</script>

v-show 沒法用於 <template> 元素,也不能和 v-else 配合使用。

3.5 v-if 和 v-show

  v-if 是「真實」的條件渲染,由於它會確保條件塊(conditional block)在切換的過程當中,完整地銷燬(destroy)和從新建立(re-create)條件塊內的事件監聽器和子組件。

  v-if 是惰性的(lazy):若是在初始渲染時條件爲 false,它不會執行任何操做 - 在條件第一次變爲 true 時,纔開始渲染條件塊。

  v-show 無論初始條件如何,元素始終渲染,而且只是基於 CSS 的切換。

  一般來講,v-if 在切換時有更高的性能開銷,而 v-show 在初始渲染時有更高的性能開銷。

  若是須要頻繁切換,推薦使用 v-show,若是條件在運行時改變的可能性較少,推薦使用 v-if。

4. 循環語句

4.1 v-for遍歷數組

  v-for 遍歷數組格式: item in items

  其中,

    items 是原始數據數組(source data array),

    item 是數組中每一個迭代元素的指代別名(alias)。

<div id="app">
    <ul>
        <li v-for="item in items">{{ item.text }}</li>
    </ul>
</div>
<script>
    var vm = new Vue({
        el: "#app",
        data: {
            items: [{
                id: 1,
                text: "Vue"
            }, {
                id: 2,
                text: "Angular"
            }, {
                id: 3,
                text: "React"
            }]
        }
    });
</script>
<div id="app">
  <ul>
    <li v-for="item in list">{{ item.text }}</li>
  </ul>
</div>

new Vue({
  el: '#app',
  data: {
    list: [{
      id: 1,
      text: 'Vue'
    }, {
      id: 2,
      text: 'Angular'
    }, {
      id: 3,
      text: 'React'
    }]
  }
});

  v-for索引參數:

<li v-for="(item, index) in items">{{ index }}-{{ item.text }}</li>

  其中,index從0開始。

4.2 v-for遍歷對象

  v-for 能夠遍歷對象的屬性。

<div id="app">
    <ul>
        <li v-for="value in item">{{ value }}</li>
    </ul>
</div>
<script>
    var vm = new Vue({
        el: "#app",
        data: {
            item: {
                id: 1,
                text: "Vue"
            }
        }
    });
</script>

  v-for遍歷對象屬性:兩個參數key、value

<div id="app">
    <ul>
        <li v-for="(value, key) in item">{{ key }}:{{ value }}</li>
    </ul>
</div>
<script>
    var vm = new Vue({
        el: "#app",
        data: {
            item: {
                id: 1,
                text: "Vue"
            }
        }
    });
</script>

  v-for遍歷對象屬性:3個參數index、key、value,索引(index)從0開始。

<div id="app">
    <ul>
        <li v-for="(value, key, index) in item">{{ index }}-{{ key }}:{{ value }}</li>
    </ul>
</div>
<script>
    var vm = new Vue({
        el: "#app",
        data: {
            item: {
                id: 1,
                text: "Vue"
            }
        }
    });
</script>

4.3 key

  爲便於 Vue 跟蹤每一個節點的身份,從新複用(reuse)和從新排序(reorder)現有元素,須要爲每項提供惟一的 key 屬性,從而給 Vue 一個提示。

  理想的 key 值是每項都有惟一的 id。

  推薦:在使用 v-for 時,儘量提供一個 key,除非迭代的 DOM 內容足夠簡單,或者是故意依賴於默認行爲來得到性能提高。

<div id="app">
    <ul>
        <li v-for="item in items" v-bind:key="item.id">{{ item.text }}</li>
    </ul>
</div>
<script>
    var vm = new Vue({
        el: "#app",
        data: {
            items: [{
                id: 1,
                text: "Vue"
            }, {
                id: 2,
                text: "Angular"
            }, {
                id: 3,
                text: "React"
            }]
        }
    });
</script>

  簡寫:

<li v-for="item in items" :key="item.id">{{ item.text }}</li>

4.4 v-for遍歷整數

  v-for能夠在整數值範圍內迭代。

<div id="app">
    <ul>
        <li v-for="n in 10">{{ n }}</li>
    </ul>
</div>
<script>
    new Vue({
        el: '#app'
    });
</script>

4.5 計算(computed)屬性與監聽(watch)屬性

4.5.1 計算(computed)屬性

  在模板中使用表達式是很是方便直接的,只適用於簡單的操做,不適於加入過多的邏輯。

  對於複雜的邏輯,使用 computed 屬性(computed property)。

  計算屬性都以函數的形式,在Vue實例的computed選項中,最終返回計算後的結果。

<div id="app">
    {{ fullName }}
</div>
<script>
    new Vue({
        el: '#app',
        data: {
            firstName: "bing",
            lastName: "li"
        },
        computed: {
            fullName: function () {
                return this.lastName + ' ' + this.firstName;
            }
        }
    });
</script>

  計算屬性依賴一個或多個Vue實例的數據,只要其中任一數據變化,計算屬性就會從新執行,視圖(vm)也會更新。

<div id="app">
    <table>
        <tr>
            <th>商品ID</th>
            <th>商品名稱</th>
            <th>單價</th>
            <th>數量</th>
        </tr>
        <tr v-for="item in products">
            <td>{{ item.ID }}</td>
            <td>{{ item.ProductName }}</td>
            <td>{{ item.UnitPrice }}</td>
            <td>
                <input type="text" v-model="item.Quantity" />
            </td>
        </tr>
        <tr>
            <td colspan="4" style="text-align: right;">總計:{{ total }}</td>
        </tr>
    </table>
</div>
<script>
    var vm = new Vue({
        el: "#app",
        data: {
            products: [{
                ID: 1,
                ProductName: "手機",
                UnitPrice: 1000,
                Quantity: 2
            }, {
                ID: 2,
                ProductName: "電腦",
                UnitPrice: 5000,
                Quantity: 5
            }]
        },
        computed: {
            total: function () {
                var total = 0;
                for (var i = 0; i < this.products.length; i++) {
                    total += this.products[i].Quantity * this.products[i].UnitPrice;
                }

                return total;
            }
        }
    });
</script>

  computed 屬性默認只有 getter ,能夠在須要時提供一個 setter 。

<div id="app">
    {{ fullName }}
</div>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            firstName: "Bing",
            lastName: "Li"
        },
        computed: {
            fullName: {
                get: function () {
                    return this.lastName + ' ' + this.firstName;
                },
                set: function (value) {
                    var names = value.split(' ')
                    this.lastName = names[0]
                    this.firstName = names[names.length - 1]
                }
            }
        }
    });

    vm.fullName = "Li Bing2018";
</script>

4.5.2 computed 緩存 vs method 方法

  computed屬性會基於它所依賴的數據進行緩存。每一個 computed 屬性,只有在它所依賴的數據發生變化時,纔會從新取值(re-evaluate)。

<div id="app">
    {{ now }}
</div>
<script>
    new Vue({
        el: '#app',
        computed: {
            now: function () {
                return Date.now()
            }
        }
    });
</script>

  method方法:每當觸發從新渲染(re-render)時,method 調用方式將老是再次執行函數。

  在某些場景下,不但願有緩存,使用 method 方法替代。

<div id="app">
    {{ now() }}
</div>
<script>
    new Vue({
        el: '#app',
        methods: {
            now: function () {
                return Date.now()
            }
        }
    });
</script>

4.5.3 computed 屬性和 watch 屬性

  watch 屬性:Vue 提供的一種更加通用的方式,來觀察和響應 Vue 實例上的數據變化。

  過分濫用 watch 屬性會形成一些問題,更推薦的方式是,使用 computed 屬性。

<div id="app">
    <input type="text" v-model="firstName">
    <input type="text" v-model="lastName">
    <div>{{ fullName }}</div>
</div>
<script>
    new Vue({
        el: '#app',
        data: {
            firstName: 'Bing',
            lastName: 'Li',
            fullName: 'Li Bing'
        },
        computed: {
            firstName: function (val) {
                this.fullName = this.lastName + ' ' + val;
            },
            lastName: function (val) {
                this.fullName = val + ' ' + this.firstName;
            }
        }
    });
</script>
<script>
    new Vue({
        el: '#app',
        data: {
            firstName: 'Bing',
            lastName: 'Li',
            fullName: 'Li Bing'
        },
        watch: {
            firstName: function () {
                this.fullName = this.lastName + ' ' + this.firstName;
            },
            lastName: function () {
                this.fullName = this.lastName + ' ' + this.firstName;
            }
        }
    });
</script>

5. 樣式綁定:class和style

5.1 class綁定

5.1.1 對象語法

  向 v-bind:class 傳入一個對象,來動態地切換 class。

<div id="app">
    <div v-bind:class="{ active: isActive }"></div>
</div>
<script>
    new Vue({
        el: '#app',
        data: {
            isActive: true
        }
    });
</script>

  渲染:

<div class="active"></div>

  active 這個 class 的存在與否,取決於 isActive 這個 data 屬性的 truthy 值。

  v-bind:class 指令能夠和普通 class 屬性共存。能夠經過在對象中添加多個字段,來切換多個 class。

<div id="app">
    <div class="static" v-bind:class="{ active: isActive, 'text-danger': hasError }"></div>
</div>
<script>
    new Vue({
        el: '#app',
        data: {
            isActive: true,
            hasError: false
        }
    });
</script>

  渲染:

<div class="static active"></div>

  綁定對象,能夠無需內聯。

<div id="app">
    <div v-bind:class="className"></div>
</div>
<script>
    new Vue({
        el: '#app',
        data: {
            className: {
                active: true,
                'text-danger': true
            }
        }
    });
</script>

  渲染:

<div class="active text-danger"></div>

  綁定返回對象的計算屬性。

<div id="app">
    <div v-bind:class="className"></div>
</div>
<script>
    new Vue({
        el: '#app',
        data: {
            isActive: true,
            hasError: true
        },
        computed: {
            className: function () {
                return {
                    active: this.isActive,
                    'text-danger': this.hasError
                }
            }
        }
    });
</script>

5.1.2 數組語法

  能夠向 v-bind:class 傳入一個數組,來與 class 列表對應。

<div id="app">
    <div v-bind:class="[activeClass, errorClass]"></div>
</div>
<script>
    new Vue({
        el: '#app',
        data: {
            activeClass: 'active',
            errorClass: 'text-danger'
        }
    });
</script>

  三元表達式:

<div v-bind:class="[isActive ? activeClass : '', errorClass]"></div>

  數組語法中使用對象語法:

<div id="app">
    <div v-bind:class="[{ active: isActive }, errorClass]"></div>
</div>
<script>
    new Vue({
        el: '#app',
        data: {
            isActive: true,
            errorClass: 'text-danger'
        }
    });
</script>

5.2 style綁定

5.2.1 對象語法

  v-bind:style 直接設置樣式

<div id="app">
    <div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
</div>
<script>
    new Vue({
        el: '#app',
        data: {
            activeColor: 'red',
            fontSize: 30
        }
    });
</script>

  渲染:

<div style="color: red; font-size: 30px;"></div>

  綁定對象

<div id="app">
    <div v-bind:style="style"></div>
</div>
<script>
    new Vue({
        el: '#app',
        data: {
            style: {
                color: 'red',
                fontSize: '13px'
            }
        }
    });
</script>

  v-bind:style 的對象語法,能夠和 computed 屬性結合使用,此 computed 屬性所對應的 getter 函數須要返回一個對象。

5.2.2 數組語法

  v-bind:style 的數組語法,能夠在同一個元素上,使用多個 style 對象。

<div id="app">
    <div v-bind:style="[baseStyles, overridingStyles]"></div>
</div>
<script>
    new Vue({
        el: '#app',
        data: {
            baseStyles: {
                color: 'red',
                fontSize: '30px'
            },
            overridingStyles: {
                'font-weight': 'bold'
            }
        }
    });
</script>

  渲染:

<div style="color: red; font-size: 30px; font-weight: bold;"></div>

6. 事件處理

6.1 監聽事件

  v-on 指令:監聽 DOM 事件,並在事件被觸發時執行 JavaScript 代碼。

<div id="app">
    <button v-on:click="counter += 1">增長 1</button>
    <div>按鈕點擊次數:{{ counter }}次</div>
</div>
<script>
    new Vue({
        el: '#app',
        data: {
            counter: 0
        }
    });
</script>

6.2 定義在 methods 對象中的事件處理器

  用於處理邏輯復瑣事件

<div id="app">
    <button v-on:click="greet">greet</button>
</div>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            name: "Li Bing"
        },
        methods: {
            greet: function (event) {
                // `this` 在方法裏指當前 Vue 實例
                alert('Hello ' + this.name + '!')
                // `event` 是原生 DOM 事件
                if (event) {
                    alert(event.target.tagName)
                }
            }
        }
    });

    // 能夠用 JavaScript 直接調用方法
    vm.greet() // -> 'Hello Li Bing!'
</script>

6.3 定義在行內的事件處理器

<div id="app">
    <button v-on:click="greet('Li Bing')">greet</button>
</div>
<script>
    var vm = new Vue({
        el: '#app',
        methods: {
            greet: function (name) {
                alert('Hello ' + name + '!');
            }
        }
    });
</script>

6.4 事件修飾符(Event Modifiers)

  在事件處理程序中常見調用 event.preventDefault() 或 event.stopPropagation()

  v-on 提供事件修飾符,以點(.)開頭的指令後綴來表示。

    ◊ .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>

<!-- 只有在 event.target 是元素自身時,才觸發處理函數。 -->
<!-- 也就是說,event.target 是子元素時,不觸發處理函數 -->
<div v-on:click.self="doThat">...</div>

  v-on:click.prevent.self 阻止全部點擊

  v-on:click.self.prevent 只阻止元素自身的點擊

相關文章
相關標籤/搜索