一. vue模版表达式全局对象白名单
Vue 模板表达式中可用的 JavaScript 全局对象和方法列表
1. Array 对象(完整方法集)
// 基础操作
{{ [1,2,3].concat([4,5]) }} // [1,2,3,4,5]
{{ [1,2,3].join('-') }} // "1-2-3"
{{ [1,2,3].slice(1) }} // [2,3]
{{ [3,1,2].sort() }} // [1,2,3]
{{ [1,2,3].reverse() }} // [3,2,1]
// ES6+ 方法
{{ [1,2,3].includes(2) }} // true
{{ [1,2,3].find(x => x > 1) }} // 2
{{ [1,2,3].findIndex(x => x > 1) }} // 1
{{ [1,2,3].indexOf(2) }} // 1
// 迭代方法
{{ [1,2,3].map(x => x * 2) }} // [2,4,6]
{{ [1,2,3].filter(x => x > 1) }} // [2,3]
{{ [1,2,3].reduce((a,b) => a + b) }} // 6
{{ [1,2,3].every(x => x < 5) }} // true
{{ [1,2,3].some(x => x > 2) }} // true
// 类型转换
{{ Array.from('foo') }} // ['f','o','o']
{{ Array.of(1,2,3) }} // [1,2,3]
2. String 对象(完整方法集)
// 基础操作
{{ 'hello'.toUpperCase() }} // "HELLO"
{{ 'HELLO'.toLowerCase() }} // "hello"
{{ ' text '.trim() }} // "text"
{{ ' text '.trimStart() }} // "text "
{{ ' text '.trimEnd() }} // " text"
// 子字符串操作
{{ 'hello'.substring(1,3) }} // "el"
{{ 'hello'.substr(1,3) }} // "ell" (已废弃,建议用 substring)
{{ 'hello'.slice(1,3) }} // "el"
{{ 'hello'.charAt(1) }} // "e"
{{ 'hello'[1] }} // "e" (现代写法)
// 搜索与匹配
{{ 'hello'.includes('ell') }} // true
{{ 'hello'.startsWith('he') }} // true
{{ 'hello'.endsWith('lo') }} // true
{{ 'hello'.indexOf('l') }} // 2
{{ 'hello'.lastIndexOf('l') }} // 3
{{ 'hello'.match(/l/g) }} // ["l","l"]
// 分割与替换
{{ 'a,b,c'.split(',') }} // ["a","b","c"]
{{ 'hello'.replace('l','x') }} // "hexlo"
{{ 'hello'.replaceAll('l','x') }} // "hexxo"
// 填充与重复
{{ 'hi'.padStart(5,'!') }} // "!!!hi"
{{ 'hi'.padEnd(5,'!') }} // "hi!!!"
{{ 'hi'.repeat(3) }} // "hihihi"
// Unicode 操作
{{ '𠮷'.codePointAt(0) }} // 134071 (ES6)
{{ String.fromCodePoint(9731) }} // "☃"
3. 补充其他重要全局对象方法
Object 增强方法
// 属性操作
{{ Object.getOwnPropertyNames({a:1}) }} // ["a"]
{{ Object.hasOwn({a:1}, 'a') }} // true (ES2022)
// 合并与复制
{{ Object.assign({a:1},{b:2}) }} // {a:1,b:2}
{{ structuredClone({a:1}) }} // 深拷贝 (ES2022)
Number 新增方法
{{ Number.isNaN(NaN) }} // true (比全局 isNaN 更安全)
{{ Number.isSafeInteger(9007199254740991) }} // true
{{ 123.456.toFixed(2) }} // "123.46"
Math 新增方法
{{ Math.trunc(3.14) }} // 3 (去小数)
{{ Math.sign(-5) }} // -1
{{ Math.cbrt(8) }} // 2 (立方根)
{{ Math.hypot(3,4) }} // 5 (勾股定理)
Date 增强方法
{{ new Date().toLocaleString('zh-CN') }} // "2023/7/15 14:30:00"
{{ Date.now() }} // 时间戳 (毫秒)
4. 现代集合类型
Map/Set 完整 API
// Map
{{ [...new Map([['key','value']]).entries()] }} // [["key","value"]]
{{ new Map().set('a',1).get('a') }} // 1
// Set
{{ new Set([1,1,2]).size }} // 2
{{ [...new Set([1,2,2])] }} // [1,2]
TypedArray 系列
{{ new Uint8Array([1,2,3]).join(',') }} // "1,2,3"
5. 国际化的 Intl 对象
// 日期格式化
{{ new Intl.DateTimeFormat('zh-CN', { dateStyle: 'full' }).format(new Date()) }}
// 输出示例: "2023年7月15日星期六"
// 数字格式化
{{ new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(1234.5) }}
// 输出示例: "1.234,50 €"
// 列表格式化
{{ new Intl.ListFormat('zh-CN').format(['苹果', '香蕉']) }}
// 输出: "苹果和香蕉"
最佳实践建议
-
复杂逻辑处理:
// 不推荐在模板中直接操作 {{ arr.filter(x => x > 1).map(x => x * 2) }} // 推荐使用计算属性 computed: { processedData() { return this.arr.filter(x => x > 1).map(x => x * 2) } } -
性能敏感操作:
// 避免在模板中频繁创建新对象 {{ new Intl.DateTimeFormat('zh-CN').format(date) }} // 推荐预先格式化 data() { return { formattedDate: new Intl.DateTimeFormat('zh-CN').format(new Date()) } } -
类型安全:
// 使用 Number 的安全检查方法 {{ Number.isInteger(value) }} // 优于 {{ value % 1 === 0 }}
所有示例均基于最新的 ECMAScript 2023 标准,在 Vue 3 的模板中可直接使用。对于旧版浏览器不支持的现代方法(如 replaceAll),建议通过 Babel 或 polyfill 提供支持。
二. vue模版表达式全局对象黑名单
在 Vue 模板表达式中,不可用的方法主要包括以下几类(按技术栈分类,基于 Vue 3 最新规范):
1. 会修改原数据的数组方法(变异方法)
// ❌ 禁止在模板中直接使用(会触发警告且可能导致渲染问题)
{{ arr.push(1) }} // 修改原数组
{{ arr.pop() }} // 修改原数组
{{ arr.shift() }} // 修改原数组
{{ arr.unshift(1) }} // 修改原数组
{{ arr.splice(0,1) }} // 修改原数组
{{ arr.sort() }} // 原地排序
{{ arr.reverse() }} // 原地反转
{{ arr.fill(0) }} // 原地填充
{{ arr.copyWithin() }} // 原地操作
2. 会产生副作用的操作
// ❌ 禁止在模板中使用(违反纯函数原则)
{{ alert('test') }} // 浏览器弹窗
{{ console.log('test') }} // 控制台输出
{{ window.open() }} // 新窗口
{{ document.write() }} // DOM 写入
{{ fetch('/api') }} // 网络请求
{{ new Promise() }} // 异步操作
{{ setTimeout() }} // 定时器
{{ setInterval() }} // 循环定时器
{{ localStorage.setItem() }} // 存储操作
{{ sessionStorage.clear() }} // 存储操作
{{ crypto.getRandomValues() }} // 加密操作
3. 受限的全局对象访问
// ❌ 以下全局对象默认不可访问(需通过 app.config.globalProperties 手动注入)
{{ window.location.reload() }} // 浏览器对象
{{ document.getElementById() }} // DOM 操作
{{ process.env }} // Node.js 环境变量
{{ require('module') }} // CommonJS 导入
{{ __dirname }} // Node.js 路径
{{ XMLHttpRequest }} // 直接 AJAX 对象
4. 其他禁止操作
// ❌ 危险或无效操作
{{ delete obj.property }} // delete 操作符
{{ (() => { throw Error() })() }} // 抛出异常
{{ new Function('return 1')() }} // 动态执行
{{ eval('1+1') }} // eval 执行
{{ 123 instanceof Number }} // 原型链操作
{{ this.$router.push() }} // 路由跳转(应放在方法中)
{{ $emit('event') }} // 事件触发(模板中仅支持监听)
5. 隐式禁止的 Vue 特殊操作
// ❌ 这些在模板中不会报错但会产生问题
{{ v-if="false" }} // 指令错误写法(应不带引号)
{{ var x = 1 }} // 变量声明(模板中无效)
{{ function test(){} }} // 函数声明(模板中无效)
{{ import('module') }} // 动态导入(应放在 script 中)
{{ v-for="(item, index) in items" :key="index" }} // 不推荐的 key 用法
最佳实践对比表
| 禁止操作 | 替代方案 | 原因 |
|---|---|---|
arr.push(1) | computed: { newArr() { return [...arr, 1] } } | 保持数据不可变 |
alert('hi') | methods: { showAlert() { alert('hi') } } | 副作用隔离 |
window.location.href | 通过 app.config.globalProperties 注入后使用 | 安全限制 |
delete obj.prop | { ...obj, prop: undefined } | 响应式系统要求 |
技术栈说明
- Vue 3 响应式原理:基于 Proxy 的响应式系统会检测到数组变异方法并抛出警告
- 模板编译限制:Vue 模板编译器会静态分析表达式,阻止危险全局访问
- 最新规范:所有示例基于 Vue 3.4+ 和 ES2023 标准
如果需要使用受限功能,应通过以下方式:
// 安全的使用方式举例
export default {
methods: {
safeArrayUpdate() {
// 在方法中使用数组变异方法
this.$set(this.arr, this.arr.push(1))
},
safeGlobalAccess() {
// 在方法中访问 window
console.log(window.innerWidth)
}
}
}