一:简介
在 Vue.js 中,经常会看到 this.$XXX 这种写法,那么这个是什么呢?其实这里就是使用 Vue.prototype 所定义的一个挂载到本身的全局方法,主要是为了防止全局变量的污染,所以我们来共同商议的一种写法。
Vue.prototype 可以用来添加一些全局的属性或方法,使其在每个 Vue 实例中都可用。Vue.prototype 可以添加任何类型的属性或方法,比如:常量、对象、方法等。
它是就是解决 替换全局使用的一个标识。
添加全局属性:
添加全局属性可以方便我们在项目中使用。例如在项目中我们需要获取当前时间戳,我们可以在 main.js 中添加如下代码:
Vue.prototype.$getTimestamp = function () {
return new Date().getTime()
}
上面的代码定义了一个名为 $getTimestamp 的全局方法,可以在整个项目中使用。在组件中使用该全局方法,只需在组件中使用 this.$getTimestamp 即可。
添加全局方法
添加全局方法也是同样的道理,在 main.js 文件中添加如下代码:
Vue.prototype.$sayHello = function (name) {
console.log(`Hello, ${name}!`)
}
上面的代码定义了一个名为 $sayHello 的全局方法,它接收一个参数 name,可以在整个项目中使用。在组件中使用该方法,只需在组件中使用 this.$sayHello("John"),就可以打印出 "Hello, John!" 了。
二:示例
下面我们通过两个示例说明 Vue.prototype 的使用。
示例一
在项目中经常会用到 Vue 的生命周期函数,如 created()、mounted() 等。如果每个组件都想要执行特定的逻辑,就需要在每个组件中的对应生命周期函数中实现,代码会显得非常冗余。这时可以考虑将该逻辑封装到共享的函数中,在 Vue.prototype 中定义该函数。
// 定义全局函数
Vue.prototype.$log = function (msg) {
console.log(`[${new Date().toLocaleString()}]: ${msg}`)
}
// 使用全局函数
export default {
created() {
this.$log("组件创建成功!")
},
mounted() {
this.$log("组件挂载成功!")
}
}
上面的代码中,我们在 Vue.prototype 中定义了一个名为 $log 的全局函数,用于记录每个组件的生命周期,然后在组件的 created()、mounted() 生命周期中分别调用 $log() 函数。
示例二
在 Vue.js 中,我们可以通过 $http 或 axios 等第三方库来进行网络请求。为了方便,我们可以将其包装成插件形式,通过 Vue.use() 来引入。
// 封装插件
import axios from "axios"
const myPlugin = {
install(Vue) {
Vue.prototype.$http = axios
}
}
// 使用插件
Vue.use(myPlugin)
// 在组件中使用 $http
export default {
mounted() {
this.$http.get("/api/users")
.then(response => console.log(response))
.catch(error => console.log(error))
}
}
上面的代码中,我们把 axios 封装成一个插件,并将其添加到 Vue.prototype 中,使其在每个 Vue 实例中都可用。在组件中使用 $http,只需像普通的函数一样调用,不需再引入和初始化 axios。
三:为什么“$”开头?
$ 是在 Vue 所有实例中都可用的属性的一个简单约定。这样做会避免和已被定义的数据、方法、计算属性产生冲突。其实可以是任意字符,比如“#”,“¥”等都可以。
错误示例:
如果代码书写如下,其全局和局部定义了同一个变量名:
Vue.prototype.appName = 'My App'
new Vue({
data: {
// 啊哦,`appName` *也*是一个我们定义的实例属性名!
appName: 'The name of some other app'
},
beforeCreate: function () {
console.log(this.appName)
},
created: function () {
console.log(this.appName)
}
})
日志中会先出现 "My App"
,然后出现 "The name of some other app"
,因为 this.appName
在实例被创建之后被 data
覆写了。我们通过 $
为实例属性设置作用域来避免这种事情发生。你还可以根据你的喜好使用自己的约定,诸如 $_appName
或 ΩappName
,来避免和插件或未来的插件相冲突。
当然有的同学不是了解vue 有这种使用的情况下,那么建议使用 require/import 来替换就好了(大型项目使用它就比较好维护)。