简单的微信小程序搜索界面(Django)(左侧条件导航栏,搜索框,历史记录)
首先看一下效果图:
huodong.wxml(代码的解释都写在里面):
<!--搜索框 默认值(placeholder)为name(js中声明的变量),并且绑定三种方法,分别为当输入时的方法( bindinput),输入完回车后的方法(bindconfirm),鼠标焦点在搜索框时的方法(bindfocus),以及失去焦点时的方法(bindblur)-->
<view class="search">
<input type="text" placeholder="{{name}}" value="{{name}}" bindinput="bindinput" bindconfirm="bindconfirm" bindfocus="bindfocus" bindblur="bindblur"></input>
<image src="../../image/search.svg"></image>
</view>
<!--历史记录 首先让整个view默认为隐藏的,当鼠标聚焦在搜索框时才显示(有历史记录时),将sercherStorage中的数据循环出来。 最后就是清除历史记录点击的方法(clearSearchStorage)-->
<view hidden="{{hiddenn}}">
<view wx:for="{{sercherStorage}}" wx:key="item.id">
<view class="liclass" style="color:#9E9E9E;border-bottom:0;font-size:26rpx;" id="{{item.id}}">
<text style="width:100rpx">{{item.name}}</text>
</view>
</view>
<view wx:if="{{sercherStorage.length!==0}}" style="text-align:center;" bindtap="clearSearchStorage">
<view class="history-span">清除历史记录</view>
</view>
</view>
<!--左侧 在js设置变量flag初始值为0,默认选中所有类型。 设置选中时与未被选中时的样式,使用三目运算符,当flag等于该id时,使用select所对应的样式,否则使用normal。 同时为每个类型添加点击的方法(switchNav)-->
<view class="content">
<view class='left'>
<view class="{{flag==0?'select':'normal'}}" id='0' bindtap='switchNav'>所有类型</view>
<view class="{{flag==1?'select':'normal'}}" id='1' bindtap='switchNav'>体育</view>
<view class="{{flag==2?'select':'normal'}}" id='2' bindtap='switchNav'>专业比赛</view>
<view class="{{flag==3?'select':'normal'}}" id='3' bindtap='switchNav'>志愿者服务</view>
<view class="{{flag==4?'select':'normal'}}" id='4' bindtap='switchNav'>文艺表演</view>
</view>
<!--右侧显示的活动的部分,使用swiper滑动容器,设置current属性(表示当前所在的滑块的id)等于js中定义的currentTab表示当前的id。swiper默认是水平滑动,如果想纵向滑动可使用vertical="{{true}}。 -->
<view class='right'>
<view class='category'>
<swiper current='{{currentTab}}' style='height:500px' vertical="{{true}}">
<!--表示第一个组件,如果current等于0时,则显示当前这个组件,并且拿到后台数据进行循环-->
<swiper-item id='0'>
<block wx:for="{{list}}">
<view class="list-item">
<view class="list-item-images">
<navigator url="/pages/detail/detail?id={{item.id}}">
<image src="{{item.url}}" class="list-item-images-img"></image>
</navigator>
</view>
<view class="list-item-text">
<view class="list-item-text-content">
<text>{{item.text}}</text>
</view>
</view>
</view>
</block>
</swiper-item>
<!--第二个组件,currentTab=1时显示。此处添加了判断条件,如果是体育类的才进行显示-->
<swiper-item id='1'>
<block wx:for="{{list}}">
<view class="list-item" wx:if="{{item.type=='体育'}}">
<view class="list-item-images">
<navigator url="/pages/detail/detail?id={{item.id}}">
<image src="{{item.url}}" class="list-item-images-img"></image>
</navigator> </view>
<view class="list-item-text">
<view class="list-item-text-content">
<text>{{item.text}}</text>
</view>
</view>
</view>
</block>
</swiper-item>
<!--第三个组件,currentTab=2时显示。此处添加了判断条件,如果是专业比赛类的才进行显示-->
<swiper-item id='2'>
<block wx:for="{{list}}">
<view class="list-item" wx:if="{{item.type=='专业比赛'}}">
<view class="list-item-images">
<navigator url="/pages/detail/detail?id={{item.id}}">
<image src="{{item.url}}" class="list-item-images-img"></image>
</navigator>
</view>
<view class="list-item-text">
<view class="list-item-text-content">
<text>{{item.text}}</text>
</view>
</view>
</view>
</block>
</swiper-item>
<!--第四个组件,currentTab=3时显示。此处添加了判断条件,如果是志愿服务类的才进行显示-->
<swiper-item id='3'>
<block wx:for="{{list}}">
<view class="list-item" wx:if="{{item.type=='志愿者服务'}}">
<view class="list-item-images">
<navigator url="/pages/detail/detail?id={{item.id}}">
<image src="{{item.url}}" class="list-item-images-img"></image>
</navigator>
</view>
<view class="list-item-text">
<view class="list-item-text-content">
<text>{{item.text}}</text>
</view>
</view>
</view>
</block>
</swiper-item>
<!--第五个组件,currentTab=5时显示。此处添加了判断条件,如果是文艺表演类的才进行显示-->
<swiper-item id='4'>
<block wx:for="{{list}}">
<view class="list-item" wx:if="{{item.type=='文艺表演'}}">
<view class="list-item-images">
<navigator url="/pages/detail/detail?id={{item.id}}">
<image src="{{item.url}}" class="list-item-images-img"></image>
</navigator>
</view>
<view class="list-item-text">
<view class="list-item-text-content">
<text>{{item.text}}</text>
</view>
</view>
</view>
</block>
</swiper-item>
</swiper>
</view>
</view>
</view>
huodong.js
Page({
data: {
flag: 0,
currentTab: 0,
name: "",
inputVal: "",
list: {},
sercherStorage: [],
hiddenn: true,
},
//switchNav方法,当点击不同类别时触发,该方法中,首先拿到点击类别的id,并且与当前的currentTab做比较,如果是相同时则不做任何的处理,直接退出方法(因为当前已经是选中这个类别了),如果不相等,则让currentTab等于我们选中的id,并且让flag也等于这个id(用于切换样式)
switchNav: function(e) {
var page = this;
var id = e.target.id;
if (this.data.currentTab == id) {
return false;
} else {
page.setData({
currentTab: id
});
}
page.setData({
flag: id
});
},
//加载当前页面时的操作,首先调用openLocationsercher()方法(打开历史记录列表,具体实现到该方法中看),进行网络数据的请求(此处用的是django当后台数据交互),将请求返回得到的值放到list中,到页面中进行循环
onLoad: function(options) {
this.openLocationsercher();
wx.request({
url: "http://127.0.0.1:8000/news/testi/",
success: res => {
console.log(res.data)
this.setData({
list: res.data
})
}
})
},
//当输入框有输入东西时进行的操作,如果想要输入一个字,并且不回车就可以更新下面的活动,可以将bindconfirm中的方法复制到这里赖
bindinput(e) {
this.setData({
inputVal: e.detail.value,
})
},
//输入框按回车后触发,让inputVal等于输入的值,并且发起请求,将inputVal的值传过去,得到的结果再放到list集合中
bindconfirm(e) {
this.setData({
inputVal: e.detail.value
})
wx.request({
url: "http://127.0.0.1:8000/news/findActivity/?text=" + this.data.inputVal,
success: res => {
console.log(res.data)
this.setData({
list: res.data
})
}
})
//控制搜索历史 如果搜索框输入的值不为空,将该值更新到缓存中,并且再次调用openLocationsercher()方法打开历史记录
if (this.data.inputVal != '') {
//将搜索记录更新到缓存
var searchData = this.data.sercherStorage;
searchData.push({
id: searchData.length,
name: this.data.inputVal
})
wx.setStorageSync('searchData', searchData);
this.setData({
StorageFlag: false,
})
}
this.openLocationsercher();
},
//清除历史记录 当点击清除历史记录时触发
clearSearchStorage: function() {
wx.removeStorageSync('searchData')
this.setData({
sercherStorage: [],
})
},
//打开历史记录列表,并将缓存中历史搜索的值放到sercherStorage中
openLocationsercher: function() {
this.setData({
sercherStorage: wx.getStorageSync('searchData') || [],
listFlag: true,
})
},
//当鼠标聚焦在搜索框上时,让历史记录显示出来,将hiddenn设置为false,取消隐藏
bindfocus(e) {
this.setData({
hiddenn: false
})
},
//当数据在搜索框上失去焦点时,让历史记录进行隐藏,将hiddenn设置为true,进行隐藏
bindblur(e) {
this.setData({
hiddenn: true
})
},
//点击左上角返回的页面
onUnload: function() {
wx.reLaunch({
url: '/pages/index/index'
}) },
})
huodong.wxss
.content {
display: flex;
flex-direction: row;
font-family: "Microsoft YaHei"
}
.left {
width: 30%;
font-size: 10px;
height: 500px;
background-color: #F4F4F4;
}
.left view {
text-align: center;
height: 45px;
line-height: 45px;
}
.select {
background-color: #ffffff;
border-left: 2px solid #36AE66;
font-weight: bold;
color: #36AE66;
}
.normal {
background-color: #F4F4F4;
border-bottom: 1px solid #f2f2f2;
}
.right {
width: 70%;
margin: 0px;
}
.list-item{
height: 100px;
width: 100px;
margin-top: 10px;
margin-left: 10px;
float: left;
}
.list-item-images{
height: 80px;
width: 100px;
position: relative;
}
.list-item-images-img{
height: 80px;
width: 100px;
}
.list-item-text{
height: 40px;
width: 100%;
margin-top: 20rpx; text-align: center;
}
.list-item-text-content{
font-size: 10px;
color: #999;
text-align: center;
}
.avator{
height: 120rpx;
width: 120rpx;
border-radius: 50%;
position: absolute;
right: 70rpx;
bottom: -50rpx;
}
.search {
margin-top: 32rpx;
position: relative;
width: 650rpx;
height: 66rpx;
padding-left: 30rpx;
}
.search input {
border: 1rpx solid #e3e3e3;
width: 650rpx;
height: 66rpx;
border-radius: 30rpx;
padding-left: 32rpx;
}
.search image {
width: 35rpx;
height: 35rpx;
position: absolute;
top: 16rpx;
right: 32rpx;
}
.ddclass {
position: absolute;
width: 100%;
margin-top: 10px;
left: 0;
}
.liclass {
font-size: 14px;
line-height: 34px;
color: #575757;
height: 34px;
display: block;
padding-left: 18px;
background-color: #fff;
border-bottom: 1px solid #dbdbdb; }
django代码
目录结构:(可以创建并注册一个新的app,或者不用也可以,但要注意自己配好路径)
views.py(自己创建的news app中)
#获取全部活动 url:http://127.0.0.1:8000/news/testi/
def test_api(request):
conn = pymysql.connect(host='localhost', port=3306, user='root', passwd='123456', db='django', charset='utf8')
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
cursor.execute("select * from api_api2")
list = cursor.fetchall()
cursor.close()
conn.close()
return HttpResponse(json.dumps(list,ensure_ascii=False),content_type="application/json , charset=utf-8")~
#当搜索框输入值时,调用改方法,拿到小程序传过来的值text
#url:"http://127.0.0.1:8000/news/findActivity/?text=" + this.data.inputVal
def findActivity(request):
text=request.GET.get('text')
conn = pymysql.connect(host='localhost', port=3306, user='root', passwd='123456', db='django', charset='utf8')
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
cursor.execute("select * from api_api2 where text like '%"+text+"%'")
list = cursor.fetchall()
cursor.close()
conn.close()
return HttpResponse(json.dumps(list,ensure_ascii=False),content_type="application/json , charset=utf-8")~
urls.py (自己创建的news app中)
from django.contrib import admin
from django.urls import path
from . import views
from django.conf.urls import handler404
urlpatterns = [
path('findActivity/',views.findActivity,name='findActivity'),
path('testi/',views.test_api)
]
urls.py(对新的app访问路径的配置)
from django.contrib import admin
from django.urls import path,include
from news import views
from django.conf.urls import url
from mywebsite import settings
from django.views.static import serve
urlpatterns = [
path('news/', include('news.urls')),
path('admin/',admin.site.urls)
]
数据表的设计(随便加了些值测试)