vue grammer one

WhaleFall541發表於2022-01-03

本文所有內容均來自 書籍《vue.js實戰》

完整程式碼請檢視github

v-model

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>Hello world</title>
</head>
<body>
	<div id="app">
		<input type="text" v-model="name" placeholder="your name">
		<h1>Hello,{{ name }}</h1>
	</div>
	<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
	<script>
		var app = new Vue({
		<!-- #app為某個元素的id -->
			el:'#app',
			data: {
				name: ''
			}
		})
	</script>
</body>
</html>

為縮減篇幅,本文後面所有程式碼 都只給出body標籤內的內容

v-html 、v-pre

<div id="app">
    <span v-html="link"></span>
</div>
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<script>
    var app = new Vue({
        el:'#app',
        data: {
            link: '<a href="#">這是一個連結</a>'
        }
    })
</script>
<div id="app">
    <span v-pre>{{只為顯示雙大括號}}</span>
</div>
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<script>
    var app = new Vue({
        el:'#app',
        data: ''
    })
</script>

三元運算子,四則運算

<div id="app">
    <!-- Vue .js 只支援單個表示式,不支援語句和流控制 -->
    {{ number / 10 }}
    {{ isOK ? 'Y' : 'N' }}
    {{ text.split(',').reverse().join(',') }}
</div>
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<script>
    var app = new Vue({
        el:'#app',
        data: {
            number: 100,
            isOK: false,
            text: '123,456'
        }
    })
</script>

過濾器

<div id="app">
    {{ date | formatDate}}<!-- 使用過濾器格式化時間 -->
</div>
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<script>
    var padDate = function(value) {
        return value < 10 ? '0' + value : value 
    };
    var app = new Vue({
        el:'#app',
        data: {
            date : new Date()
        },
        filters: {
            formatDate: function(value) {
                var date = new Date(value);
                var year = date.getFullYear();
                var month = padDate(date.getMonth()+1);
                var day = padDate(date.getDate());
                var hours = padDate(date.getHours());
                var minutes = padDate(date.getMinutes());
                var seconds = padDate(date.getSeconds());
                return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds
            }
        },
        mounted: function() {
            var _this = this;// 宣告一個變數指向Vue例項this,保證作用域一致
            this.timer = setInterval(function() {
                _this.date = new Date(); // 修改資料
            }, 1000);
        },
        beforeDestroy: function() {
            if(this.timer) {
                clearInterval(this.timer);
            }
        }
    })
</script>

過濾器應當用於處理簡單的文字轉換,如果要實現更為複雜的資料變換,應該使用計算屬性

v-bind

<div id="app">
    <a v-bind:href="url">連結</a>
    <img v-bind:src="imgUrl">
</div>
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<script>
    var app = new Vue({
        el:'#app',
        data: {
            url : 'https://www.github.com',
            imgUrl : 'https://gitee.com/jack541/repo-for-pic-go/raw/master/img/image-20220102162032176.png'
        }
    })	
</script>

以下兩句等效:

<a v-bind:href="url">連結</a>

<a :href="url">連結</a>

v-on

<div id="app">
    <p v-if="show">這是一段文字</p>
    <button v-on:click="handleClose">點選隱藏</button>
</div>
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<script>
    var app = new Vue({
        el:'#app',
        data: {
            show : true
        },
        methods: {
            handleClose: function(){
                if (this.show == true)
                    this.show = false;
                else 
                    this.show = true;
            }
        }
    })	
</script>

以下兩句等效:

<button v-on:click="handleClose">點選隱藏</button>

<button @click="handleClose">點選隱藏</button>

computed屬性用法

<div id="app">
    {{ reversedText }}
</div>
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<script>
    var app = new Vue({
        el:'#app',
        data: {
            text: '123,456'
        },
        computed: {
            reversedText: function() {
                return this.text.split(',').reverse().join(',');
            }
        }
    })	
</script>
<div id="app">
    總價:{{ prices }}
</div>
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<script>
    var app = new Vue({
        el:'#app',
        data: {
            package1: [
                {
                    name: 'iPhone 13 128G',
                    price: 5999,
                    count: 3
                },{
                    name: 'iPad mini6',
                    price: 3799,
                    count: 5
                }
            ],
            package2: [
                {
                    name: 'iPhone 13 pro 256G',
                    price: 8999,
                    count: 3
                },{
                    name: 'Mac Pro intel i9 1TB SDD 32G RAM',
                    price: 21999,
                    count: 1
                }
            ]
        },
        computed: {
            prices : function() {
                var prices = 0;
                for (var i = 0; i < this.package1.length; i++) {
                    prices += this.package1[i].price * this.package1[i].count;
                }
                for (var i = 0; i < this.package2.length; i++) {
                    prices += this.package2[i].price * this.package2[i].count;
                }
                return prices;
            }
        }
    })	
</script>

setter getter

<div id="app">
    姓名:{{ fullName }}
</div>
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<script>
    var app = new Vue({
        el:'#app',
        data: {
            firstName: 'jack',
            lastName: 'green'
        },
        computed: {
            fullName: {
                //getter 用於讀取
                get: function () {
                    return this.firstName + ' ' + this.lastName;
                },
                // setter 寫入時出發
                set: function (newValue) {
                    var names = newValue.split(' ');
                    this.firstName = names[0];
                    this.lastName = names[names.length - 1];
                } 
            }
        }
    })	
</script>

計算快取

計算屬性是基於它的依賴快取的。 一個計算屬性所依賴的資料發生變化時,它才會重新取值。

<div id="app">
    <!-- 注意,這裡的 reversedText是方法,所以要帶()-->
    {{ reversedText() }}
</div>
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<script>
    var app = new Vue({
        el:'#app',
        data: {
            text: '123,456'
        },
        methods: {
            reversedText: function() {
                return this.text.split(',').reverse().join(',');
            }
        }
    })	
</script>

使用 v-bind切換class屬性

<div id="app">
    <div :class="{ 'active': isActive, 'error': isError }"></div>
</div>
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<script>
    var app = new Vue({
        el:'#app',
        data: {
            isActive: true,
            isError: false
        }
    })	
</script>

:class 的表示式過長或邏輯複雜時,還可以繫結一個計算屬性,這是一種很友好和常見的用法,一般當條件多於兩個時,都可以使用data 或computed。

<div id="app">
    AA<div :class="classes"></div>
</div>
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<script>
    var app = new Vue({
        el:'#app',
        data: {
            isActive: true,
            error: null
        },
        computed: {
            classes: function() {
                return {
                    active: this.isActive && !this.error,
                    'text-fail': this.error && this.error.type === 'fail'
                }
            }
        }
    })	
</script>

陣列語法

  • data 定義
<div id="app">
    <div :class="[{ 'active' : isActive }, errorCls]"></div>
</div>
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<script>
    var app = new Vue({
        el:'#app',
        data: {
            isActive: true,
            errorCls: 'error'
        },
    })	
</script>
  • computed定義
<div id="app">
    <button :class="classes"></button>
</div>
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<script>
    var app = new Vue({
        el:'#app',
        data: {
            size: 'large',
            disabled: true
        },
        computed: {
            classes: function() {
                return [
                    'btn',
                    {
                    // 定義btn大小,不為空的時候就為size的尺寸
                        ['btn-' + this.size]: this.size != '',
                    // 定義button是否可用
                        ['btn-disabled']: this.disabled
                    }
                ]
            }
        }
    })	
</script>

NOTES: 使用計算屬性給元素動態設定類名,在業務中經常用到,尤其是在寫複用的元件時,所以在開發過程中,如果表示式較長或邏輯複雜,應該儘可能地優先使用計算屬性。

繫結style

<div id="app">
    <div :style="styles">文字</div>
    <!-- 應對多個物件時可以使用陣列語法 styleA相當於一個data中的styles元素 -->
    <!-- <div :style="[styleA, styleB] " >文字</d iv> -->
</div>
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<script>
    var app = new Vue({
        el:'#app',
        data: {
            styles :{
                color: 'red',
                fontSize: 14+'px'
            }
        }
    })	
</script>

在實際業務中,: style 的陣列語法並不常用,因為往往可以寫在一個物件裡面;而較為常用的應當是計算屬性。

v-cloak

<div id="app" v-cloak>
    {{ message }}
</div>
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<script>
    var app = new Vue({
        el:'#app',
        data: {
            message: '頁面正在載入中……'
        }
    });

</script>

v-once

作用是定義它的元素或元件只渲染一次,包括元素或元件的所有子節點。

<div id="app">
    <span v-once> {{ message }}</span>
    <div v-once>
        <span> {{ message }} </span>
    </div>
</div>
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<script>
    var app = new Vue({
        el:'#app',
        data: {
            message: '這是一段文字'
        }
    })
</script>

v-if v-else-if v-else

<div id="app">
    <p v-if="status === 1"> 當status為1時顯示該行</p>
    <p v-else-if="status === 2"> 當status為2時顯示該行</p>
    <p v-else>否則顯示該行</p>
</div>
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<script>
    var app = new Vue({
        el:'#app',
        data: {
            status: 1
        }
    })
</script>

v-else-if 要緊跟v-if, v-else 要緊跟v-else-if 或v-if, 表示式的值為真時,當前元素/元件及所
有子節點將被渲染,為假時被移除

template 複用元素

<div id="app">
    <template v-if="type === 'name'">
        <label>使用者名稱:</label>
        <input placeholder="輸入使用者名稱">
    </template>
    <template v-else>
        <label>郵箱:</label>
        <input placeholder="輸入郵箱">
    </template> 
    <button @click="handleToggleClick">切換輸入型別</button>
</div>
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<script>
    var app = new Vue({
        el:'#app',
        data: {
            type: 'name'
        },
        methods: {
            handleToggleClick: function () {
                this.type = this.type === 'name' ? 'mail' : 'name';
            }
        }
    })
</script>

如果不希望複用input框,可以使用Vue.js 提供的key 屬性,它可以讓你自己決定是否要複用元
素, key 的值必須是唯一的。

<template v-if="type === 'name'">
    <label>使用者名稱:</label>
    <input placeholder="輸入使用者名稱" key="name-input">
</template>
<template v-else>
    <label>郵箱:</label>
    <input placeholder="輸入郵箱" key="mail-input">
</template>

v-show

<div id="app">
    <p v-show="status === 1">當status為1時顯示該行</p>
</div>
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<script>
    var app = new Vue({
        el:'#app',
        data: {
            status: 2
        }
    })
</script>

v-show 不能在<template>上使用。

若表示式v-if初始值為false, 則一開始元素/元件並不會渲染,只有當條件第一次變為真時才開始編譯。而v-show 只是簡單的CSS屬性切換,無論條件真與否,都會被編譯。相比之下, v-if 更適合條件不經常改變的場景,因為它切換開銷相對較大, 而v-show 適用千頻繁切換條件。

v-for

<div id="app">
    <ul>
        <li v-for="book in books">{{ book.name }}</li>
        <!-- <li v-for="book of books">{{ book.name }}</li> -->
    </ul>
</div>
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            books: [
                {name : '《Vue.js實戰》'},
                {name : '《JavaScript 語言精粹》'},
                {name : '《JavaScript 高階程式設計》'}
            ]
        }
    })
</script>

參考文獻:書籍《vue.js實戰》

轉載請註明 原文地址

相關文章