【uni-app】懂你找图--创建项目到首页推荐模块
1.項目搭建
1.1 新建項目
- 創建項目 vue create -p dcloudio/uni-preset-vue dnpicture
- 安裝 sass依賴?? npm install sass-loader@7.3.1
npm install node-sass@4.14.1 node -v
查看自己的node版本根據node和node-sass版本關系按照相應的sass依賴
-
運行項目并導入微信開發者工具
npm run dev:mp-weixin
1 新增 tabbar 頁面
1.2 引入字體圖標
- 字體圖標使用的是 iconfont
Iconfont-阿里巴巴矢量圖標庫:https://www.iconfont.cn
這里有個坑就是:微信不支持本地字體圖標
從 阿里巴巴矢量圖標庫 下載到本地的,但是uni-app不支持本地iconfont.css,報錯
解決方案:從阿里巴巴矢量圖標庫 獲取在線連接
然后復制代碼粘貼到自己新建的iconfont.css文件里面
@font-face {font-family: "iconfont"; /* Project id 2973828 */src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834');src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'),}.iconfont {font-family: "iconfont" !important;font-size: 16px;font-style: normal;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale; }.icon-jiantou:before {content: "\e662"; }.icon-search:before {content: "\e600"; }.icon-shouye:before {content: "\e64f"; }.icon-shipin:before {content: "\e644"; }.icon-hengping:before {content: "\e671"; }.icon-wode:before {content: "\e602"; }在 App.vue中 全局引入
<style> @import "./styles/iconfont.css"; </style>在home/index.vue中使用
<template><view class="iconfont icon-search"></view> </template>1.3 uni-ui
1 uni-ui 介紹
- ?uni-app官網
-
uni-ui 是 DCloud 提供的一個跨端 ui 庫,它是基于vue組件的,flex布局的,無dom 的跨全端 ui 框架
-
uni-ui 不包括基礎組件,它是基礎組件的補充
-
數字角標,日歷,卡片,折疊面板,倒計時,抽屜,懸浮按鈕,收藏按鈕,底部購物導航,宮格,圖標,索引列表,加載更多,自定義導航欄,通告欄,數字輸入框,分頁器,彈出層,評分,搜索欄,分段器,步驟條,滑動操作,輪播圖指示點,標簽
2 uni-ui 使用
- 安裝 uni-ui npm install @dcloudio/uni-ui
- 局部引入組件
- 注冊組件
- 使用組件
?在 script 中引用組件:
<script> import { uniBadge } from "@dcloudio/uni-ui"; export default {components: {uniBadge,} </script>在 template 中使用組件:
<template><view>首頁<view class="iconfont icon-jiantou"></view><uni-badge text="1"></uni-badge><uni-badge text="2" type="success"></uni-badge><uni-badge text="3" type="primary" :inverted="true"></uni-badge></view> </template>1.4 uni-api 介紹?
- https://uniapp.dcloud.io/api/README
- 原生的微信小程序的 api 都是不支持 promise(承諾)
- uni-app 對大部分的小程序的原生 api 做了封裝。使之支持 promise
- 使用方法? ?
- ? ? ? ?原生微信小程序 wx.request
- ? ? ? ?uni-api 的方式 uni.request
- ? ? ? ?
2. 首頁模塊
2.1 功能分析
- 修改 導航欄的外觀
- 使用 分段器組件 搭建子頁面
- 封裝自己的異步請求
2.2 搭建子頁面
1. 子頁面
- 首頁模塊分為 4個部分,分別是 推薦,分類,最新,專輯
- 新建自定義組件來代替 上述的4個頁面
- home-recommend(推薦)
- home-category(分類)
- home-new(最新)
- home-album(專輯)
?在home/index.vue中引入組件
<template><view><home-recommend></home-recommend><home-category></home-category><home-new></home-new><home-album></home-album></view> </template><script> import homeAlbum from "./home-album"; import homeCategory from "./home-category"; import homeNew from "./home-new"; import homeRecommend from "./home-recommend";export default {components: {homeAlbum,homeCategory,homeNew,homeRecommend,} } </script>2. 分段器介紹
分段器·指的是 uni-ui 中的一個組件,其實就是我們俗稱的 標簽頁,tab頁
uni-segmented-control 分段器 - DCloud 插件市場
? 在 script 中引用組件:
<script> import { uniSegmentedControl } from "@dcloudio/uni-ui";export default {components: {uniSegmentedControl,},data() {return {items: ["選項卡1","選項卡2","選項卡3"],current: 0,};},methods: {onClickItem(e) {if (this.current !== e.currentIndex) {this.current = e.currentIndex;}},}, } </script>? 在 template 中使用組件:
<template><view><uni-segmented-control:current="current":values="items"@clickItem="onClickItem"style-type="button"active-color="#d4237a"></uni-segmented-control><view class="content"><view v-show="current === 0">選項卡1的內容</view><view v-show="current === 1">選項卡2的內容</view><view v-show="current === 2">選項卡3的內容</view></view></view> </template>3.分段器樣式優化?
調整后首頁的代碼
<template><view><view class="home_tab"><view class="home_tab_title"><view class="title_inner"><uni-segmented-control:current="current":values="items.map((v) => v.title)"@clickItem="onClickItem"style-type="text"active-color="#d4237a"></uni-segmented-control></view><view class="iconfont icon-search"></view></view><view class="home_tab_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 homeAlbum from "./home-album"; import homeCategory from "./home-category"; import homeNew from "./home-new"; import homeRecommend from "./home-recommend"; import { uniSegmentedControl } from "@dcloudio/uni-ui";export default {components: {homeAlbum,homeCategory,homeNew,homeRecommend,uniSegmentedControl,},data() {return {items: [{ title: "推薦" },{ title: "分類" },{ title: "最新" },{ title: "專輯" },],current: 0,};},methods: {onClickItem(e) {if (this.current !== e.currentIndex) {this.current = e.currentIndex;}},}, }; </script><style lang="scss"> .home_tab {.home_tab_title {position: relative;.title_inner{width: 60%;margin: 0 auto;}.icon-search{position: absolute;top: 50%;transform: translateY(-50%);right: 5%;}} } </style>? ? ? ? ? ? ??
2.3 封裝自己的異步請求
1.為什么要封裝
- 原生的請求不支持 promise
- uni-api 的請求不夠方便的添加 請求中 效果
- uni-api 的請求返回值是個數組,不方便
2.封裝的思路
- 基于原生的 promise 來封裝
- 掛載到 Vue 的原型上
- 通過 this.request 的方式來使用
3.封裝
在src中新建文件夾utils,在utils中新建文件request.js
//es6 promise 微信小程序的API的鋪墊 export default (params)=>{//加載中uni.showLoading({title:"加載中"})// 函數調用返回Promise對象return new Promise((resolve,reject)=>{wx.request({...params, //形參params解構//請求成功返回一個值到resolvesuccess(res){resolve(res.data) },//請求失敗返回一個值到rejectfail(err){reject(err)},complete(){uni.hideLoading()}})}) }?在main.js中
import request from "./utils/request"; Vue.prototype.request = request;返回首頁在 script 中?
<script> export default {onLoad(){this.request({url:"http://157.122.54.189:9088/image/v3/homepage/vertical"}).then(res=>{console.log(res);})} } </script>3. 編寫 首頁-推薦 頁面
3.1 功能介紹
-
接口文檔
懂你找圖--ShowDoc -
數據動態渲染
<template><!-- 推薦開始 --><view class="recommend_wrap"><view class="recommend_item" v-for="item in recommends" :key="item.id"><!-- mode圖片高度自適應 --><image mode="widthFix" :src="item.thumb"></image></view></view><!-- 推薦結束 --><!-- 月份開始 --><view class="monthes_wrap"><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"><imagemode="aspectFill":src="item.thumb + item.rule.replace('$<Height>', 360)"></image></view></view></view><!-- 月份結束 --> </template><script> // 引入moment import moment from "moment"; export default {// 定義數據data() {return {//推薦列表recommends: [],// 月份monthes: {},},// mounted組件生命周期事件,表示組件掛載完畢mounted() {this.request({url: "http://157.122.54.189:9088/image/v3/homepage/vertical",data: {//要獲取幾條limit: 30,//關鍵字order: "hot",//要跳過幾條skip: 0,},}).then((result) => {console.log(result);// 賦值拿到數據 推薦模塊this.recommends = result.res.homepage[1].items;// 賦值拿到數據 月份模塊this.monthes = result.res.homepage[2];// 將時間戳改成18號/月 用到moment.js 按照代碼npm install momentthis.monthes.MM = moment(this.monthes.stime).format("MM");this.monthes.DD = moment(this.monthes.stime).format("DD");});}, }; </script><style lang="scss" scoped> .recommend_wrap {//flex布局display: flex;flex-wrap: wrap;.recommend_item {width: 50%;border: 5rpx solid #fff;} } .monthes_wrap {.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 {color: $color;font-size: 24rpx;}}.monthes_content {display: flex;flex-wrap: wrap;.monthes_item {width: 33.33%;border: 5rpx solid #fff;}}} } </style> -
moment.js 的使用(時間格式)
npm install moment
momentjs.cn在 script 中引用
<script> // 引入moment 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 的分頁加載
<template><!-- 熱門開始 --><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><!-- 熱門結束 --> </template><style lang="scss" scoped> .hots_wrap {.hots_title {padding: 20rpx;text {border-left: 20rpx solid $color;font-size: 34rpx;font-weight: 600;padding-left: 20rpx;}}.hots_content {display: flex;flex-wrap: wrap;.hots_item {width: 33.33%;border: 5rpx solid #fff;}} } </style>3.2 解決一閃而過的問題
在最外層view加個判斷條件,當長度大于零的時候才顯示里面的標簽
<template> <view v-if="recommends.length > 0></template>3.3 分頁功能分析
- 使用 scroll-view 標簽充當分頁的容器 <template><!-- scroll-view標簽充當分頁的容器 --><scroll-view class="recommend_view" scroll-y></scroll-view> </template> <style lang="scss" scoped> .recommend_view {// 高度: 屏幕的高度(不能寫死) - 頭部標題的高度height: calc(100vh - 36px); } </style>
- 綁定滾動條觸底事件 scrolltolower <template><! scrolltolower綁定觸底事件 --><view @scrolltolower="handleToLower"><view> </template> <script> export default { methods: {handleToLower() {console.log(大帥哥)}} } </script>
- 實現分頁邏輯 <script> // 引入moment import moment from "moment"; export default {// 定義數據data() {return {//推薦列表recommends: [],// 月份monthes: {},// 熱門hots: [],// 請求參數params: {//要獲取幾條limit: 30,//關鍵字order: "hot",//要跳過幾條skip: 0,},// 是否還有下一頁hasMore: true,};},// mounted組件生命周期事件,表示組件掛載完畢mounted() {this.getList();},methods: {// 獲取接口數據getList() {this.request({url: "http://157.122.54.189:9088/image/v3/homepage/vertical",data: this.params,}).then((result) => {// console.log(result);// 判斷是否還有下一頁數據if (result.res.vertical.length === 0) {this.hasMore = false;uni.showToast({title: "沒有數據了",icon: "none",});return;}// 第一次發送的請求if (this.recommends.length === 0) {// 賦值拿到數據 推薦模塊this.recommends = result.res.homepage[1].items;// 賦值拿到數據 月份模塊this.monthes = result.res.homepage[2];// 將時間戳改成18號/月 用到moment.js 按照代碼npm install momentthis.monthes.MM = moment(this.monthes.stime).format("MM");this.monthes.DD = moment(this.monthes.stime).format("DD");}// 賦值獲取熱門數據的列表// 數組拼接 es6 (為下面第三步)this.hots = [...this.hots, ...result.res.vertical];});},// 滾動條觸底事件handleToLower() {/* 1 修改參數 skip+=limit2 重新發送請求 getList()3 請求回來成功 hots 數據的疊加*/if (this.hasMore) {this.params.skip += this.params.limit;this.getList();} else {// 彈窗提示用戶uni.showToast({title: "沒有數據了",icon: "none",});}},}, }; </script>
首頁-推薦 頁面:
<template><!-- scroll-view標簽充當分頁的容器 scrolltolower綁定觸底事件 --><scroll-viewclass="recommend_view"scroll-y@scrolltolower="handleToLower"v-if="recommends.length > 0"><!-- 推薦開始 --><view class="recommend_wrap"><view class="recommend_item" v-for="item in recommends" :key="item.id"><!-- mode圖片高度自適應 --><image mode="widthFix" :src="item.thumb"></image></view></view><!-- 推薦結束 --><!-- 月份開始 --><view class="monthes_wrap"><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"><imagemode="aspectFill":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> // 引入moment import moment from "moment"; export default {// 定義數據data() {return {//推薦列表recommends: [],// 月份monthes: {},// 熱門hots: [],// 請求參數params: {//要獲取幾條limit: 30,//關鍵字order: "hot",//要跳過幾條skip: 0,},// 是否還有下一頁hasMore: true,};},// mounted組件生命周期事件,表示組件掛載完畢mounted() {this.getList();},methods: {// 獲取接口數據getList() {this.request({url: "http://157.122.54.189:9088/image/v3/homepage/vertical",data: this.params,}).then((result) => {// console.log(result);// 判斷是否還有下一頁數據if (result.res.vertical.length === 0) {this.hasMore = false;uni.showToast({title: "沒有數據了",icon: "none",});return;}// 第一次發送的請求if (this.recommends.length === 0) {// 賦值拿到數據 推薦模塊this.recommends = result.res.homepage[1].items;// 賦值拿到數據 月份模塊this.monthes = result.res.homepage[2];// 將時間戳改成18號/月 用到moment.js 按照代碼npm install momentthis.monthes.MM = moment(this.monthes.stime).format("MM");this.monthes.DD = moment(this.monthes.stime).format("DD");}// 賦值獲取熱門數據的列表// 數組拼接 es6 (為下面第三步)this.hots = [...this.hots, ...result.res.vertical];});},// 滾動條觸底事件handleToLower() {/* 1 修改參數 skip+=limit2 重新發送請求 getList()3 請求回來成功 hots 數據的疊加*/if (this.hasMore) {this.params.skip += this.params.limit;this.getList();} else {// 彈窗提示用戶uni.showToast({title: "沒有數據了",icon: "none",});}},}, }; </script><style lang="scss" scoped> .recommend_view {// 高度:屏幕的高度(不能寫死) - 頭部標題的高度height: calc(100vh - 36px); } .recommend_wrap {//flex布局display: flex;flex-wrap: wrap;.recommend_item {width: 50%;border: 5rpx solid #fff;} } .monthes_wrap {.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 {color: $color;font-size: 24rpx;}}.monthes_content {display: flex;flex-wrap: wrap;.monthes_item {width: 33.33%;border: 5rpx solid #fff;}}} } .hots_wrap {.hots_title {padding: 20rpx;text {border-left: 20rpx solid $color;font-size: 34rpx;font-weight: 600;padding-left: 20rpx;}}.hots_content {display: flex;flex-wrap: wrap;.hots_item {width: 33.33%;border: 5rpx solid #fff;}} } </style>總結
以上是生活随笔為你收集整理的【uni-app】懂你找图--创建项目到首页推荐模块的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 熔断及算法
- 下一篇: 基于Java+SpringBoot+Vu