vue共享数据---vuex state

安装

npm run vuex --save

是什么? 怎么使用

vuex 是一个专门为vue.js应用程序开发的状态管理模式。
这个状态我们可以理解为在data中的属性,需要共享给其他组件使用的部分。
也就是说,是我们需要共享的data,使用vuex进行统一集中式的管理。

vuex中,有默认的五种基本的对象:

state:存储状态(变量)
getters:对数据获取之前的再次编译,可以理解为state的计算属性。我们在组件中使用 s o t r e . g e t t e r s . f u n ( ) m u t a t i o n s : 修 改 状 态 , 并 且 是 同 步 的 。 在 组 件 中 使 用 sotre.getters.fun() mutations:修改状态,并且是同步的。在组件中使用 sotre.getters.fun()mutations使store.commit(’’,params)。这个和我们组件中的自定义事件类似。
actions:异步操作。在组件中使用是$store.dispath(’’)
modules:store的子模块,为了开发大型项目,方便状态管理而使用的。这里我们就不解释了,用起来和上面的一样。

图解

在这里插入图片描述
这个图很重要
管理应用的所有组件的状态。
这个状态自管理应用包含以下几个部分:
state,驱动应用的数据源;
view,以声明方式将 state 映射到视图;
actions,响应在 view 上的用户输入导致的状态变化。

使用

在这里插入图片描述
导出创建的库

import Vue from 'vue'
import Vuex from 'vuex'
import state from './state'
import mutations from './mutations'
import actions from './actions'
Vue.use(Vuex)
// 导出 的是通过vuex 创建的仓库
export default new Vuex.Store({
  // 存放全局公用的数据 在 state.js 中 和mutations.js中
  state,
  mutations,
  actions
})

这里还有 state、 mutations、actions三个文件 分别对应的是vuex 的3个对象
第一种方法: 直接使用
在这里插入图片描述

<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">{{this.$store.state.city}}</div>
          </div>
        </div>
      </div>
      <div class="area">
        <div class="title border-topbottom">热门城市</div>
        <div class="button-list">
          <div 
            class="button-wrapper"  
            v-for=' item of hotCities ' 
            :key='item.id'
            @click="handleCityClick(item.name)"
          >
            <div class="button">{{item.name}}</div>
          </div>
        </div>
      </div>
      <div class="area" 
        v-for="(item,key) of cities "
        :ref="key" 
        :key="key"
        
        >
        <div class="title border-topbottom" >{{key}}</div>
        <div class="item-list"> 
          <div class="item border-bottom"
            v-for="innerItem of item" 
            :key="innerItem.id"
            @click="handleCityClick(innerItem.name)"
            >
            <div>{{innerItem.name}}</div>
          </div>
        
        </div>
      </div>    
    </div>
  </div>
</template>

<script>
import Bscroll  from 'better-scroll'
// 代码优化  将vuex 中的 state  、  mutations、actions  映射到此对象上
import { mapState, mapMutations,mapActions } from 'vuex'

export default {
  name:"CityList",
  props:{
    hotCities:Array,
    cities:Object,
    letter:String
  },
  methods:{
    handleCityClick(city) {
      console.log("共享数据");
      //  使用vuex 中的对象的第一种方法 还有另一种高级在search.vue 中
      this.$store.dispatch('changeCity',city);
      // localstroage 中保存一份 刷新之后 还 有城市
      localStorage.city = city;
      this.$router.push('./home');

    }
  
  },
  watch:{
    letter(){// 方法名要和数据一样
      console.log("到watch ");
      if(this.letter){
        // scroll 组件中的操作
        const element = this.$refs[this.letter][0];
        this.scroll.scrollToElement(element);
      }
    }
  },
  mounted(){
    //  { mouseWheel: true, click: true, tap: true }后面的加上点击才会生效
    this.scroll = new Bscroll(this.$refs.wrapper,{ mouseWheel: true, click: true, tap: true });
  },
  computed:{
    //扩展运算符...mapState,意思是把vuex的state数据映射到计算属性里面,映射后的名字为city  使用state中对象
    ...mapState({
      currentCity:'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.7rem
    left:0
    right:0
    bottom:0
    .title
      line-height:.54rem
      background:#eee
      padding-left:.2rem
      color:#666
      font-size:.26rem
    .button-list
      overflow:hidden
      padding:.1rem .6rem .1rem .1rem
      .button-wrapper
        float:left
        width:33.33%
        .button
          margin: .1rem
          padding: 0.1rem
          text-align: center
          border:.02rem solid #cccccc
          border radius 0.06rem
    .item-list
      .item
        line-height:.76rem
        padding-left:.2rem
</style>

第二种方法 将vuex对象映射到当前对象中 具体代码
在这里插入图片描述

<template>
  <div>
    <div class="search">
      <input  v-model="keyword" class="search-input" type="text" placeholder="请输入城市或拼音" />
    </div>
    <div 
      class="search-content"
      ref="search"
      v-show="keyword"
    >
      <ul>
        <li
          class="search-item border-bottom"
          v-for="item of list"
          :key="item.id"
          @click="handleCityClick(item.name)"
        >
        {{item.name}}
        </li>
        <li class="search-item border-bottom" v-show="hasNodata">
          没有找到匹配的数据
        </li>
      </ul>
    </div>
  </div>
</template>

<script>
import Bscroll from 'better-scroll'
// 代码优化  将vuex 中的 state  、  mutations、actions  映射到此对象上
import { mapState, mapActions,mapMutations } from 'vuex'
export default {
  name:'CitySearch',
  props:{
    cities:Object
  },
  data(){
    return {
      keyword:'',
      list:[],
      timer:null
    }
  },
  computed:{//计算属性
    // 查看是否有数据 
    hasNodata(){
      return !this.list.length
    }
  },
  watch:{
    keyword(){
      //截流 降低内存
      if(this.timer){
        clearTimeout(this.timer);
      }
      // 查看是否有值决定显示的内容
      if(!this.keyword){
        this.list = [];
        return 
      }
      this.timer = setTimeout(()=>{
        const result = []
        for (let i in this.cities){
          this.cities[i].forEach((value) =>{
              if(value.spell.indexOf(this.keyword) > -1 || value.name.indexOf(this.keyword) > -1){
                result.push(value);
              }
          })
          
        }
        console.log(result);
        this.list = result
      },100);
    },
    

  },
  mounted (){
    this.scroll = new Bscroll(this.$refs.search,{ mouseWheel: true, click: true, tap: true });
  },
  methods:{
    handleCityClick(city) {
      console.log("共享数据");

      //this.$store.dispatch('changeCity',city);
      this.changeCity(city);
      // localstroage 中保存一份 刷新之后 还 有城市
      localStorage.city = city;
      this.$router.push('./home');
    },
    //  vuex 高级使用 ...mapMutation把本组件的mutations映射到changeCity方法里(changeCity在mutations里)
    ...mapActions(['changeCity'])
  }
}
</script>
<style lang="stylus" scoped>
  @import '~styles/varibles.styl'
  .search
    height: .72rem
    padding: 0 .1rem
    background: $bgColor
    .search-input
      box-sizing: border-box
      width: 100%
      height: .62rem
      padding: 0 .1rem
      line-height: .62rem
      text-align: center
      border-radius: .06rem
      color: #666
  .search-content
    z-index: 1
    overflow: hidden
    position: absolute
    top: 1.58rem
    left: 0
    right: 0
    bottom: 0
    background: #eee
    .search-item
      line-height: .62rem
      padding-left: .2rem
      background: #fff
      color: #666
</style>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值