我在第一次进入页面时city页面的点击地区改变$store中的state事件就可以正常执行,但再次刷新就无法运行

我在第一次进入页面时city页面的点击地区改变$store中的state事件就可以正常执行,但再次刷新就无法运行

问题:我在第一次进入页面时city页面的点击地区改变$store中的state事件就可以正常执行,但再次刷新就无法运行。我尝试使用console.log来判断citySearch.vue和cityList.vue中的点击事件是否可以正常执行,发现首次进入网站后再次刷新网页除了cityList.vue中热门地区的点击事件可以使用,citySearch.vue中ul区块和cityList.vue中A,B,C等区块的点击事件均不可以使用

city.vue

<template>
<div>
<city-header></city-header>
<city-search :cities="cities"></city-search>
<city-list :hotCities="hotCities" :cities="cities" :changeALph="changeALph"></city-list>
<city-alph :cities="cities" @change="handleAlph"></city-alph>
</div>
</template>

<script>
import CityHeader from './component/CityHeader.vue'
import CitySearch from './component/CitySearch.vue'
import CityList from './component/CityList.vue'
import CityAlph from './component/CityAlph.vue'
import axios from 'axios'
export default {
name: 'City',
components: {
CityHeader,
CitySearch,
CityList,
CityAlph
},
data () {
return {
city: '',
hotCities: [],
cities: {},
changeALph: ''
   }
},
methods: {
getAxios () {
axios.get('/api/city.json')
.then(this.successInfo)
},
successInfo (res) {
if (res.data.ret && res.data.data) {
this.city = res.data.data.city
       this.hotCities = res.data.data.hotCities
       this.cities = res.data.data.cities
       console.log(res)
}
},
handleAlph (letter) {
this.changeALph = letter
}
},
mounted () {
this.getAxios()
}
}
</script>

<style scoped>

</style>

cityHeader.vue

<template>
<div class="cityHeader">城市选择
   <router-link to="/">
<div class="cityHeader-left">
<div class="iconfont backIcon">&#xe685;</div>
</div>
</router-link>
</div>
</template>

<script>
export default {
name: 'CityHeader'
}
</script>

<style lang="stylus" scoped>
@import "~styles/varibles.styl"
 .cityHeader
   position:relative
   height:.86rem
   background:$bgColor
   overflow:hidden
   text-align:center
   line-height:.86rem
   color:white
   font-size:.32rem
   .cityHeader-left
     position:absolute
     top:0
     left:0
     padding-left:.1rem
     color:white
     .backIcon
      font-size:.4rem
</style>

citylist.vue

<template>
<div class="cityList" ref="wrapper">
<div>
<div class="area">
<div class="areaTitle border-topbottom">当前位置</div>
<div class="btnList">
<div class="btnWrapper">
<button class="areaBtn">{{this.currentCity}}</button>
</div>
</div>
</div>
<div class="area">
<div class="areaTitle border-topbottom">热门地区</div>
<div class="btnList">
<div class="btnWrapper" v-for="item of hotCities" :key="item.id" @click="changeAreaBtn(item.name)">
<button class="areaBtn">{{item.name}}</button>
</div>
</div>
</div>
<div class="area" v-for="(item,key) of cities" :key="key" :ref="key">
<div class="areaTitle border-topbottom">{{key}}</div>
<div class="areaItems" v-for="singleItem of item" :key="singleItem.id" @click="changeAreaBtn(singleItem.name)">
<div class="areaItem border-bottom">{{singleItem.name}}</div>
</div>
</div>
</div>
</div>
</template>

<script>
import BScroll from '@better-scroll/core'
import {mapState, mapMutations} from 'vuex'
export default {
name: 'CityList',
computed: {
...mapState({
currentCity: 'city'
   })
},
mounted () {
this.scroll = new BScroll(this.$refs.wrapper)
},
updated () {
this.scroll.refresh()
},
props: {
hotCities: Array,
cities: Object,
changeALph: String
},
watch: {
changeALph () {
if (this.changeALph) {
const ele = this.$refs[this.changeALph][0]
this.scroll.scrollToElement(ele)
}
}
},
methods: {
changeAreaBtn (city) {
// this.$store.dispatch('changeArea', city)
     // this.$store.commit('changeRegion',city)
     this.changeRegion(city)
this.$router.push('/')
},
...mapMutations(['changeRegion'])
}
}
</script>

<style lang="stylus" scoped>
.border-topbottom
   &:before
     border-color:#ccc
   &:after
     border-color:#ccc
 .border-bottom
   &:before
     border-color:#ccc
 .cityList
   position:absolute
   left:0
   top:1.58rem
   bottom:0
   right:0
   overflow:hidden
   .area
     .areaTitle
       background:#eee
       padding:.1rem .1rem
     .btnList
       padding:.1rem .6rem 0rem .1rem
       overflow:hidden
       .btnWrapper
         float:left
         .areaBtn
           background:#fff
           border:.02rem solid #ccc
           padding:0rem .75rem
           border-radius:.1rem
           margin-bottom:.1rem
           margin-right:.04rem
     .areaItems
       padding:.1rem
       .areaItem
         height:.42rem
         line-height:.42rem
         padding:.1rem 0rem
</style>

citysearch.vue

<template>
<div>
<div class="searchBg">
<input type="text" placeholder="输入城市名或拼音" class="searchInput" v-model="keyword"/>
</div>
<div class="searchContent" ref="itemWrapper" v-show="keyword">
<ul>
<li class="contentItem border-bottom" v-for="item of list" :key="item.id" @click="changeAreaBtn(item.name)">{{item.name}}</li>
<li class="contentItem border-bottom" v-show="hasNoData">没有找到匹配数据</li>
</ul>
</div>
</div>
</template>

<script>
import BScroll from 'better-scroll'
import {mapMutations} from 'vuex'
export default {
name: 'CitySearch',
props: {
cities: Object
},
data () {
return {
keyword: '',
timer: null,
list: []
}
},
computed: {
hasNoData: function () {
return !this.list.length
   }
},
watch: {
keyword: function () {
if (this.timer) {
clearTimeout()
}
if (!this.keyword) {
this.list = []
return
     }
this.timer = setTimeout(() => {
const result = []
for (let i in this.cities) {
this.cities[i].forEach((value) => {
if (value.name.indexOf(this.keyword) > -1 || value.spell.indexOf(this.keyword) > -1) {
result.push(value)
}
})
}
this.list = result
     }, 100)
}
},
mounted () {
this.scroll = new BScroll(this.$refs.itemWrapper)
},
methods: {
changeAreaBtn (city) {
// this.$store.dispatch('changeArea', city)
     // this.$store.commit('changeRegion',city)
     this.changeRegion(city)
this.$router.push('/')
},
...mapMutations(['changeRegion'])
}
}
</script>

<style lang="stylus" scoped>
@import "~styles/varibles.styl"
.border-bottom
 &:before
   border-color:#ccc
.searchBg
 background:$bgColor
 height:.72rem
 padding:0 .1rem
 .searchInput
   width:100%
line-height:.62rem
   height:.62rem
   border-radius:.06rem
   text-align:center
   padding:0 .1rem
   box-sizing:border-box
.searchContent
 position:absolute
 z-index:1
 left:0
 right:0
 top:1.58rem
 bottom:0
 overflow:hidden
 background:#eee
 .contentItem
     padding:.17rem
     background:#fff
</style>

cityAlph.vue

<template>
<ul class="cityAlph">
<li class="alphItem" v-for="item of letters" :key="item" :ref="item" @click="clickAlph" @touchstart="touchStart" @touchmove="touchMove" @touchend="touchEnd">{{item}}</li>
</ul>
</template>

<script>
export default {
name: 'CityAlph',
props: {
cities: Object
},
data () {
return {
touchState: false,
startY: 0,
timer: null
   }
},
computed: {
letters () {
const letters = []
for (let i in this.cities) {
letters.push(i)
}
return letters
   }
},
updated () {
this.startY = this.$refs['A'][0].offsetTop
 },
methods: {
clickAlph (e) {
this.$emit('change', e.target.innerText)
},
touchStart () {
this.touchState = true
   },
touchMove (e) {
if (this.timer) {
clearTimeout()
}
this.timer = setTimeout(() => {
if (this.touchState) {
const touchY = e.touches[0].clientY - 79
         const index = Math.floor((touchY - this.startY) / 16)
console.log(index)
if (index >= 0 && index < this.letters.length) { this.$emit('change', this.letters[index]) }
}
}, 16)
},
touchEnd () {
this.touchState = false
   }
}
}
</script>

<style lang="stylus" scoped>
@import "~styles/mixFunction.styl"
@import "~styles/varibles.styl"
.cityAlph
 position:absolute
 top:1.58rem
 right:0
 bottom:0
 font-size:.28rem
 width:.4rem
 vertical()
.alphItem
   text-align:center
   padding:.02rem 0
   color:$bgColor
</style>

mixfunction.styl

ellipsis()
overflow:hidden
 white-space:nowrap
 text-overflow:ellipsis
vertical()
display:flex
 flex-direction:column
 justify-content:center

varibles.styl

$bgColor=#00bcd4
$blackText=#333

store-index.js

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

Vue.use(Vuex)

export default new Vuex.Store({
state: state,
actions: {
changeArea (ctx, city) {
ctx.commit('changeRegion', city)
}
},
mutations: mutations
})

state.js

let defaultLocal = '上海'
try {
if (localStorage.city) {
defaultLocal = localStorage.city
}
} catch (e) {}

export default {
city: defaultLocal
}

mutation.js

export default {
changeRegion (state, city) {
state.city = city
try {
localStorage.city = city
} catch (e) {}
}
}


正在回答 回答被采纳积分+1

登陆购买课程后可参与讨论,去登陆

2回答
好帮手慕星星 2021-03-04 18:55:12

同学你好,$route是路由对象,里面有path(路由路径)等属性,详细介绍可以参考文档:

https://router.vuejs.org/zh/api/#%E8%B7%AF%E7%94%B1%E5%AF%B9%E8%B1%A1

老师在测试代码的时候,发现从首页进入city页面后不能滑动,点击右侧的楼梯没有效果。所以建议当监听了路由,当路径改变的时候,刷新了滚动条。

自己可以去掉试试,祝学习愉快!

好帮手慕星星 2021-03-04 12:12:20

同学你好,代码中问题如下:

1、从better-scroll引入方式来看,安装的better-scroll是2版本的,建议修改为课程中的1版本,避免出现问题

http://img1.sycdn.imooc.com//climg/60405d030968634f05430272.jpg

cnpm install --save better-scroll@1.15.2

修改引入方式

http://img1.sycdn.imooc.com//climg/60405d3009d03c9605770062.jpg

2、CityList,CitySearch页面中在实例化BScroll的时候添加允许点击

http://img1.sycdn.imooc.com//climg/60405d530948161c06360129.jpg

3、建议在cityList页面中监听路由改变,然后刷新滚动条

http://img1.sycdn.imooc.com//climg/60405d8809b4d93106800284.jpg

自己再测试下,祝学习愉快!

  • 提问者 慕用7018409 #1

    $router就可以监控路由么,为什么要在路由改变时刷新

    2021-03-04 16:09:01
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师