記事のディレクトリ
入力ボックスのvモデル双方向データバインディングのバインディング
親コンポーネントCity.vueに移動して親から子に渡し、cityiesを子コンポーネントSearch.vueに渡します。子コンポーネントはデータを受信
してキーワードを監視します。この部分は頻繁に使用されるため、パフォーマンスを節約するために、関数スロットリング、データの
最初タイマーを追加した場合の最初の効果:nullは次のとおりで、検索できます、hahahaha:
スタイルを増やし、より良いスクロールプラグインを導入して上下にスライドさせる
次に、スタイルを変更してより美しくします。このとき、テキストまたは文字を入力して検索しますが、検索コンテンツが多い場合は、下にスライドして詳細を表示することはできません。ここでは、より適切なものを紹介する必要があります。プラグインをスクロールして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>
入力ボックスにコンテンツがなく、リストがまだある状況を解決します
検索結果の問題
テンプレートにliタグ
を追加すると、使用頻度が高いためここで使用されるため、判断が必要v-show
です。リストリストにデータがない場合は、一致するデータが見つからないことを示す必要があります。
入力ボックスに値がない場合は表示されませんが、値がある場合にのみ表示されます。
全体的なコードは次のとおりです
<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>