Article Directory
-
- Binding v-model two-way data binding for the input box
- Increase style, introduce better-scroll plugin to slide up and down
- Solve the situation where there is no content in the input box and the list is still there
- Search results problem
- When the input box has no value, it will not be displayed, and it will be displayed
- Optimize code, calculate attributes, try not to have too much logic in the template
Binding v-model two-way data binding for the input box
Go to the parent component City.vue to pass from parent to child, and pass cityies to the child component Search.vue. The child component receives data and
monitors the keyWord. Because this part is often used, in order to save performance, use function throttling, first in data The
initial effect of adding timer: null is as follows, and it can be searched out, hahahaha:
Increase style, introduce better-scroll plugin to slide up and down
Then modify the style to make it more beautiful. At this time, input text or letters to search out, but when there is a lot of search content, you can’t slide down to see more. Here you need to introduce a better-scroll plug-in to get 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>
Solve the situation where there is no content in the input box and the list is still there
Search results problem
Adding a li tag
to the template requires a judgment because it is used here because of the high frequency of use v-show
. If there is no data in the list list, it needs to show that no matching data is found
When the input box has no value, it will not be displayed, and it will be displayed
The overall code is as follows
<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>
Optimize code, calculate attributes, try not to have too much logic in the template
<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>