uni-app实现的搜索功能-可以应用到vue和小程序
目录
uni-app实现的搜索功能 可以应用到vue和小程序
search.vue
<template>
<view class="search" :style="{ backgroundColor: backgroundColor }">
<view class="content" :style="{ 'border-radius': radius + 'px', border: border }">
<view class="content-box" :class="{ center: mode === 2 }">
<text class="icon icon-search"></text>
<input class="input" :class="{ center: !active && mode === 2 }" :focus="isFocus" :placeholder="placeholder" v-model="inputVal" @focus="focus" @blur="blur" />
<!-- <view v-if="!active && mode === 2" class="input sub" @click="getFocus">请输入搜索内容</view> -->
<text v-if="isDelShow" class="icon icon-del" @click="clear"></text>
</view>
<view v-show="(active && show && button === 'inside') || (isDelShow && button === 'inside')" class="searchBtn" @click="search">搜索</view>
</view>
<view v-if="button === 'outside'" class="button" :class="{ active: show || active }" @click="search">
<view class="button-item">{
{ !show ? searchName : '搜索' }}</view>
</view>
</view>
</template>
<script>
export default {
props: {
mode: {
type: Number,
default: 1
},
button: {
type: String,
default: 'outside'
},
show: {
type: Boolean,
default: true
},
radius: {
type: String,
default: '60'
},
placeholder: {
type: String,
default: '请输入搜索内容'
},
backgroundColor: {
type: String,
default: '#fff'
},
border: { type: String, default: '1px #f5f5f5 solid' }
},
data() {
return {
active: false,
inputVal: '',
searchName: '取消',
isDelShow: false,
isFocus: false
};
},
methods: {
focus() {
this.active = true;
},
blur() {
this.isFocus = false;
if (!this.inputVal) {
this.active = false;
}
},
clear() {
this.inputVal = '';
this.active = false;
this.$emit('search', '');
},
getFocus() {
this.isFocus = true;
},
search() {
if (!this.inputVal) return;
console.log(this.inputVal);
this.$emit('search', this.inputVal);
}
},
watch: {
inputVal(newVal) {
if (newVal) {
this.searchName = '搜索';
this.isDelShow = true;
} else {
this.searchName = '取消';
this.isDelShow = false;
}
}
}
};
</script>
<style lang="scss" scoped>
.search {
display: flex;
width: 100%;
border-bottom: 1px #f5f5f5 solid;
box-sizing: border-box;
padding: 15upx;
font-size: $uni-font-size-base;
background: #fff;
.content {
display: flex;
align-items: center;
width: 100%;
height: 60upx;
border: 1px #ccc solid;
background: #fff;
overflow: hidden;
transition: all 0.2s linear;
border-radius: 30px;
.content-box {
width: 100%;
display: flex;
align-items: center;
background-color:#F4F4F4;
&.center {
justify-content: center;
}
.icon {
padding: 0 15upx;
&.icon-del {
font-size: 38upx;
}
}
.input {
width: 100%;
max-width: 100%;
line-height: 60upx;
height: 60upx;
color:#333;
font-size:28upx;
// transition: all 0.2s linear;
&.center {
width: 200upx;
}
&.sub {
// position: absolute;
width: auto;
color: grey;
}
}
}
.searchBtn {
height: 100%;
flex-shrink: 0;
padding: 0 30upx;
background: $uni-color-success;
line-height: 60upx;
color: #fff;
border-left: 1px #ccc solid;
transition: all 0.3s;
}
}
.button {
display: flex;
align-items: center;
justify-content: center;
position: relative;
flex-shrink: 0;
width: 0;
transition: all 0.2s linear;
white-space: nowrap;
overflow: hidden;
&.active {
padding-left: 15upx;
width: 100upx;
color: #8BC34A;
}
}
}
@font-face {
font-family: 'iconfont';
src: url('https://at.alicdn.com/t/font_989023_efq0mtli526.ttf') format('truetype');
}
.icon {
font-family: iconfont;
font-size: 32upx;
font-style: normal;
color: #999;
}
</style>
引用 搜索框
Quotesearch.vue
<template>
<view>
=============================
使用
<mSearch :show="false" @search="search($event, 1)"></mSearch>
==================================
下面是写的一些别的 可以不用看
<view class="hot-search-wrap" v-if="isShowHotKey">
<view class="hot-search"><text class="shugang"></text> <text class="textinfo">热门搜索</text> </view>
<view class="hot-key-wrap">
<view class="hot-key" v-for="(item, index) in mhotKey" :key="index" @tap="search(item, '')">{
{ item }}</view>
</view>
</view>
<view class="wrapper" v-if="jobList">
<view class="job-list-wrap">
<view class="job-list" v-for="(item, index) in jobList" :key="item.id" @tap="goDetailPage(item.id)">
<view class="icon"><image :src="item.thumbimg" mode=""></image></view>
<view class="job-con-wrap">
<view class="job-title">
{
{ item.product_name }}
<image class="hot" :src="item.tag_logo" mode=""></image>
</view>
<view class="job-tip">{
{ item.settlement }} | {
{ item.recruitment }} | {
{ item.sex }}</view>
</view>
<view class="job-rich">
<text class="job-salary">{
{ item.remuneration }}</text>
<text class="job-cen">{
{ item.remuneration_type }}</text>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
//引入进来
import mSearch from '@/components/mehaotian-search/search.vue';
api 是封装了请求数据 不用看
import { api } from '@/common/api.js';
export default {
// 注册子组件
components: {
mSearch
},
data() {
return {
keyword: '',
jobList: '',
mhotKey: ['服务员', '客服', '销售', '在线直播','提成','校园代理','家教','餐饮','促销','派单','日结','分拣打包'],
isShowHotKey: true
};
},
methods: {
search(e, val) {
// console.log(e, val);
// this['val'+val] = e;
if (e == '') {
uni.showToast({
title: '请输入关键词',
icon: 'none',
duration: 2000
});
return;
}
this.getJoblist(1, 20, e).then(rs => {
let [err, res] = rs;
let { code, data } = res.data;
if (code == 1001) {
this.jobList = data;
this.isShowHotKey = false;
} else {
uni.showToast({
title: '换一个关键词试试吧',
icon: 'none',
duration: 2000
});
}
});
},
goDetailPage(key) {
uni.navigateTo({
url: '/pages/select/detail?id=' + key
});
},
getJoblist(_page = 1, _limit = 10, _keyword) {
接口换成自己的
return api.post('https://job.liaotaba.com/api/product/dataList', {
page: _page,
limit: _limit,
product_type: this.pid,
keyword: _keyword,
token: uni.getStorageSync('token') ? uni.getStorageSync('token') : '',
uid: uni.getStorageSync('uid') ? uni.getStorageSync('uid') : '',
type: '',
is_selected: '',
is_hot: '',
is_tuijian: ''
});
}
}
};
</script>
<style lang="scss">
.hot-search-wrap {
padding: 20upx;
.hot-search {
font-size: 32upx;
font-weight: 500;
color: #333;
padding:10upx;
overflow: hidden;
position:relative;
.shugang{
display: inline-block;
width: 6upx;
height: 30upx;
background-color: #89C756;
position: absolute;
top: 18upx;
left: 30upx;
}
.textinfo{
display: inline-block;
width: 200upx;
height: 34upx;
margin-left: 40upx;
color: #333333;
font-weight: 600;
}
}
.hot-key-wrap {
overflow: hidden;
margin-top: 20upx;
.hot-key {
float: left;
margin-right: 20upx;
padding: 14upx 40upx;
margin-bottom: 30upx;
background: #f4f4f4;
font-size: 28upx;
border-radius: 10upx;
color: #898989;
font-weight: 600;
}
}
}
.wrapper {
padding: 10upx 30upx 0;
}
.job-list-wrap {
overflow: hidden;
.job-list {
overflow: hidden;
border-bottom: 2upx solid #d7d7d7;
padding: 30upx 0 32upx;
.icon {
float: left;
width: 56upx;
height: 56upx;
image {
width: 56upx;
height: 56upx;
}
}
.job-con-wrap {
float: left;
margin-left: 19upx;
width: 424upx;
font-size: 30upx;
.job-title {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
color: #333333;
font-size: 35upx;
font-weight: 600;
.hot {
width: 60upx;
height: 30upx;
margin-left: 20upx;
}
}
.job-tip {
margin-top: 22upx;
font-size: 24upx;
color: #868686;
clear: both;
}
}
.job-rich {
float: left;
width: 190upx;
text-align: right;
font-size: 36upx;
font-weight:600;
color:rgba(229,28,35,1);
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
margin-top: 30upx;
.job-salary {
font-size:36upx;
font-family:PingFangSC;
font-weight:600;
color:rgba(229,28,35,1);
text-align: right;
}
.job-cen{
font-size:28upx;
font-family:PingFangSC;
font-weight:400;
color:rgba(229,28,35,1);
text-align: right;
}
}
}
}
</style>