下面我将详细讲解Vue.js中过滤器的语法和使用注意事项,并提供一个完整的演示页面。
在Vue.js中,过滤器(Filters) 是用于文本格式化的功能,可以在双花括号插值和v-bind
表达式中使用。过滤器通过管道符(|)指示,主要用于简单的文本转换。
{{ message | capitalize }}
{{ message | filterA | filterB }}
{{ date | formatDate('YYYY-MM-DD') }}
Vue.filter('filterName', function(value, ...args) {
// 处理逻辑
return transformedValue;
});
new Vue({
filters: {
filterName(value, ...args) {
// 处理逻辑
return transformedValue;
}
}
});
<p>{{ price | currency }}p>
<div v-bind:id="rawId | formatId">div>
<p>{{ text | trim | capitalize }}p>
<p>{{ now | dateFormat('YYYY年MM月DD日') }}p>
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/[email protected]/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) }}
过滤器特点:
Vue 3的变更:
{{ formatCurrency(price) }}
最佳实践:
这个演示页面展示了Vue 2中过滤器的各种用法,同时提供了Vue 3的迁移建议,帮助开发者更好地理解和应用过滤器功能。