兄弟间传值这个案例就是Alphabet向list组件进行传值 这两个都是兄弟
要实现的效果就是在绑定了 better-scroll的list组件点击右侧的字母展示相应的区域
1.首先先在Alphabet li标签里面绑定一个 点击事件 @click="handleLetterClick"这样就能检测到数据的改变
然后向外触发
methods: {
handleLetterClick (a) { //点击城市列表的字母让其显示在相应的页面上
//向外触发change事件 (就是子组件向父组件进行传值)并且携带一个内容
this.$emit('change',a.target.innerText) //target 事件属性可返回事件的目标节点(触发该事件的节点),如生成事件的元素、文档或窗口。
//console.log(a.target.innerText); 因为绑定了点击事件 所以点击a.target.innerText就会显示相应的字母
}
}
2.父亲组件进行监听Alphabet触发的数据 @change="handleLetterChange"
methods: {
handleLetterChange (letter) { //儿子传递过来的 然后在传递给list 就是点击了字母会显示相应的字母的
this.letter = letter;
}
}
data () {
return {
letter:'' //默认值为空
}
}
最后绑定到 <city-list :letter="letter"></city-list> 组件里面
3.list接收父亲组件传递下来的组件 并且采用监听事件 监听传递过来的数据是否发生改变
props: {
letter:String ; //必须是String
}
然后监听事件 显示出相应的区域
因为better-scroll是根据dom来进行的 所以要在要显示的 区域加上 :ref="key"
watch: { //监听兄弟组件传递过来的数据是否改变
letter () {
//better-scroll提供了这样的接口
if (this.letter) { //如果letter不为空
const element = this.$refs[this.letter][0] //获取得到字母对应指定的区域 better-scroll必须是dom元素
this.scroll.scrollToElement(element) //滚动到指定的元素上面
}
}
}
5.better-scroll的点击滑动
<template>
<div class="div1">
<ul class="list">
@touchstart="handleTouchStart"
@touchmove="handleTouchMove"
@touchend="handleTouchEnd"
>
</li>
</ul>
</div>
</template>
<script>
export default {
name: 'CityAlphabet',
props: {
city:Object,
},
data() {
return {
touchStatus:false, //增加一个标识位
timer: null,
}
},
methods: {
handleTouchStart () {
this.touchStatus = true
},
handleTouchMove (e) { //不理解
if (this.touchStatus) {
if (this.timer) {
clearTimeout(this.timer)
}
this.timer = setTimeout ( () => {
const startY = this.$refs['A'][0].offsetTop
const touchY = e.touches[0].clientY - 88;
const index = Math.floor ((touchY-startY)/20)
//就是滑动的距离减去 第一个字母到顶部的距离 然后在减去自身的高度
if (index >= 0 && index < this.letters.length) {
this.$emit('change',this.letters[index])
}
},16)
}
},
handleTouchEnd () {
this.touchStatus = false;
},
}
}
</script>
搜索功能的实现
搜索功能的实现就是把根据拼音或者汉字,把这些相应的城市名称,拼接到相应的列表里面
<template>
<div>
<div
class="search-content"
ref="search"
v-show="keyword"
> <!--keyword有值的时候就会显示 没值的时候就会隐藏 搜索的展示的界面-->
<ul>
<li class="search-item" v-for="item of list" :key="item.id"
>{{item.name}}</li>
<li class="search-item" v-show="hasNoData">没有找到匹配数据</li>
</ul>
</div>
</div>
</template>
<script>
//引入better-scroll
import Bscroll from 'better-scroll'
export default {
name:'CitySearch',
props: {
cities: Object //接收传递过来的数据
},
mounted () {
this.scroll = new Bscroll(this.$refs.search) //根据dom元素 使用better-scroll就能正常的滚动了
},
data () {
return {
keyword: '', //让input框的内容与data里面的数据做双向绑定
list:[], //定义一个空数组 用来存放搜索到的数据列表
timer:null
}
},
computed: { //尽量避免在模板页面里面进行逻辑运算
hasNoData () {
return !this.list.length //如果长度为0的话 让 没有找到匹配数据 进行展示
}
},
watch: {
keyword () { //节流函数 提高效率
if (this.timer) {
clearTimeout(this.timer)
}
this.timer = setTimeout (() => { //是从city传递下来的 所以根据keymodel的关键字进行显示的
const result = []
for (let i in this.cities) { //对这个对象进行遍历 里面还包含数组
this.cities[i].forEach((value) => { //在对A数组里面进行遍历
if (value.spell.indexOf(this.keyword) > -1 || //根据字母进行显示
value.name.indexOf(this.keyword) > -1) { //根据中文进行显示的
result.push(value) //如果能搜素到相应的字母则把他们添加到相应的列表当中
}
})
}
this.list = result //将得到的数据放入list数组里面就好了
},100)
//如果keyword不存在的话 就设置为空数组 列表就设置为空了
if (!this.keyword) {
this.list = []
return
}
}
}
}
</script>