uni-app 全局变量的使用
全局变量
目录:
- 通过js文件实现
- 通过Vue.prototype来实现
- globalData
- 通过Vuex实现
1、通过js文件实现
创建一个js文件,如:global.js
,假设我们需要一个能够在全局访问的data对象,我们可以这样写:
var data = {}
function setData(obj){
data = obj
}
function getData(isCopy = false) {
if (!isCopy) {
return data
}
return JSON.parse(JSON.stringify(data))
}
module.exports = {
setData: setData,
getData: getData
}
个人是建议写成set和get函数的方式来设置和获取data变量,不建议直接将data暴露给外部。
外部vue文件想访问data,导入js文件即可:
<script>
/// 导入js文件,这里用的是相对路径
import global from "../../common/js/global.js"
export default {
onShow:function(){
// 调用setData函数,可以设置data的值
global.setData({'name': 'diudiu'})
// 调用getData函数,可以拿到data的值
var data = global.getData()
console.log(data)
}
}
</script>
外部js文件想要访问data,同理只要导入路径。
import global from './global.js'
function testMethod(){
var data = global.getData()
console.log(data)
}
module.exports = {
testMethod: testMethod
}
这种方式的缺点是每一个使用的地方都需要导入头文件。
2、通过Vue.prototype来实现
注: .vue 和 .nvue 并不是一个规范,因此一些在 .vue 中适用的方案并不适用于 .nvue。 Vue 上挂载属性,不能在 .nvue 中使用。
1、直接挂载
一些常用的使用频次高的函数和属性,我们可以直接挂载到Vue.prototype上
在 main.js 中挂载属性/方法:
/// 挂载属性
Vue.prototype.data = {
name: 'diudiu'
}
/// 挂载函数
Vue.prototype.log = function(){
console.log('......')
}
在vue文件中使用:
<script>
export default {
onShow:function(){
/// 访问属性
var data = this.data
console.log(data)
/// 调用方法
this.log()
}
}
</script>
控制台输出:
{name: "diudiu"}
......
但是不建议挂载直接写属性名和函数名,因为这样如果vue中也有同名的属性和函数时,vue中访问的就是自己的属性和函数。所以我们一般使用
Vue.prototype
挂载属性和函数时会在前面加上$
前缀。上面的代码改造如下:
Main.js中
/// 挂载属性
Vue.prototype.$dataObj = {
name: 'diudiu'
}
/// 挂载函数
Vue.prototype.$log = function(){
console.log('......')
}
vue文件中调用:
<script>
export default {
onShow:function(){
/// 访问属性
var data = this.$dataObj
console.log(data)
/// 调用方法
this.$log()
}
}
</script>
2、挂载js文件
通过Vue.prototype
将属性和函数一个一个的挂载上去,最后main.js
会显得很臃肿,而且不好维护。我们可以按需将他们抽离出来分别封装到对应的js文件中,以上文的global.js
为例,在main.js
中直接挂载global.js
:
/// 导入js文件
import global from 'common/js/global.js'
/// 挂载
Vue.prototype.$global = global
在vue文件中使用
<script>
export default {
data() {
return {
}
},
onShow:function(){
/// 调用global中的setData函数
this.$global.setData({name:'diudiu'})
/// 调用global中的getData函数
var data = this.$global.getData()
console.log(data)
}
}
</script>
通过Vue.prototype方式优点是不需要在使用的地方导入路径,缺点是该方式只在vue文件中通用,在js文件中不生效。
3、globalData
小程序中有globalData
的概念,我们可以在App.vue
文件中设置globalData
。
<script>
export default {
globalData:{
name:'diudiu',
logString:function(str){
console.log(str)
}
},
onLaunch: function() {
},
onShow: function() {
},
onHide: function() {
}
}
</script>
这里我们设置了一个属性:name,一个函数:logString。在js文件或者vue文件中,我们可以通过getApp().globalData
来拿到它。代码如下:
var global = getApp().globalData
var name = global.name
global.logString('name: ' + name)
/// 控制台输入如下:
/// name: diudiu
注:
如果你需要在
App.vue
中使用globalData
,不能通过getApp().globalData
方式来获取。在
App.vue
需使用this.$options.globalData
来获取globalData
,代码示例如下:
<script> export default { globalData:{ name:'diudiu', logString:function(str){ console.log(str) } }, onShow: function() { console.log(this.$options.globalData) } } </script>
4、通过Vuex实现
我们某一个页面vue文件的计算型属性模块引用了上述方法定义的全局变量时,当变量发生改变时并不能及时的反馈在当前页面中。举个例子:
<template>
<view >
<button type="default" @click="buttonClick">点击修改name</button>
<text>{{ name }}</text>
</view>
</template>
<script>
export default {
computed: {
name(){
return getApp().globalData.name
}
},
method:{
buttonClick: function(){
getApp().globalData.name = '张三'
}
}
}
</script>
点击按钮触发buttonClick
函数,全局变量globalData.name值实际上被修改了,但是界面上展示的name还是之前的值,并不会被刷新。需要界面实时刷新,可以考虑使用Vuex的方式实现。
1、创建相关目录和文件
在工程根目录下创建store文件夹,并在store文件夹下创建index.js文件。js文件内容如下:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
name: '李四'
},
mutations: {
modifyUserName(state){
state.name = '张三'
}
}
})
export default store
2、挂载
main.js文件中
import store from './store'
Vue.prototype.$store = store
Vue.config.productionTip = false
App.mpType = 'app'
const app = new Vue({
store,
...App
})
app.$mount()
使用
此时改造下第一步中的vue文件代码
<template>
<view >
<button type="default" @click="buttonClick">点击修改name</button>
<text>{{ name }}</text>
</view>
</template>
<script>
import {mapState, mapMutations} from 'vuex'
export default {
computed: {
...mapState(['name'])
},
method:{
...mapMutations(['modifyUserName']),
buttonClick: function(){
this.modifyUserName()
}
}
}
</script>
此时,点击按钮修改name之后,界面展示的文字也会发生改变。对比前面的方式,该方式更加适合处理全局的并且值会发生变化的情况。
关于vuex更详细的语法和用法,请参考教程:地址