在写小程序之前的必备准备:
1.可以在app.wxss中写页面的全局样式,每个页面都共享这个。
app.wxss:
page {
height: 100vh;
background-color: rgb(245,249,253);
}
画面功能分析1:
当时间在半夜或水果在某一季节,我们要使页面呈现为"打烊了"如:
<view class="offline" wx:if="{{offline}}" >
打烊了
</view>
在homepage.js中声明offline:false,在offline为true时,将"打烊了"显示在中间,homepage.wxss如下:
.offline {
height:100%;
width: 750rpx;/* iphone*/
background:white;
text-align: center;
line-height: 1200rpx;
}
rpx是相对的,750rpx在任何手机都是占满整个屏幕,在iphone
画面功能分析2:
搜索、swiper、列表。利用组件化的思想进行实现功能,
<view class="myHomePage"
wx:if="{{isShow&&!offline}}">
<!-- 搜索框 -->
<my-search></my-search>
<!-- 轮播图 -->
<view class="swiper-container">
<index-swiper imgUrls="{{imgUrls}}"></index-swiper>
</view>
</view>
,都是封装好了的组件,在components下建立一个文件夹search,再在search下建立一个component文件。会生成这些东西
在像写page中的一样写search功能就可以了。在homepage.json
中进行声明:
{
"navigationBarTitleText": "廖师傅的水果店",
"usingComponents": {
"my-search": "/components/search/search",
"index-swiper": "/components/swiper/swiper"
}
}
index-swiper实现轮播图,同样如此。homepage.js中的data:{imgUrls:}中imgUrls向组件swiper.js中进行传值,那么只要在swiper.js的properties中加上:
properties: {
imgUrls: Object
},
为何使用组件:
大项目页面比较长,用组件封装出去,没有那么长,提高复用性。
application <- page <- components <- 原子的组标,
组件有data 和propertoty的概念,
page老板 component 打工人 , property属性 data。
画面功能分析3:
tab切换?
1. 设置数据 tab状态相关 activeTypeId
2. 多个type 放到数据typeCat里
activeTypeId: 0,
typeCat: [ /** 类型的数据配置 */
{ id: 0, name:"美味鲜果", },
{ id: 1, name: "今日特惠" },
{ id: 2, name: "新鲜上架" },
{ id: 3, name: "店主推荐" }
]
<!-- 分类展示 -->
<view class="type-container">
<view class="type-item" wx:for="{{typeCat}}" wx:key="id" >
<view data-id="{{item.id}}"
class="type-name {{activeTypeId === item.id? 'type-item-on':''}}"
bindtap="typeSwitch" > {{item.name}}
</view>
</view>
</view>
data-id="{{item.id}}" 将for循环中typeCat的id进行绑定到data-id,可以在typeSwith函数中进行
this.setData({
activeTypeId: e.currentTarget.dataset.id
})
获取item.id的值用e.currentTarget.dataset.id,将activeTypeId的值改为我们用鼠标进行切换的四个按钮的id。
class="type-name {{activeTypeId === item.id? 'type-item-on':''}}",默认调用.typename,
如果activeTypeId === item.id则调用.type-item-on的css样式。主要是点击tab实现高亮!
然后进行显示即可。
switch(e.currentTarget.dataset.id) {
//美味新品
case 0:
app.getInfoByOrder('fruit-board', 'time', 'desc', e => {
this.setData({ fruitInfo: e.data })
wx.hideLoading(); }) break;
// 今日特惠
case 1: app.getInfoWhere('fruit-board', {myClass:'1'}, e => {
this.setData({ fruitInfo: e.data }) })
wx.hideLoading(); break;
//新鲜上架
case 2: app .getInfoByOrder('fruit-board', 'time', 'desc', e => {
this.setData({ fruitInfo: e.data }) })
wx.hideLoading(); break;
// 店主推荐
case 3: app.getInfoWhere('fruit-board', { recommend: '1'}, e => {
this.setData({ fruitInfo: e.data }) })
wx.hideLoading(); break; }
其中getInfoByOrder,getInfoWhere是在app.js中进行全局声明的类似的mysql查询云数据库的函数。
getInfoByOrder(setName, ruleItem, orderFunc, callback) {
const db = wx.cloud.database();
db.collection(setName)
// 边接数据表 mongodb 没有严格的字段 tmpPictures json文档document mysql 关系型 mongodb 文档型
.orderBy(ruleItem, orderFunc)
.get() // promise
.then(callback) // 回到页面去
.catch(console.error) // 容错处理
},
getInfoWhere(setName,ruleObj,callback){
const db = wx.cloud.database();
db
.collection(setName)
.where(ruleObj) // 条件
.get({
success: callback,
fail: console.err
})
},
封装云开发数据操作的能力
1. app.js 是天然的公用js 方法的地方
const app = getApp(); // 微信的定义,全局方法, app.js 定义的全局方法
app.get
2. 抽象了某个表某种排序方式,得到结果后做某种操作
高效
全局的列表查询方法 ,全局共享
setName 表名
ruleItem 条件 time
orderFunc 排列方式 升序 ASC 降序 DSEC
生命周期函数onLoad、onReady和onShow的用法:
onReady: function () {
ready 在show 后面? js 跟页面交互了
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
数据请求 云端请求数据 比较早, 放
到ready 晚了, 花时间, 尽量提前,
onLoad 正在加载 加载且计算渲染页面, 线程
如果又再启动下载进程的话 可能就会卡到
封装所有的请求为一个方法
// app 当前应用
app.getInfoByOrder('fruit-board', 'time', 'desc', e => {
this.setData({
fruitInfo: e.data,
isShow:true
})
wx.hideLoading();
})
},
云数据库设计
云数据库是一种NoSQL数据库。每一张表是一个集合。值得注意的是在设计数据库时,_id 和_fruitId这两个字段需要带上。_id是表的主键,而_openid是不同商品标识,每个商品都有不同的_fruitId,可区分不同商品。
建立一个fruit-board表例如:
要想在代码中使用数据库则要:将权限该成这个
画面功能分析4:
点击不同按钮出现不同的列表。如:
<view class="fruit-container">
<block wx:for="{{fruitInfo}}" wx:key="fruitId">
<view class="fruit-item" bindtap="tapToDetail"
data-fid="{{item._id}}" wx:if="{{item.onShow}}">
<view class="fruit-image">
<image src="{{item.imgUrl}}" mode="aspectFill"/>
</view>
<view class="fruit-info">
<view class="line1">
<text class="name">{{item.name}}</text>
</view>
<view class="line2">
<view class="price">
<text>${{item.price}}</text>
<text class="unit">{{item.unit}}</text>
</view>
<image src="../../images/icon/cart4.png" mode="aspectFit"
catchtap="addCartByHome" data-fid="{{item._id}}" />
</view>
</view>
</view>
</block>
</view>
其中的fruitInfo是利用.js中的
this.setData({
fruitInfo: e.data
})
将“美味鲜果”“今日特惠”“新鲜上架”“店家推荐”中不同的数据收纳到fruitInfo中,然后通过wx:for进行循环输出。
中mode有四个值可自由观看:blog.csdn.net/weixin\_337…
catchtap="addCartByHome",这个是一个捕获事件,由于js有冒泡机制,当点击了image时,会同时触发bindtap="tapToDetail",从而跳转到详情页,但我们并不要它出发,所以用了catchtap。
wxss难以想到的点子:
1.页面宽度为750rpx,有三个盒子为375rpx,但是全显示在一行,如何让flex元素下去,
只需在盒子上添加 flex-wrap: wrap;
变成
.fruit-item .fruit-info .name {
display:block;
font-size:35rpx;
-webkit-line-clamp: 2; //文字只显示两行
text-overflow: ellipsis; //超过两行以...显示
display: -webkit-box; //可伸缩的盒子
-webkit-box-orient: vertical; //在垂直方向可伸缩,以文字两行进行伸缩
overflow:hidden;
}
3.
display: flex;
justify-content: space-between;
一行有两个元素,让它们靠边站中间留有边距,这是flex布局的一个技法
未完待析:
点击图片进入详情页,点击一个购物车图片按钮,加入购物车,如果再次点击就会提示“已添加”。在详情页中点击加入购物车就会弹出
本次总结:
1.对于多个页面都是用的功能可封装到app.js中,例如:查询函数。
2.能用组件一定要用组件。
3.对于css中的弹性一定要多加了解。