目錄
1. 項目搭建
1.1 新建項目
- 創建項目 vue create -p dcloudio/uni-preset-vue dnpicture
- 安裝 sass依賴 npm install sass-loader node-sass
1 新增 tabbar 頁面
1.2 引入字體圖標
- 字體圖標使用的是 iconfont
- 在 App.vue中 全局引入
Iconfont-阿里巴巴矢量圖標庫:https://www.iconfont.cn
從 阿里巴巴矢量圖標庫 下載到本地的,但是uni-app不支持本地iconfont.css,報錯
00:42:22.580 Module build failed: ModuleNotFoundError: Module not found: Error: Can't resolve './iconfont.eot?t=1521557349802' in 'D:\workspace\appProjects\uniQingchi\pages\index'
00:42:22.592 at factoryCallback (D:\app\HBuilderX\plugins\uniapp\node_modules\webpack\lib\Compilation.js:264:39)
00:42:22.592 at factory (D:\app\HBuilderX\plugins\uniapp\node_modules\webpack\lib\NormalModuleFactory.js:247:20)
00:42:22.603 at resolver (D:\app\HBuilderX\plugins\uniapp\node_modules\webpack\lib\NormalModuleFactory.js:65:21)
00:42:22.613 at asyncLib.parallel (D:\app\HBuilderX\plugins\uniapp\node_modules\webpack\lib\NormalModuleFactory.js:138:21)
解決方案:從阿里巴巴矢量圖標庫 獲取在線連接
@import "./styles/iconfont.wxss";
<text class="iconfont"></text>
1.3 uni-ui
1 uni-ui 介紹
-
uni-ui 是 DCloud 提供的一個跨端 ui 庫,它是基於vue組件的,flex佈局的,無dom 的跨全端 ui 框架
-
uni-ui 不包括基礎組件,它是基礎組件的補充
-
數字角標,日曆,卡片,摺疊面板,倒計時,抽屜,懸浮按鈕,收藏按鈕,底部購物導航,宮格,圖標,索引列表,加載更多,自定義導航欄,通告欄,數字輸入框,分頁器,彈出層,評分,搜索欄,分段器,步驟條,滑動操作,輪播圖指示點,標籤
2 uni-ui 使用
- 安裝 uni-ui
npm install @dcloudio/uni-ui
- 局部引入組件
- 註冊組件
- 使用組件
在 script 中引用組件:
import {uniBadge} from '@dcloudio/uni-ui'
//import uniBadge from '@dcloudio/uni-ui/lib/uni-badge/uni-badge.vue' //也可使用此方式引入組件
export default {
components: {uniBadge}
}
在 template 中使用組件:
<uni-badge text="1"></uni-badge>
<uni-badge text="2" type="success" @click="bindClick"></uni-badge>
<uni-badge text="3" type="primary" :inverted="true"></uni-badge>
1.4 uni-api 介紹
- https://uniapp.dcloud.io/api/README
- 原生的微信小程序的 api 都是不支持 promise(承諾)
- uni-app 對大部分的小程序的原生 api 做了封裝。使之支持 promise
- 使用方法
- 原生微信小程序 wx.request
- uni-api 的方式 uni.request
- 其他 api 的使用方式也類似
onLoad() {
//http://157.122.54.189:9088/image/v3/homepage/vertical
// 1 原生的微信小程序的 api
wx.request({
url:"http://157.122.54.189:9088/image/v3/homepage/vertical",
success:(res) =>{
console.log(res)
}
})
//2. uni-api
uni.request({
url:"http://157.122.54.189:9088/image/v3/homepage/vertical",
}).then(res => {
console.log(res)
})
},
2. 首頁模塊
2.1 功能分析
- 修改 導航欄的外觀
- 使用 分段器組件 搭建子頁面
- 封裝自己的異步請求
2.2 搭建子頁面
1. 子頁面
- 首頁模塊分爲 4個部分,分別是 推薦,分類,最新,專輯
- 新建自定義組件來代替 上述的4個頁面
- home-recommend(推薦)
- home-category(分類)
- home-new(最新)
- home-album(專輯)
2. 分段器介紹
分段器·指的是 uni-ui 中的一個組件,其實就是我們俗稱的 標籤頁,tab頁
https://ext.dcloud.net.cn/plugin?id=54
<!-- 首頁 -->
<template>
<view class="content">
<view>
<uni-segmented-control
:current="current"
:values="items.map(a=>a.title)"
@clickItem="onClickItem"
style-type="text"
active-color="#d4237a">
</uni-segmented-control>
<view class="content">
<view v-if="current === 0">
<home-recommend></home-recommend>
</view>
<view v-if="current === 1">
<home-category></home-category>
</view>
<view v-if="current === 2">
<home-new></home-new>
</view>
<view v-if="current === 3">
<home-album></home-album>
</view>
</view>
</view>
</view>
</template>
<script>
import homeRecommend from './home-recommend';
import homeCategory from './home-category';
import homeNew from './home-new';
import homeAlbum from './home-album';
import { uniSegmentedControl } from "@dcloudio/uni-ui";
export default {
data (){
return {
items: [{
title:'推薦'
},
{
title:'分類'
},
{
title:'最新'
},
{
title:'專輯'
}],
current: 0
}
},
components: {
homeRecommend,
homeCategory,
homeNew,
homeAlbum,
uniSegmentedControl
},
methods: {
onClickItem(index) {
if (this.current !== index.currentIndex) {
this.current = index.currentIndex;
}
}
}
}
</script>
<style>
</style>
3.分段器樣式優化
有四個區域
所以大概結構是:
<view>
<view class="上 home_tab">
<view >
1(這個一般不寫)
</view>
<view class="home_tab_title">
2(分段器)
</view>
<view class="search_icon">
3(搜索按鈕)
<text class="iconfont"></text>
</view>
</view>
<view class="下 content">
4(內容)
</view>
</view>
<style lang="scss">
.home_tab{
position: relative;
.home_tab_title{
width: 60%;
margin: 0 auto;
}
.search_icon{
position: absolute;
top: 50%;
transform: translateY(-50%);
right: 5%;
}
}
</style>
2.3 封裝自己的異步請求
1.爲什麼要封裝
- 原生的請求不支持 promise
- uni-api 的請求不夠方便的添加 請求中 效果
- uni-api 的請求返回值是個數組,不方便
2.封裝的思路
- 基於原生的 promise 來封裝
- 掛載到 Vue 的原型上
- 通過 this.request 的方式來使用
3.封裝
// es6
export default (params)=>{
//加載中
uni.showLoading({
title:"加載中"
})
return new Promise((resolve,reject)=>{
wx.request({
...params,
success:(res)=>{
resolve(res.data)
},
fail:(err)=>{
reject(err)
},
complete() {
uni.hideLoading();
}
})
})
}
在 main.js 中
import request from "./utils/request.js"
Vue.prototype.request=request;
onLoad(){
this.request({
url:"http://157.122.54.189:9088/image/v3/homepage/vertical"
}).then(res=>{
console.log(res);
})
}
3. 編寫 首頁-推薦 頁面
3.1 功能介紹
-
接口文檔
https://www.showdoc.cc/414855720281749?page_id=3618621017219602 -
數據動態渲染
-
moment.js 的使用(時間格式)
momentjs.cn
npm install moment --save # npm
yarn add moment # Yarn
Install-Package Moment.js # NuGet
spm install moment --save # spm
meteor add momentjs:moment # meteor
bower install moment --save # bower (廢棄)
<script>
import moment from "moment";
this.monthes.MM = moment(this.monthes.stime).format("MM");
this.monthes.DD = moment(this.monthes.stime).format("DD");
</script>
- “熱門” 列表的基於 scroll-view 的分頁加載
3.2 解決一閃而過的問題
解決辦法:
加個判斷
<template>
<view v-if="recommends.length>0">
3.3 分頁功能分析
- 使用 scroll-view 標籤充當分頁的容器
- 綁定滾動條觸底事件 scrolltolower
- 實現分頁邏輯
<template>
<scroll-view class="recommend_view"
@scrolltolower="handerToLower"
scroll-y v-if="recommends.length>0">
<script>
methods:{
//滾動條觸底事件
handerToLower(){
console.log("遲到大王大大");
}
}
<style lang="scss">
.recommend_view{
//height: 屏幕的高度 - 頭部標題的高度
height: calc( 100vh - 36px);
首頁-推薦 頁面:
<template>
<scroll-view class="recommend_view" @scrolltolower="handerToLower"
scroll-y v-if="recommends.length>0">
<!-- 推薦 開始 -->
<view class="recommend_warp">
<view class="recommend_item" v-for="item in recommends"
:key="item.id">
<image mode="widthFix" :src="item.thumb"></image>
</view>
</view>
<!-- 推薦 結束 -->
<!-- 月份 開始 -->
<view class="monthes_warp">
<view class="monthes_title">
<view class="monthes_title_info">
<view class="monthes_info">
<text> {{monthes.DD}} /</text>
{{monthes.MM}} 月
</view>
<view class="monthes_text">
{{monthes.title}}
</view>
</view>
<view class="monthes_title_more">
更多 >
</view>
</view>
<view class="monthes_content">
<view class="monthes_item" v-for="item in monthes.items" :key="item.id">
<!-- mode="widthFix" -->
<image mode="widthFix"
:src="item.thumb+item.rule.replace('$<Height>',360)">
</image>
</view>
</view>
</view>
<!-- 月份 結束 -->
<!-- 熱門 開始 -->
<view class="hots_wrap">
<view class="hots_title">
<text>熱門</text>
</view>
<view class="hots_content">
<view class="hots_item" v-for="item in hots" :key="item.id">
<image mode="widthFix" :src="item.thumb">
</image>
</view>
</view>
</view>
<!-- 熱門 結束 -->
</scroll-view>
</template>
<script>
import moment from "moment";
export default {
data(){
return{
//推薦列表
recommends:[],
//月份
monthes:{},
//熱門
hots:[],
//請求的參數
params:{
//要獲取幾條
limit: 30,
//關鍵字
order: 'hot',
//要跳過幾條
skip: 0
},
//是否還有下一頁
hasMore:true
}
},
mounted() {
this.getList();
},
methods:{
//獲取接口的數據
getList(){
this.request({
url: 'http://157.122.54.189:9088/image/v3/homepage/vertical',
data: this.params
}).then(result =>{
// 判斷有沒有下一頁數據
if(result.res.vertical.length===0){
this.hasMore=false;
return;
}
if(this.recommends.length===0){
//第一次發送的請求
//推薦模塊
this.recommends = result.res.homepage[1].items;
//月份模塊
this.monthes = result.res.homepage[2];
//將時間戳 改成 18號/月 moment.js
this.monthes.MM = moment(this.monthes.stime).format("MM");
this.monthes.DD = moment(this.monthes.stime).format("DD");
}
//獲取熱門數據的列表
// 數組拼接 es6
//this.hots = result.res.vertical;
this.hots = [...this.hots, ...result.res.vertical];
})
},
//滾動條觸底事件
handerToLower(){
/**
* 1. 修改參數 skip+=limit;
* 2. 重新發送請求 getList()
* 3. 請求回來成功 hots 數據的疊加
*/
if(this.hasMore){
this.params.skip += this.params.limit;
this.getList();
}else{
// 彈窗提示用戶
uni.showToast({
title:"沒有了喲",
icon:"none"
})
}
}
}
}
</script>
<style lang="scss">
.recommend_view{
//height: 屏幕的高度 - 頭部標題的高度
height: calc( 100vh - 36px);
}
.recommend_warp{
display: flex;
flex-wrap: wrap;
.recommend_item{
width: 50%;
border: 5rpx solid #000;
}
}
.monthes_warp{
.monthes_title{
display: flex;
justify-content: space-between;
padding: 20rpx;
.monthes_title_info{
color: $color;
font-size: 30rpx;
font-weight: 600;
display: flex;
.monthes_info{
text{
font-size: 36rpx;
}
}
.monthes_text{
font-size: 34rpx;
color: #666;
margin-left: 30rpx;
}
}
.monthes_title_more{
font-size: 24rpx;
color: $color;
}
}
.monthes_content{
display: flex;
flex-wrap: wrap;
.monthes_item{
width: 33.3%;
border: 5rpx solid #fff;
}
}
}
.hots_wrap{
.hots_title{
padding: 20rpx;
text{
border-left: 20rpx solid $color;
padding-left: 20;
font-size: 34rpx;
font-weight: 600;
}
}
.hots_content{
display: flex;
flex-wrap: wrap;
.hots_item{
width: 33.3%;
border: 5rpx solid #fff;
image{
}
}
}
}
</style>
4.首頁模塊-專輯模塊
4.1 專輯列表
1. 功能分析
- 使用 setNavigationBarTitle 修改 頁面標題
- 發送請求獲取數據
- 使用 swiper 輪播圖組件
- 使用 scroll-view 組件實現分頁
- 點擊跳轉到 專輯詳情頁