Vue2.5开发去哪儿网App 城市列表开发之 Vuex实现…

2019-02-28 07:51:11来源:博客园 阅读 ()

新老客户大回馈,云服务器低至5折

一,数据共享

1.  安装:

npm install vuex --save

2. 在src目录下 新建state文件夹,新建index.js文件

3. 创建一个 store

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

Vue.use(Vuex)
export default new Vuex.Store({
  state: {
    city: '上海'
  }
})

4.main.js中创建根实例时,传入store


import store from './store'
......
new Vue({ el: '#app', router, store, components: { App }, template: '
<App/>' })
......

5.然后子组件使用:

//获取城市名
{{this.$store.state.city}}

二,数据的修改

 

1. 给每个城市绑定一个方法:

@click="HandleCity(城市名)"
HandleCity (value) {
// 派发一个citychange city的 action
this.$store.dispatch('citychanged',value)
}

2. 在Index.js中:

  actions: {
//ctx上下文 citychanged (ctx, cityname) { ctx.commit(
'citychanged', cityname) } }
mutations: {
//改变数据
citychanged (state, city) {
state.city = city
}
}

效果:

3. 简化步骤

    HandleCity (value) {
      this.$store.commit('citychanged', value)
    }

index.js中 省略actions:

  mutations: {
    citychanged (state, city) {
      state.city = city
    }
  }

搜索Seatch组件步骤一致

三,使用localstorage存储当前城市,并返回到城市

每次刷新后,城市默认

localStorage - 用于长久保存整个网站的数据,保存的数据没有过期时间,直到手动去除。

let defaultCity = '北京'
try {
//判断浏览器是否支持
if (localStorage.city) { defaultCity = localStorage.city } } catch (e) {}
//点击后页面跳转
this.$router.push('/')

在 Vue 实例内部,你可以通过 $router 访问路由实例。因此你可以调用 this.$router.push

 

四,vuex高级使用

mapState:
import { mapState, mapMutations } from 'vuex'

mapState指将state数据映射到city的计算属性中
computed: mapState({
    current_city: 'city'
})
// html写法:
// {{this.current_city}}

 

mapMutations :

你可以在组件中使用 this.$store.commit('xxx') 提交 mutation,或者使用 mapMutations 辅助函数将组件中的 methods 映射为 store.commit 调用
    HandleCity (value) {
      this.citychanged(value)
      this.$router.push('/')
    },
    ...mapMutations([
      'citychanged'
    ])

mapgetter函数:

mapGetters 辅助函数仅仅是将 store 中的 getter 映射到局部计算属性:

import { mapGetters } from 'vuex'

export default {
  // ...
  computed: {
  // 使用对象展开运算符将 getter 混入 computed 对象中
    ...mapGetters([
      'doneTodosCount',
      'anotherGetter',
      // ...
    ])
  }
}
如果你想将一个 getter 属性另取一个名字,使用对象形式:

mapGetters({
  // 把 `this.doneCount` 映射为 `this.$store.getters.doneTodosCount`
  doneCount: 'doneTodosCount'
})
<template>
  <div class="list" ref="wrapper">
    <div>
      <div class="area">
        <div class="title border-topbottom">当前城市</div>
        <div class="button-list">
          <div class="button-wrapper">
            <div class="button" ref="mycity">{{this.current_city}}</div>
          </div>
        </div>
      </div>
      <div class="area">
        <div class="title border-topbottom">热门城市</div>
        <div class="button-list">
          <div class="button-wrapper"  v-for="city in hotcities" :key="city.id">
            <div class="button" @click="HandleCity(city.name)">{{city.name}}</div>
          </div>
        </div>
      </div>
      <div class="area" v-for="(city,key) in cities" :key="key" :ref="key">
        <div class="title border-topbottom">{{key}}</div>
        <div class="item-list">
          <div class="item border-bottom" v-for="c in city" :key="c.id" @click="HandleCity(c.name)">{{c.name}}</div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import BScroll from 'better-scroll'
import { mapState, mapMutations } from 'vuex'
export default {
  name: 'CityList',
  mounted: function () {
    this.scroll = new BScroll(this.$refs.wrapper)
  },
  props: ['cities', 'hotcities', 'letter'],
  methods: {
    HandleCity (value) {
      // this.$store.commit('citychanged', value)
      this.citychanged(value)
      this.$router.push('/')
    },
    ...mapMutations([
      'citychanged'
    ])
  },
  watch: {
    letter () {
      if (this.letter) {
        const element = this.$refs[this.letter][0]
        this.scroll.scrollToElement(element)
      }
    }
  },
  computed: mapState({
    current_city: 'city'
  })
}
</script>
<style lang="stylus" scoped>
  @import "~styles/varibles.styl"
  .border-topbottom
    &:before
      border-color #ccc
    &:after
      border-color #ccc
  .border-bottom
  &:before
    border-color #ccc
  .list
    overflow hidden
    position absolute
    top 1.58rem
    right 0
    bottom 0
    left 0
    .title
      line-height .54rem
      padding-left .2rem
      background #eee
      color #666
      font-size .26rem
    .button-list
      padding .1rem .6rem .1rem .1rem
      overflow hidden
      .button-wrapper
        float left
        padding .1rem
        .button
          text-align center
          margin .1rem
          border .02rem solid #ccc
          border-radius .06rem
          padding .1rem .5rem
    .item-list
      .item
        line-height .76rem
        padding-left .2rem
</style>
List.vue
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,
  // 省略步骤
  // 1. this.$store.dispatch('citychanged', value)
  // 2. actions: {
  //   citychanged (ctx, cityname) {
  //     ctx.commit('citychanged', cityname)
  //   }
  // },
  mutations: mutations
})
/src/store/index.js

五,keep-alive优化网页性能

解决每次进入页面都发送ajax请求的问题

1.  keep-alive是Vue提供的一个抽象组件,用来对组件进行缓存,从而节省性能

<template>
  <div id="app">
    <!--#显示当前路由对应的内容-->
    <keep-alive>
      <router-view/>
    </keep-alive>
  </div>
</template>

2.  当组件在keep-alive内被切换时组件的activated、deactivated这两个生命周期钩子函数会被执行

添加LastCity 属性

  mounted () {
    this.getHomeInfo()
    this.LastCity = this.city
  }
  activated () {
    // 当页面加载时,进行判断,城市发生了改变
    if (this.LastCity !== this.city) {
      this.getHomeInfo()
// 更新上一城市
this.LastCity = this.city } },

项目地址:

https://github.com/1417766861/Vue2.5-App


原文链接:https://www.cnblogs.com/donghaoblogs/p/10447361.html
如有疑问请与原作者联系

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:react 源码之setState

下一篇:开发谷歌浏览器插件会上瘾,搞了一个JSONViewer,一个页面格式化