文章目录
- 为input框绑定v-model双向数据绑定
- 增加样式,引入better-scroll插件可上下滑动
- 解决input框里没内容,列表还在的情况
- 搜索结果问题
- 输入框没值时不显示,有值才显示
- 优化代码,计算属性,尽量不要在模板里有过多的逻辑
为input框绑定v-model双向数据绑定
去父组件City.vue中父传子,把cityies传给子组件Search.vue,子组件进行接收数据
监听keyWord,由于这部分经常用到,为了节约性能,用到函数节流,先在data中增加timer:null
初步效果如下,可以搜索出来了,哈哈哈哈:
增加样式,引入better-scroll插件可上下滑动
然后修改下样式,更美观些,这时输入文字或字母搜索出来了,但是搜索的内容多的时候,不能向下滑动滑动看更多,这里需要引入better-scroll插件,获取dom
search.vue
<template>
<div>
<div class="search">
<input
class="search-input"
type="text"
placeholder="输入城市名或拼音"
v-model="keyWord"
/>
</div>
<div class="search-content" ref="search">
<ul>
<li
class="search-item border-bottom"
v-for="item in list"
:key="item.id"
>
{{ item.name }}
</li>
</ul>
</div>
</div>
</template>
<script>
import BScroll from 'better-scroll'
export default {
name: 'CitySearch',
props: {
cities: Object
},
data () {
return {
keyWord: '',
list: [],
timer: null
}
},
// 监听keyword
// 这里用到函数节流,因为这里用的频率比较高,节约性能
watch: {
keyWord () {
if (this.timer) {
clearTimeout(this.timer)
}
this.timer = setTimeout(() => {
const result = []
// 循环从父组件接收cities里面的内容
for (let i in this.cities) {
// 把cities里面的A、B、C等等键值对里面的值再给遍历一遍
this.cities[i].forEach(value => {
// 如果从spell,name中能搜索到这个关键词,就把这一项添加到result中
if (
value.spell.indexOf(this.keyWord) > -1 ||
value.name.indexOf(this.keyWord) > -1
) {
result.push(value)
}
})
}
// 把result结果赋值给list数组,在上面的li中循环list数组
this.list = result
}, 100)
}
},
// 列表解决不滑动
updated () {
this.scroll = new BScroll(this.$refs.search)
}
}
</script>
<style lang="scss" scoped>
@import '~styles/varibles.scss';
.search {
background: $bgColor;
height: 0.72rem;
padding: 0.1rem;
padding: 0 0.2rem;
.search-input {
width: 100%;
height: 0.62rem;
line-height: 0.62rem;
text-align: center;
background: #fff;
border-radius: 0.06rem;
color: #666;
}
}
.search-content {
overflow: hidden;
position: absolute;
top: 1.58rem;
left: 0;
right: 0;
bottom: 0;
background: #eee;
z-index: 1;
.search-item {
line-height: 0.62rem;
padding-left: 0.2rem;
color: #666;
background: #fff;
}
}
</style>
解决input框里没内容,列表还在的情况
搜索结果问题
在模板里加上一个li标签
需要一个判断,因为使用频率高这里用v-show
,如果list列表没有数据的话,就需要显示没有找到匹配数据
输入框没值时不显示,有值才显示
整体代码如下
<template>
<div>
<div class="search">
<input
class="search-input"
type="text"
placeholder="输入城市名或拼音"
v-model="keyWord"
/>
</div>
<!-- 有值时才显示 -->
<div class="search-content" ref="search" v-show="keyWord">
<ul>
<li
class="search-item border-bottom"
v-for="item in list"
:key="item.id"
>
{{ item.name }}
</li>
<li class="search-item border-bottom" v-show="!this.list.length">没有找到匹配数据</li>
</ul>
</div>
</div>
</template>
<script>
import BScroll from 'better-scroll'
export default {
name: 'CitySearch',
props: {
cities: Object
},
data() {
return {
keyWord: '',
list: [],
timer: null
}
},
// 监听keyword
// 这里用到函数节流,因为这里用的频率比较高,节约性能
watch: {
keyWord() {
if (this.timer) {
clearTimeout(this.timer)
}
//如果input框没有输入内容,那就设置this.list为空数组
if (!this.keyWord) {
this.list = []
return
}
this.timer = setTimeout(() => {
const result = []
// 循环从父组件接收cities里面的内容
for (let i in this.cities) {
// 把cities里面的A、B、C等等键值对里面的值再给遍历一遍
this.cities[i].forEach(value => {
// 如果从spell,name中能搜索到这个关键词,就把这一项添加到result中
if (
value.spell.indexOf(this.keyWord) > -1 ||
value.name.indexOf(this.keyWord) > -1
) {
result.push(value)
}
})
}
// 把result结果赋值给list数组,在上面的li中循环list数组
this.list = result
}, 100)
}
},
// 列表解决不滑动
updated() {
this.scroll = new BScroll(this.$refs.search)
}
}
</script>
<style lang="scss" scoped>
@import '~styles/varibles.scss';
.search {
background: $bgColor;
height: 0.72rem;
padding: 0.1rem;
padding: 0 0.2rem;
.search-input {
width: 100%;
height: 0.62rem;
line-height: 0.62rem;
text-align: center;
background: #fff;
border-radius: 0.06rem;
color: #666;
}
}
.search-content {
overflow: hidden;
position: absolute;
top: 1.58rem;
left: 0;
right: 0;
bottom: 0;
background: #eee;
z-index: 1;
.search-item {
line-height: 0.62rem;
padding-left: 0.2rem;
color: #666;
background: #fff;
}
}
</style>
优化代码,计算属性,尽量不要在模板里有过多的逻辑
<template>
<div>
<div class="search">
<input
class="search-input"
type="text"
placeholder="输入城市名或拼音"
v-model="keyWord"
/>
</div>
<!-- 有值时才显示 -->
<div class="search-content" ref="search" v-show="keyWord">
<ul>
<li
class="search-item border-bottom"
v-for="item in list"
:key="item.id"
>
{{ item.name }}
</li>
<li class="search-item border-bottom" v-show="hasNoData">没有找到匹配数据</li>
</ul>
</div>
</div>
</template>
<script>
import BScroll from 'better-scroll'
export default {
name: 'CitySearch',
props: {
cities: Object
},
data () {
return {
keyWord: '',
list: [],
timer: null
}
},
computed: {
hasNoData () {
return !this.list.length
}
},
// 监听keyword
// 这里用到函数节流,因为这里用的频率比较高,节约性能
watch: {
keyWord () {
if (this.timer) {
clearTimeout(this.timer)
}
// 如果input框没有输入内容,那就设置this.list为空数组
if (!this.keyWord) {
this.list = []
return
}
this.timer = setTimeout(() => {
const result = []
// 循环从父组件接收cities里面的内容
for (let i in this.cities) {
// 把cities里面的A、B、C等等键值对里面的值再给遍历一遍
this.cities[i].forEach(value => {
// 如果从spell,name中能搜索到这个关键词,就把这一项添加到result中
if (
value.spell.indexOf(this.keyWord) > -1 ||
value.name.indexOf(this.keyWord) > -1
) {
result.push(value)
}
})
}
// 把result结果赋值给list数组,在上面的li中循环list数组
this.list = result
}, 100)
}
},
// 列表解决不滑动
updated () {
this.scroll = new BScroll(this.$refs.search)
}
}
</script>
<style lang="scss" scoped>
@import '~styles/varibles.scss';
.search {
background: $bgColor;
height: 0.72rem;
padding: 0.1rem;
padding: 0 0.2rem;
.search-input {
width: 100%;
height: 0.62rem;
line-height: 0.62rem;
text-align: center;
background: #fff;
border-radius: 0.06rem;
color: #666;
}
}
.search-content {
overflow: hidden;
position: absolute;
top: 1.58rem;
left: 0;
right: 0;
bottom: 0;
background: #eee;
z-index: 1;
.search-item {
line-height: 0.62rem;
padding-left: 0.2rem;
color: #666;
background: #fff;
}
}
</style>