Vue.js如何在data选项中引用自定义常量?
我当前的Vue代码如下:
new Vue({ el: '#app', const: { monthNames : ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], }, data: { year : (new Date()).getFullYear(), month : (new Date()).getMonth(), monthName : this.monthNames[(new Date()).getMonth()], day : (new Date()).getDate(), }, ... })
我尝试通过(new Date()).getMonth()去获取const配置里monthNames数组对应的月份名称,但控制台抛出错误:Uncaught TypeError: Cannot read property '4' of undefined。请问该怎么在data里正确引用monthNames呢?我使用的是最新版JavaScript开发构建版本。
首先得说,你这里有两个核心问题需要修正:
1. Vue实例选项里没有const这个配置项
Vue官方的实例选项里根本不存在const这个属性,你没法通过它来定义实例内部的常量。得把monthNames放到合适的位置,比如外部全局常量、data里,或者用计算属性来处理。
2. data初始化阶段this的指向问题
就算你把monthNames放到正确的位置,在data的初始化对象里直接用this也拿不到Vue实例的属性——因为此时实例还没创建完成,this的指向并不是你期望的Vue实例。
给你几个实用的解决方案:
方案一:把monthNames定义为外部全局常量
这是最直接也最推荐的方式,把月份数组定义在Vue实例外面,这样不管是data还是实例的其他部分都能直接调用:
// 外部定义可复用的常量 const monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]; new Vue({ el: '#app', data: { year : (new Date()).getFullYear(), month : (new Date()).getMonth(), day : (new Date()).getDate(), }, computed: { // 用计算属性动态获取月份名称,month变化时会自动更新 monthName() { return monthNames[this.month]; } }, ... })
用计算属性的好处是,如果之后month的值发生变化(比如做月份切换功能),monthName会自动同步更新,比直接在data里初始化死值要灵活得多。
方案二:用data的工厂函数封装内部常量
如果想把monthNames封装在Vue实例内部,可以用data的工厂函数形式(Vue 2.x的组件必须用工厂函数,根实例也支持),这样能在初始化时直接访问到内部定义的常量:
new Vue({ el: '#app', data() { // 先在工厂函数内部定义常量 const monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]; const currentDate = new Date(); // 返回data对象,直接用内部常量初始化 return { monthNames, year : currentDate.getFullYear(), month : currentDate.getMonth(), day : currentDate.getDate(), monthName : monthNames[currentDate.getMonth()] } }, ... })
这种方式把所有相关数据都封装在实例内部,避免了全局变量污染,同时也避开了this指向的问题。
方案三:在created钩子中初始化monthName
如果你一定要把monthNames放在data里,也可以在实例创建完成后的created钩子中给monthName赋值——此时this已经能正确指向Vue实例了:
new Vue({ el: '#app', data: { monthNames : ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], year : (new Date()).getFullYear(), month : (new Date()).getMonth(), day : (new Date()).getDate(), monthName: '' // 先初始化空值 }, created() { // 实例创建完成后,this能正确访问到data里的所有属性 this.monthName = this.monthNames[this.month]; }, ... })
总结一下,方案一和方案二是更优的选择:方案一适合需要在多个地方复用的常量,方案二更适合数据封装在实例内部的场景。
内容的提问来源于stack exchange,提问作者user7179686

