Vue.js 過濾器詳解
下面我將詳細講解Vue.js中過濾器的語法和使用注意事項,并提供一個完整的演示頁面。
過濾器基本概念
在Vue.js中,過濾器(Filters) 是用于文本格式化的功能,可以在雙花括號插值和v-bind
表達式中使用。過濾器通過管道符(|)指示,主要用于簡單的文本轉換。
<!-- 基本語法 -->
{{ message | capitalize }}<!-- 鏈式調用 -->
{{ message | filterA | filterB }}<!-- 帶參數的過濾器 -->
{{ date | formatDate('YYYY-MM-DD') }}
過濾器語法詳解
1. 全局過濾器定義
Vue.filter('filterName', function(value, ...args) {// 處理邏輯return transformedValue;
});
2. 局部過濾器定義
new Vue({filters: {filterName(value, ...args) {// 處理邏輯return transformedValue;}}
});
3. 使用方式
<!-- 在插值中使用 -->
<p>{{ price | currency }}</p><!-- 在v-bind中使用 -->
<div v-bind:id="rawId | formatId"></div><!-- 鏈式調用 -->
<p>{{ text | trim | capitalize }}</p><!-- 帶參數 -->
<p>{{ now | dateFormat('YYYY年MM月DD日') }}</p>
過濾器注意事項
- 過濾器只用于文本轉換:適用于簡單的文本格式化,不應用于復雜的數據轉換
- 參數傳遞:
- 第一個參數始終是管道前的值
- 后續參數是調用時傳入的參數
- 鏈式調用順序:從左到右執行,前一個過濾器的結果作為后一個過濾器的輸入
- 返回值:過濾器必須返回一個值
- Vue 3的變化:Vue 3中移除了過濾器,官方推薦使用方法或計算屬性替代
- 性能考慮:避免在過濾器中執行復雜操作,特別是大數據量時
- 作用域:過濾器函數內無法訪問組件實例(this為undefined)
完整演示示例
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Vue.js 過濾器詳解</title><script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script><style>* {box-sizing: border-box;margin: 0;padding: 0;font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;}body {background: linear-gradient(135deg, #6a11cb 0%, #2575fc 100%);min-height: 100vh;padding: 20px;color: #333;}.container {max-width: 1000px;margin: 40px auto;background: rgba(255, 255, 255, 0.95);border-radius: 15px;box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);overflow: hidden;}header {background: linear-gradient(90deg, #3498db, #2c3e50);color: white;padding: 30px 40px;text-align: center;}h1 {font-size: 2.5rem;margin-bottom: 10px;text-shadow: 2px 2px 4px rgba(0,0,0,0.3);}.subtitle {font-size: 1.2rem;opacity: 0.9;max-width: 700px;margin: 0 auto;}.content {display: flex;flex-wrap: wrap;padding: 30px;}.panel {flex: 1;min-width: 300px;padding: 25px;margin: 15px;background: white;border-radius: 10px;box-shadow: 0 5px 15px rgba(0, 0, 0, 0.08);transition: transform 0.3s ease;}.panel:hover {transform: translateY(-5px);}.panel h2 {color: #2c3e50;border-bottom: 2px solid #3498db;padding-bottom: 10px;margin-bottom: 20px;display: flex;align-items: center;}.panel h2 i {margin-right: 10px;color: #3498db;}.example {background: #f8f9fa;border-radius: 8px;padding: 20px;margin: 15px 0;border-left: 4px solid #3498db;}.input-group {margin-bottom: 20px;}label {display: block;margin-bottom: 8px;font-weight: 600;color: #2c3e50;}input, select, textarea {width: 100%;padding: 12px 15px;border: 1px solid #ddd;border-radius: 6px;font-size: 16px;transition: border 0.3s;}input:focus, select:focus, textarea:focus {outline: none;border-color: #3498db;box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.2);}.result {background: #e3f2fd;padding: 15px;border-radius: 8px;margin-top: 15px;min-height: 50px;font-size: 18px;font-weight: 500;color: #0d47a1;}.note {background: #fff8e1;border-left: 4px solid #ffc107;padding: 15px;margin-top: 20px;border-radius: 0 8px 8px 0;}.note h3 {color: #ff9800;margin-bottom: 10px;}.code {background: #2c3e50;color: #ecf0f1;padding: 20px;border-radius: 8px;font-family: 'Courier New', monospace;margin: 15px 0;overflow-x: auto;}.footer {text-align: center;padding: 20px;background: #f8f9fa;color: #6c757d;font-size: 0.9rem;border-top: 1px solid #eee;}.filters-list {display: grid;grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));gap: 15px;margin-top: 20px;}.filter-item {background: #e3f2fd;padding: 15px;border-radius: 8px;border-left: 4px solid #2196f3;}.filter-item h4 {margin-bottom: 8px;color: #0d47a1;}@media (max-width: 768px) {.content {flex-direction: column;}.panel {min-width: 100%;margin: 10px 0;}}</style>
</head>
<body><div id="app"><div class="container"><header><h1>Vue.js 過濾器詳解</h1><p class="subtitle">過濾器用于文本格式化,在Vue 2中通過管道符(|)使用。Vue 3中已移除,建議使用計算屬性或方法替代。</p></header><div class="content"><div class="panel"><h2><i class="fas fa-filter"></i> 過濾器演示</h2><div class="input-group"><label for="textInput">輸入文本:</label><input type="text" id="textInput" v-model="inputText" placeholder="輸入文本進行格式化"></div><div class="input-group"><label for="numberInput">輸入數值:</label><input type="number" id="numberInput" v-model.number="inputNumber" placeholder="輸入數值進行格式化"></div><div class="filters-list"><div class="filter-item"><h4>大寫轉換</h4><div class="result">{{ inputText | uppercase }}</div></div><div class="filter-item"><h4>首字母大寫</h4><div class="result">{{ inputText | capitalize }}</div></div><div class="filter-item"><h4>貨幣格式化</h4><div class="result">{{ inputNumber | currency }}</div></div><div class="filter-item"><h4>百分比</h4><div class="result">{{ inputNumber | percent }}</div></div><div class="filter-item"><h4>反轉文本</h4><div class="result">{{ inputText | reverse }}</div></div><div class="filter-item"><h4>截斷文本</h4><div class="result">{{ inputText | truncate(20) }}</div></div><div class="filter-item"><h4>日期格式化</h4><div class="result">{{ currentDate | dateFormat('YYYY年MM月DD日') }}</div></div><div class="filter-item"><h4>鏈式調用</h4><div class="result">{{ inputText | uppercase | truncate(15) }}</div></div></div></div><div class="panel"><h2><i class="fas fa-code"></i> 過濾器定義</h2><div class="example"><h3>全局過濾器</h3><div class="code">
// 大寫轉換過濾器
Vue.filter('uppercase', function(value) {if (!value) return '';return value.toString().toUpperCase();
});// 貨幣格式化過濾器
Vue.filter('currency', function(value) {if (value === null || value === undefined) return '';return '¥' + value.toFixed(2);
});</div></div><div class="example"><h3>局部過濾器</h3><div class="code">
new Vue({filters: {// 首字母大寫capitalize: function(value) {if (!value) return '';value = value.toString();return value.charAt(0).toUpperCase() + value.slice(1);},// 帶參數的截斷過濾器truncate: function(value, length) {if (!value) return '';if (value.length <= length) return value;return value.substring(0, length) + '...';}}
});</div></div><div class="example"><h3>帶參數的過濾器</h3><div class="code">
// 日期格式化過濾器
Vue.filter('dateFormat', function(value, format) {if (!value) return '';const date = new Date(value);const year = date.getFullYear();const month = (date.getMonth() + 1).toString().padStart(2, '0');const day = date.getDate().toString().padStart(2, '0');return format.replace('YYYY', year).replace('MM', month).replace('DD', day);
});</div></div><div class="note"><h3><i class="fas fa-exclamation-triangle"></i> 重要注意事項</h3><ul><li>過濾器只用于文本格式化,不改變原始數據</li><li>過濾器函數應保持純凈,不產生副作用</li><li>過濾器不能訪問組件實例(this為undefined)</li><li>Vue 3中已移除過濾器功能,建議使用方法或計算屬性替代</li><li>復雜邏輯應使用計算屬性而非過濾器</li><li>過濾器可以鏈式調用,順序從左到右</li><li>第一個參數始終是管道符前的值</li></ul></div></div></div><div class="footer"><p>Vue.js 過濾器演示 | 在實際項目中考慮Vue版本兼容性</p></div></div></div><script>// 全局過濾器定義Vue.filter('uppercase', function(value) {if (!value) return '';return value.toString().toUpperCase();});Vue.filter('reverse', function(value) {if (!value) return '';return value.toString().split('').reverse().join('');});Vue.filter('currency', function(value) {if (value === null || value === undefined) return '';return '¥' + value.toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,');});Vue.filter('percent', function(value) {if (value === null || value === undefined) return '';return (value * 100).toFixed(2) + '%';});Vue.filter('dateFormat', function(value, format) {if (!value) return '';const date = new Date(value);const year = date.getFullYear();const month = (date.getMonth() + 1).toString().padStart(2, '0');const day = date.getDate().toString().padStart(2, '0');return format.replace('YYYY', year).replace('MM', month).replace('DD', day);});new Vue({el: '#app',data: {inputText: 'Vue過濾器使用示例',inputNumber: 1234.567,currentDate: new Date()},filters: {// 局部過濾器:首字母大寫capitalize: function(value) {if (!value) return '';value = value.toString();return value.charAt(0).toUpperCase() + value.slice(1);},// 局部過濾器:截斷文本truncate: function(value, length) {if (!value) return '';if (value.length <= length) return value;return value.substring(0, length) + '...';}}});</script><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
</body>
</html>
關鍵知識點總結
-
過濾器定義:
- 全局過濾器使用
Vue.filter()
定義 - 局部過濾器在組件選項的
filters
屬性中定義
- 全局過濾器使用
-
過濾器使用:
- 通過管道符
|
使用 - 可以鏈式調用:
{{ value | filterA | filterB }}
- 可以傳遞參數:
{{ value | filter(arg1, arg2) }}
- 通過管道符
-
過濾器特點:
- 第一個參數是管道符前的值
- 必須返回一個值
- 不改變原始數據,只做格式化展示
- 不能訪問組件實例(this為undefined)
-
Vue 3的變更:
- Vue 3中已移除過濾器
- 替代方案:使用計算屬性或方法
- 示例:
{{ formatCurrency(price) }}
-
最佳實踐:
- 用于簡單文本格式化
- 復雜邏輯使用計算屬性
- 保持過濾器函數純凈(無副作用)
- 考慮向后兼容性(Vue 3遷移)
這個演示頁面展示了Vue 2中過濾器的各種用法,同時提供了Vue 3的遷移建議,幫助開發者更好地理解和應用過濾器功能。