1. Vue 模板中的 JavaScript 表达式基础
Vue 模板支持在插值 ({{ }}) 和指令 (如 v-bind) 中使用 JavaScript 表达式,但必须是单个表达式,不能是语句或多行代码。
可用表达式示例:
<!-- 基本运算 -->
{{ number + 1 }}
<!-- 三元表达式 -->
{{ isActive ? 'active' : 'inactive' }}
<!-- 方法调用 -->
{{ message.toUpperCase() }}
<!-- 数组操作 -->
{{ list.join(', ') }}
<!-- 对象属性访问 -->
{{ user.name }}
<!-- 复杂表达式 -->
{{ new Date().toLocaleDateString() }}
不可用示例:
<!-- 语句 (报错) -->
{{ let a = 1 }}
{{ if (true) { return 'yes' } }}
<!-- 多行表达式 (报错) -->
{{
const name = 'Vue';
name.toUpperCase()
}}
<!-- 访问未在白名单中的全局变量 (报错) -->
{{ window.location.href }}
2. 表达式与语句的区别
表达式:会产生一个值的代码片段
a + bfunc()x ? y : z
语句:执行操作但不直接产生值
if (...) {...}for (...) {...}let a = 1
Vue 模板中只允许表达式,不允许语句。
3. 可用的全局对象白名单
Vue 模板表达式运行在沙箱环境中,默认可以访问以下全局对象:
InfinityundefinedNaNisFiniteisNaNparseFloatparseIntdecodeURIdecodeURIComponentencodeURIencodeURIComponentMathNumberDateArrayObjectBooleanStringRegExpMapSetJSONIntl
4. 实用示例与替代方案
需要访问全局变量
解决方案:在组件的 data 或 methods 中暴露需要的值
// 推荐写法:在组件的 `data` 或 `methods` 中暴露需要的值
data() {
return {
currentUrl: window.location.href
}
}
// 不推荐写法:在模板中格式化日期
{{ new Date(timestamp).toLocaleDateString() }}
// 推荐写法:使用过滤器 (Vue 2) 或方法/计算属性 (Vue 3)
methods: {
formatDate(timestamp) {
return new Date(timestamp).toLocaleDateString()
}
}
需要复杂逻辑
解决方案:使用计算属性或方法
<!-- 不好的实践:复杂表达式 -->
<div :class="'btn-' + (isActive ? (hasError ? 'danger' : 'success') : 'default') + ' ' + size">
<!-- 好的实践:简化表达式 -->
<div :class="buttonClasses">
computed: {
buttonClasses() {
let cls = 'btn-'
if (this.isActive) {
cls += this.hasError ? 'danger' : 'success'
} else {
cls += 'default'
}
return `${cls} ${this.size}`
}
}
//不推荐:复杂表达式
{{ message.split('').reverse().join('') }}
//推荐写法:使用过滤器 (Vue 2) 或方法/计算属性 (Vue 3)
computed: {
reversedMessage() {
return this.message.split('').reverse().join('')
}
}
需要条件判断
解决方案:使用三元表达式或 v-if/v-show
<!-- 简单条件 -->
{{ isAdmin ? 'Admin' : 'User' }}
<!-- 复杂条件:推荐写法 -->
<template v-if="role === 'admin'">
Admin Panel
</template>
<template v-else-if="role === 'editor'">
Editor Panel
</template>
5. 总结
Vue 模板中的 JavaScript 表达式提供了强大的数据绑定能力,但需要遵循以下规则:
- 必须是单个表达式,不能是语句
- 只能访问有限的全局对象白名单
- 应该避免副作用和复杂逻辑
- 对于复杂场景,优先使用计算属性和方法
通过合理使用表达式和计算属性,可以保持模板的简洁性和可维护性,同时实现强大的动态功能。