去哪儿-14-vuex_localstorage

目标: Vuex的高级使用与localStorage本地存储

  1. bug:我们在src/store/index.js中设置的city的默认值是“上海”,当我们在城市列表中选择某一个城市的时候,首页上确实会变成相应的城市,但是当我们再刷新首页的时候会发现又变成了“上海”。

正常情况下我们去访问一个网页,当再次打开的时候,它显示的应该是用户上次请求的内容。在H5中有一个新增API: localStorage,它可以帮助我们实现类似Cookie的功能,做到本地存储,这个API比Cookie更简单,所以在这里使用localStorage来实现城市保存的功能。

  1. localStorage的使用:在city这个数据发生变化的时候,除了改变公共数据state中的city,还要把这个city进行本地存储,而首页中city的默认值就是localStorage.city或者上海:
export default new Vuex.Store ({
    state: {
        city: localStorage.city || '上海'
    },
    mutations: {
        changeCity (state, city) {
            state.city = city
            localStorage.city = city
        }
    }
})

注意: 在使用localStorage的时候最好是在外层加一个try-catch,因为如果用户关闭了浏览器的本地存储功能或者使用隐身模式,使用localStorage有可能会导致浏览器直接抛出异常,整个代码就无法运行了,为了避免这种问题,最好是在外层加一个try-catch:

let defaultCity = '上海'
try {
    if (localStorage.city) {
        defaultCity = localStorage.city
    }
} catch (error) {}

export default new Vuex.Store ({
    state: {
        city: defaultCity
    },
    mutations: {
        changeCity (state, city) {
            state.city = city
            try {
                localStorage.city = city
            } catch (error) {}
            
        }
    }
})
  1. store目录下的index.js文件中的内容开始变得复杂起来了,在真正的项目开发中,会将整个文件做进一步的拆分。

在store中创建state.js文件,将与城市数据更新相关的代码拆分到state.js文件中,并将city export出去,这时需要在index.js中引入这个模块才能使用state.js接口对象中的city数据。

state.js:

let defaultCity = '上海'
try {
  if (localStorage.city) {
    defaultCity = localStorage.city
  }
} catch (error) {}

export default {
  city: defaultCity
}

创建store/mutations.js,将index.js中的mutations下的changeCity函数拆分到mutations.js文件中并export出去,则在index.js中使用这个模块同样要import进去。

mutations.js:

export default {
    changeCity(state, city) {
      state.city = city
      try {
        localStorage.city = city
      } catch (error) {}

    }
}

此时index.js中就变成了:

import Vue from 'vue'
import Vuex from 'vuex'
import state from './state'
import mutations from './mutations';

Vue.use(Vuex)

export default new Vuex.Store ({
    state: state,
    mutations: mutations
})

键和值是一样的,可以进一步修改成ES6的写法:

export default new Vuex.Store ({
    state,
    mutations
})
  1. 小bug: 当我们选择的城市名字是4个字或者5个字的时候,会发现首页的header部分会被撑开,页面样式放生了变化。

在home的Header.vue组件中进行样式的修改:
原本是:

.header-right
    width: 1.24rem
    float: right 
    text-align: center
    color: #fff

上面的代码写死了它的宽度,修改:

.header-right
    min-width: 1.04rem
    padding 0 .1rem
    float: right 
    text-align: center
    color: #fff
  1. vuex的使用的优化

我们在使用state当中的city数据时,是这样写的:this.$store.state.city,写起来很繁琐, vuex提供了一个简便的API。

pages/home/components/Header.vue中首先引入:import { mapState } from 'vuex', 然后设置一个计算属性:

export default {
    name: 'HomeHeader',
    computed: {
        ...mapState(['city'])
    }
}

计算属性中的...是一个展开运算符,mapState的意思是指把vuex里面的数据映射到当前这个组件的计算属性中,就是把city这个公用数据映射到名称为city的计算属性中,所以,在使用这个数据的时候就可以使用this.city替换原来的this.$store.state.city

也可以这样用:

computed: {
    ...mapState({
        currentCity: 'city'
    })
}

表示的是: 想要把公用数据中的city映射到当前组件的计算属性当中,映射过来的名称叫作currentCity,所以这里就可以直接用this.currentCity代替this.$store.state.city

同样的,当点击城市按钮的时候,city数据将会发生变化,就会去派发一个mutation,即this.$store.commit('changeCity', city)。Vuex同样也提供了一个简便的方法:mapMutations。

首先,import { mapState, mapMutations } from 'vuex',然后在methods中应用mapMutations:

methods: {
    handleCityClick (city) {
        // this.$store.commit('changeCity', city)
        this.changeCity(city)
        this.$router.push('/')
    },
    ...mapMutations(['changeCity'])
}

...mapMutations(['changeCity'])表示的意思是: 有一个名字叫作changeCity的mutation,我把这个mutation映射到当前组件的一个名为changeCity的方法中,那如果要调用这个mutation就可以直接使用this.changeCity(city)来代替this.$store.commit('changeCity', city)了。

Search.vue中也要做出同样的修改,但是一定要记得先引入这个方法。

Vuex核心概念中的Getters它是一个方法,它的参数是state,可以根据state的值经过计算得到一些新的值,避免数据的冗余,它的功能有点类似于计算属性。

Module在目前还应用不上,具体的应用方法去官网自行学习。

代码提交

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值