2020-01-29 Vuex 和 this 的填坑记录

1. npm install vuex --save

2. main.js :

import Vuex from 'vuex'
Vue.use(Vuex)

const store = new Vuex.Store({
state: {
  loginState: false, //定义一个全局变量loginState监控登录状态
},
//vuex的全局变量是不可以直接修改值的,必须在mutations里设置对应的方法来修改
mutations: {
  loginStateChanged(state, r) { 
    state.loginState = r
  }
}
})

new Vue({
el: "#app",
store, //这里将我们设置好的store灌注到根Vue实例中去
router,
components: {
  App,
},
template: '<App/>',

methods: {  },
mounted: function () {
},
})
设置好store之后,我们可以在任意地方用:

-用 this.$store.state.loginState 来访问loginState的值
-用 this.$store.commit('loginStateChanged', true) 来设置loginState的值

3. 子组件的模板中:

        <span v-show="loginState"> //利用v-show来动态渲染
          已登录
        </span>
如果loginState=true 则渲染并显示 “已登录” 这三个字, 反之则不显示。
子组件的computed属性里需要添加一个loginState监控,只有这样才能实现“响应式”全局变量的目的。
  computed: {
    loginState() {
      //此处返回全局变量loginState的值(true/false)
      return this.$store.state.loginState 
    }
  },

4. 总结

看到这里,你可能想问,vue本身就可以实现全局变量功能,用这么麻烦的办法去实现一个相同的功能,又是何苦呢? 其实并非如此,vuex除了具有全局性之外,它还是响应式的,如本例,当loginState = false的时候,UI显示游客能看到的内容,而当loginState = true的时候,则动态渲染正式会员才能看到的界面,大概就这意思。

5. 坑

用Vue.use(Vuex) 引用的Vuex的时候,全局变量将灌注到所有的子组件里去,但是当我们的组件不是以Vue.use而是采用Vue.extend注册的,那么这个组件是无法访问根实例的this的。例如:

Vue.prototype.$login = function (data) { //这是一个全局弹窗组件
const LoginBox = Vue.extend(Login) // 注意,此处采用extend来注册该组件
let instance = new LoginBox({data})
let LoginEl = instance.$mount().$el
document.body.appendChild(LoginEl)
Vue.nextTick(() => {
  instance.dialogVisible = true
})
}

那么,在这个组件中,你就不能采用 this.$store.state.变量名,去访问那些全局变量了,因为此处的this并非根vue实例的this.如果强行引用,则会抛出一个:

cannot read property store of undefined vuex

为了避免这个错误,我们可以将这个根this存放在一个vue的全局变量里。
(注意:这个例子也完整展示了传统上vue是如何设置全局变量的)

第1步. 创造一个global_variable.js的独立文件:

const loginState = false
const token = '1234567'
const userSite = '床前明月光'
let globalThis = ''

export default { //将这些变量暴露给外界
loginState,
token,
userSite,
globalThis
}

第2步. 在main.js中这么用:

import globalVariable from './global_variable'
Vue.prototype.GLOBAL = globalVariable

//。。。略

mounted: function () {
   this.autoLogin()
   this.GLOBAL.globalThis = this //在根实例加载的时候用全局变量globalThis记下Vue根实例的this
 },

在其他子组件中(包括用expend注册的)中,就可以用过this.GLOBAL.globalThis来访问根实例了。例如在本例中,可以这样访问loginState的值:

console.log(this.GLOBAL.globalThis.$store.state.loginState)

或者修改它:

this.GLOBAL.globalThis.$store.commit('loginStateChanged', false)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

rockage

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值