Day1

学习方法

本次课程选择的集成开发环境是HBuilder X ,框架为uni-app

此外,为了接近企业开发,使用git控制版本,尽量通过官方文档自学为主,教学为辅的学习方法

官方文档 : https://uniapp.dcloud.net.cn/tutorial/

项目结构的认识

pages.json用于对项目进行全局配置,配置所有页面的最基本的信息

每次新建一个page,pages.json中就会自动注册一个pages的配置框

tabBar配置框用于配置底部导航栏

按键绑定页面,实现交互

在button标签中使用@click=”function()”,然后在function中使用uni.navigateTo函数下使用url:”页面地址”

1
2
3
4
5
goToPlay(name,id){
uni.navigateTo({
url:"/pages/player/player?name=" + name + "&id=" + id
})
}

页面之间互相传递值

在被上级使用uni.navigateTo绑定了的下级页面中的export default下使用onLoad()函数接收值

1
2
3
4
5
onLoad(query) {
console.log(query);
this.name = query.name
console.log(this.name);
},

#Day2

块级元素和行内元素

view是块级元素,自占一行,text则是行内元素,不能设置宽高,由内部元素自己撑开,在前端中,对块的理解是必须的.一个块包括中心、padding、border、margin

使用display: flex设置弹性盒子

子元素可以灵活调整大小和位置 如果一行多个弹性盒子,可以使用flex:1来在盒子里面调整分得的比例,1代表一份

另外,可以使用flex-direction: column改为纵向的弹性盒子,juestify-content相应变成了纵向.

在构建盒子时,应该先把骨架写好,名称命名好.然后再进行具体的style编辑,可以使用backgroundcolor来辅助标明位置

绝对定位

绝对定位可以使一个块级元素悬浮于其他元素,绝对定位的位置是相对于「设置了position的上级」

在script区,循环遍历一段数据

Day3

列表渲染,使用v-for=”(项目1,项目2) in 数组名” : key=””

key为了提高性能,如果是相同key,更新时无需卸载,直接更新,可以填一个项目的id作为key,这里填写movie.id

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
 <view class="songs-item" v-for="song in songsList" :key="song.id">
<image class="songs-avatar" :src="song.picUrl"></image>
<view class="songs-name">{{song.name}}</view>
<view class="songs-id">{{song.id}}</view>
</view>
return {
songsList: [{
"id": 2124385868,
"name": "如果爱忘了 (live)",
"picUrl": "http://p1.music.126.net/kGdzpMO7C-8ERTcwymW4sA==/109951169315856070.jpg",
}, {
"id": 2124381474,
"name": "小美满",
"picUrl": "http://p1.music.126.net/ve0l1aPRUBPP7e4x2Oz5DA==/109951169318479430.jpg",

}, {
"id": 2124731026,

"name": "5:20AM",
"picUrl": "http://p1.music.126.net/RjiI9yP2Fnxx5cxiTVCIrQ==/109951169318905148.jpg",

}, {
"id": 2127872173,

"name": "身骑白马",

"picUrl": "http://p1.music.126.net/njLkPcFGmXRe5G6yyKuH-A==/109951169350414864.jpg",

}, {
"id": 2122308127,
"name": "不眠之夜",
"picUrl": "http://p1.music.126.net/sZ-rACbFrybF0x_lI6XNMw==/109951169297766755.jpg",

}, {
"id": 2121901193,
"name": "你曾说过的话",
"picUrl": "http://p1.music.126.net/zi39Vt1U9ifuBMN3JZxBBw==/109951169352203792.jpg",
}, {
"id": 2121775518,
"name": "只要有你",
"picUrl": "http://p1.music.126.net/3TD_dt9FlvXfYgF3ZRWXiw==/109951169293642007.jpg",

}, {
"id": 2124385829,
"name": "晚安 (live)",
"picUrl": "http://p1.music.126.net/kGdzpMO7C-8ERTcwymW4sA==/109951169315856070.jpg",
}]

}

使用whilte-space: nowrap使行内元素在一行展示

可以将块元素的display设置为inline-block使其变为行内元素,可以达到块元素展示在同一行的效果

尝试发起网络请求

uni.request(){}函数可以发起网络请求,如果希望页面加载时就发起,就放到OnLoad函数中

处理获得的信息

将复杂数组转换成一个简单数组,方便自己使用

Day4后 制作瑞幸咖啡前端页面

首页

搜索栏,根据时间显示早上好、上午好、中午好、下午好、晚上好

首先,确定本项目是使用自定义导航栏,在.json中的globalStyle中配置”navigationStyle”: “custom”和具体风格.注意导航栏只是覆盖在页面Z轴顶部,因此会遮挡页面内容,根据需要给页面设置padding-top解决.

将根据时间输出早中上下午的的函数放到Onload()中执行即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
sayHello() {
// 获取当前时间
let date = new Date()
// 获取小时数
let h = date.getHours()

if(h > 3 && h < 12) {
this.time = '上午好'
}else if(h >=12 && h < 15) {
this.time = '中午好'
}else if(h >=15 && h < 19) {
this.time = '下午好'
}else {
this.time = '晚上好'
}

轮播图

在官方文档的视图容器中找到swiper,查询相关内容.

首先,在Unload中request到我们需要的图片数组,然后在swiper-item中v-for即可

1
2
3
4
5
6
<swiper class="banner" v-if="banner.length" indicator-color="#fff" indicator-active-color="rgb(12,52,186)" :interval="2000" circular :indicator-dots="false" autoplay>
<swiper-item v-for="b in banner" :key="b.pid">
<image class="img-content" :src="b.bannerImg"></image>
</swiper-item>
</swiper>

缺角盒子样式

缺角样式可使用border-radius设置四个数值,从左上角开始增加弧度

菜单页和搜索页

搜索框有内容时出现一键删除小按钮,点击会清空搜索框文字,没内容时立即清除下方商品

在搜索框右方放置icon,通过v-show与search内容绑定,当有内容时出现,点击事件设为清空search内容
初始化空数组用于存下方商品,
将变量绑定到watch中监听,seach为修改前变量,newVal为修改后,当其为空时,清除下方商品

1
2
3
4
5
search(newVal) {
if (newVal === '') {
this.searchResult = []
}
}

搜索栏出现不同数量商品采取不同的对齐风格

通过动态绑定style的对齐属性,使用三目运算解决

1
<view class="result-wrapper" :style="{'justify-content': searchResult.length < 3 ? 'flex-start':'space-between'}" v-show="searchResult.length">

四个分类:推荐、拿铁、咖啡、瑞纳冰,点击会更新相应内容到下方

实现根据输入内容搜索功能

查看api中数据源的id,在Onload中request搜索到的数据到本地
在watch中监听search值,当为空时需要清空查询数组,使展示框为空.

商品详情页

商品详情文字内容模块浮于图片上

在样式中设置z-index

可选择的温度、糖度按键(单选型),未选择选项灰度

使用 : class绑定语法,根据条件动态添加类的方法.当被选中的内容和按键的内容一致时,触发条件成立,更新新的class.然后将button调用的函数功能设置为将按键内容赋值给选中内容

1
2
3
<view class="selector-btn" v-for="o in t.options" :class="{active: o ===  t.selected }"@click="onSelectHandel(o, i)" :key="o">
{{o}}
</view>

可点击的数量加减按键,点击会更新数量

定义加减函数和变量即可

底部Bar为有购物袋和收藏,点击相应按键会变蓝,且购物袋右上角会显示购物袋>0时的数字

在icon文件设置两个样式,一个为另一个的active变色样式.设置一个布尔值,和反转布尔值的方法.点击按键即调用方法.使用动态添加类方法,根据布尔值选择灰图标类还是active变色样式.

购物袋页

判断是否需要跳转到登陆页面

在onShow中使用getStorage()方法获取token

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
onShow() {
console.log(1231231);
// 判断是否登录
uni.getStorage({
key: 'token',
success: function (res) {
console.log("有token,已登陆");
},
fail(err) {
console.error('err',err);
uni.navigateTo({
url:'/pages/login/login'
})
}
});
},


一个商品一行排列,行头提供选中按键,最后一行显示“哎呀,没有数据可加载了!”点击选中按键会计算合集金额.

提交订单栏,提供全选按键,点击会打勾本按键和所有商品选中按键,且计算合计金额

点击右上角编辑,文字会变为“完成”提交订单栏会变为删除栏,提供“删除选择”按键和相应功能.

订单结算页

地址栏提供选择地址按键和显示地址,点击“选择地址”下方弹出可供选择的地址(带有单选型蓝勾选择按键)、新增地址按键

我的订单页

提供分类,全部、进行中、已完成,点击展示相应商品

商品一行一个,一个订单号多个商品为一组,已完成的组提供删除按键和相应功能,进行中的商品提供确认收货按键,点击后完成

我的页

个人信息栏提供头像、名字和签名「悬浮透明框」

选项卡提供四个入口,个人资料、我的订单、我的收藏、地址管理

个人资料页

提供四个可更改的内容,头像、id、昵称、简介「悬浮框」

收藏页

一行三件商品,显示图片文字价格,价格旁边有删除按键和相应功能「悬浮框」

地址管理页

每行显示一条显示收货信息,旁边有一个修改按键,点击跳转到编辑地址页

编辑地址页和新增地址页

提供若干条可编辑的框,有设为默认收货地址框,提供保存地址和删除按键和功能

点击地区可弹出地区的滑动选择框

底部Bar

四个入口,单选,选中会变蓝.

在pages.json文件的tabBar样式中配置selectedIconPath

登陆页

页面接受登陆所需的数据

input框使用v-model绑定变量

登陆功能

在登陆函数中,传入电话和密码,使用api发送请求.将获得api传回的数据.
根据数据,如果成功,则使用setStorage将认证token放到缓存中去.然后使用showToast方法显示小提示,使用setTimeout延迟且使用uni.switchTab跳转到特定界面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
login() {
console.log(this.phone);
console.log(this.pwd);
if (this.pwd && this.phone) {
uni.request({
url: 'http://www.kangliuyong.com:10002/login',
data: {
appkey: 'U2FsdGVkX19WSQ59Cg+Fj9jNZPxRC5y0xB1iV06BeNA=',
password: this.pwd,
phone: this.phone
},
method: 'POST',
header: {
'content-type': 'application/x-www-form-urlencoded;charset=utf-8' // 默认值
},
success: res => {
console.log(res.data);
if (res.data.code == 200) {
// 存 token
uni.setStorage({
key: 'token',
data: res.data.token,
success() {
uni.showToast({
title: '登录成功',
icon: 'success',
duration: 1000,
})
// 延迟执行
setTimeout(() => {
uni.switchTab({
url: '/pages/index/index'
})
}, 1000)
}
})

} else {
uni.showToast({
title: res.data.msg,
icon: 'error'
})
}
}
})
} else {
uni.showToast({
title: '输入框不能为空',
icon: 'error'
})
}
}

点击注册会从页面下方平滑地弹出一个注册副页面,同时原页面会有一层灰色蒙板覆盖

设置蒙板打开变量为0,注册点击事件中将变量置1,此时蒙板打开(蒙板为全屏幕,蒙板点击事件为变量置0,使用v-show来绑定打开状态)

1
2
<view class="register-btn" @click="showRegisterHandel">注册</view>
<view class="register-view" @click="hiddenRegister" v-show="showRegister">

使用标签作为盒子,Z轴设置为999,且设置相关参数.

  1. 开始初始滑动位置,100%即为从底部完全没有开始滑动上来
  2. 滑动完成的所需时间
  3. 滑动动画结束后的位置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
.move-enter,
.move-leave-to {
transform: translateY(100%);
}

.move-enter-active,
.move-leave-active {
transition: all linear .2s;
}

.move-enter-to,
.move-leave {
transform: translateY(0);
}