8-9&10#去哪儿网app#使用Vuex实现数据共享及Vuex高级用法

本文介绍了如何使用Vuex状态管理库和Vue Router路由库,实现应用中城市选择的共享状态,并通过本地存储localStorage持久化城市信息。在组件中,通过commit直接调用mutations改变城市,同时更新页面并实现页面跳转。当刷新页面时,通过localStorage获取城市,确保状态不丢失。此外,还提到了getters的使用以及模块化的考虑,以提高代码的可维护性。
摘要由CSDN通过智能技术生成

mission:home和city之间共享,即在city中切换城市,home会变化。

用到Vuex,这是官方推荐的数据框架。

vuex

先在vscode中创建上图虚线部分的内容,暂且称其为store,我们创建一个state区域,存放公用数据

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
    state: {
        city: '北京'
    }
})

还要在main.js中,创建根实例new vue中,把store传进去,这样每个子组件都能使用这个数据

由于之前是ajax来传递数据,现在不需要了,可以把index.json中也去掉city,所以在home中可以把与city有关的代码都去掉, 回到header中,props里的city也去掉,并把插值表达式改为{{this.$store.state.city}},同样把city里的list组件的当前城市内容也改为{{this.$store.state.city}}。

想要实现点击city页面的热门城市,在home中变成一样的城市,那么就要更改最开始的state里的city的值。

按照官方文档流程图,组件调用actions,actions调用 mutations, mutations再去修改state:

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
    state: {
        city: '北京'
    },
    actions: {
        changeCity(ctx, city) {
            ctx.commit('changeCity', city)
        }
    },
    mutations: {
        changeCity(state, city) {
            state.city = city
        }
    }
})

其实这里组件可以直接调用mutations就可以,把actions可以去掉,

在组件中不用dispatch,直接commit调用mutations。list.vue:

methods : {
    handleCityClick (city) {
        this.$store.commit('changeCity',city)
        // alert(city)
    }
},

同样,对于list和search列表中的城市,可以把@click相关的代码复制过去,从而实现点击阿拉尔等全国城市也会在home里切换。

接着想要改变城市之后实现页面的跳转,用到vue.router,在每个组件(list和search)中:

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

这样就可以点击城市后,直接回到home!

此时还有问题,当首页刷新的话,定位的城市又回变成vuex的state代码我们给定的原始城市。

我们用localstorage来解决,实现本地cookie(存储)

export default new Vuex.Store({
    state: {
        city: localStorage.ciyu || '北京'
            // 逻辑运算符 A||B 若A能取到,则A,若A是false则peking!
    },
    // actions: {
    //     changeCity(ctx, city) {
    //         ctx.commit('changeCity', city)
    //     }
    // },
    mutations: {
        changeCity(state, city) {
            state.city = city
            localStorage.city = city
        }
    }
})

但如果用户使用隐私模式或取消cookie,就会异常,所以加上这样的代码:

let defaultCity = '北京'
try {
    if (localStorage.city) {
        defaultCity = localStorage.city
    }
} catch (e) {}

export default {
    city: defaultCity
}

可以把state和mutations都在单独的js文件中写。

浏览器提示:

chrome性能优化的一个警告,不用管,继续写代码就好了,手机上不会有这个问题的。

下面对代码再优化,import { mapState } from 'vuex',通过展开运算符,把vuex的city映射到计算属性中,映射名字是currentCity,再把div中的也改为currentCity

computed: {
    ...mapState({
        currentCity:'city'
    })
},
<div class="button">
    {{this.currentCity}}
    <!-- {{this.$store.state.city}} -->
</div>

达到简化效果,其余的插值表达式中的$store写法都可以改成这样同理。

补充:

①官方文档中的getters可根据state中的数据进行一些计算,类似于computed。

本次代码中,利用getters对home.vue右上角的城市进行修改,让其显示两次,在index.js里添加getters,在home的header中写成{{this.doubleCity}}

getters: {
    doubleCity(state) {
        return state.city + '' + state.city
    }
}

②module可以对复杂的mutations和actions进行拆分,可以提高可维护性。

 

最后一步!代码入库!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值