锅巴沙丁 發表於 2020-3-14 10:30:00

基于uni-app开发微信小程序__手牵手带你开发【懂你找图】项目

<h3>前戏</h3>
<p>某一天的夜里,敲完了代码之后便直接倒在床上睡着了,醒来时只记得梦里的一句话:“想要成为高手,就必须要大量实践,大量做项目,必须要把自己不会的东西全部吃透,不要得过且过。”,猛然想起是一位大神前辈对我说的,工作之后每天加班,回家之后就不想学习了,总想着一把锤子搞定所有钉子,这样是不行的,于是我就下了几百G的项目实战视频,有Vue、React、Node.js、Angular、Flutter、各个框架源码分析。。。我计划今年把它们全部干完,每做一个项目我都会写一篇博客来记录开发过程和收获,我想着通过大量的项目练习来让自己变成熟练工种,然后再去看源码就会比较轻松;接下来就让我牵着同学们的小手带你们开发一款基于uni-app的微信小程序项目,项目名字叫【懂你找图】。</p>
<p>&nbsp;</p>
<h3>项目介绍</h3>
<p>做这个项目之前,同学们最好写过2-3个移动端的页面,有一定的JS基础,比如map,forEach函数的使用,Promise的使用,掌握Vue的基本语法,基本的生命周期,什么是Watch?怎么使用一个Component?子传父 / 父传子的实现方式。</p>
<p>没有基础的同学也不要担心,可以跟着把项目写完,然后把不理解的地方单独抽出来,逐个学习,然后再把项目独立做一遍就完事了。</p>
<p>这个是项目做完之后的效果:</p>
<p><img src="https://img2018.cnblogs.com/i-beta/1783433/202003/1783433-20200301131028293-191300726.png" alt="" width="309" height="535"></p>
<p>&nbsp;</p>
<p>这个项目我会带领同学们写完首页的模块,其他模块由于API接口还没有写好,暂时不做,等以后写好了,我会马上更新,接下来我们就进入正片环节。</p>
<p>&nbsp;</p>
<h3>1.项目准备</h3>
<h4>1.1开发方式</h4>
<p>uni-app为我们提供2种开发方式:</p>
<p>1.使用DCloud公司提供HBuilderX工具来快速开发;</p>
<p>2.使用脚手架来快速开发(我们这次项目使用此方式);</p>
<p>&nbsp;</p>
<h4>1.2脚手架搭建项目</h4>
<p>1.全局安装,如果你以前安装过就不需要重复安装了。</p>
<div class="cnblogs_code">
<pre>npm install -g @vue/cli</pre>
</div>
<p>2.创建项目。</p>
<div class="cnblogs_code">
<pre>vue create -p dcloudio/uni-preset-vue dnpicture</pre>
</div>
<p>3.启动项目(微信小程序)。</p>
<div class="cnblogs_code">
<pre>npm run dev:mp-weixin</pre>
</div>
<p>4.在微信小程序开发者工具导入项目。</p>
<p><strong>&nbsp;注意导入项目的路径。</strong></p>
<p><img src="https://img2018.cnblogs.com/i-beta/1783433/202003/1783433-20200301140154987-734245728.png" alt="" width="708" height="399"></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h4>1.3搭建过程中可能遇到的问题</h4>
<p>容易出现 vue 和 vue-template-complier版本不一致的问题。</p>
<p><img src="https://img2018.cnblogs.com/i-beta/1783433/202003/1783433-20200301132922420-691588745.png" alt="" width="811" height="190"></p>
<p>&nbsp;</p>
<p>&nbsp;根据提示重新安装对应的vue版本即可 npm install vue@2.6.10,然后再重新运行项目&nbsp;npm&nbsp;run dev:mp-weixin。</p>
<p>&nbsp;</p>
<h4>1.4安装sass依赖</h4>
<div class="cnblogs_code">
<pre>npm install sass-loader node-sass</pre>
</div>
<p>&nbsp;</p>
<h3>2.项目搭建</h3>
<h4>2.1新增tabbar页面</h4>
<table style="height: 139px; width: 422px" border="0">
<tbody>
<tr>
<td style="text-align: center">页面名称</td>
<td style="text-align: center">路径</td>
</tr>
<tr>
<td style="text-align: center">首页</td>
<td style="text-align: center">home/index.vue</td>
</tr>
<tr>
<td style="text-align: center">横屏</td>
<td style="text-align: center">horizontal/index.vue</td>
</tr>
<tr>
<td style="text-align: center">精美视频</td>
<td style="text-align: center">video/index.vue</td>
</tr>
<tr>
<td style="text-align: center">搜索</td>
<td style="text-align: center">search/index.vue</td>
</tr>
<tr>
<td style="text-align: center">我的</td>
<td style="text-align: center">mine/index.vue</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p><img src="https://img2018.cnblogs.com/i-beta/1783433/202003/1783433-20200301135005225-1409197246.png" alt="" width="757" height="400"></p>
<p>&nbsp;</p>
<p>新建完页面之后,我们再去pages.json文件里面添加页面路径和tabbar对应的图片和样式。</p>
<div class="cnblogs_code"><img id="code_img_closed_e4e8b853-b7e4-4b12-9727-ad1cfc9574d4" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_e4e8b853-b7e4-4b12-9727-ad1cfc9574d4" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_e4e8b853-b7e4-4b12-9727-ad1cfc9574d4" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 0, 1)">{
    </span>"pages"<span style="color: rgba(0, 0, 0, 1)">: [{
            </span>"path": "pages/home/index"<span style="color: rgba(0, 0, 0, 1)">,
            </span>"style"<span style="color: rgba(0, 0, 0, 1)">: {
                </span>"navigationBarTitleText": "首页"<span style="color: rgba(0, 0, 0, 1)">
            }
      },
      {
            </span>"path": "pages/horizontal/index"<span style="color: rgba(0, 0, 0, 1)">,
            </span>"style"<span style="color: rgba(0, 0, 0, 1)">: {
                </span>"navigationBarTitleText": "横屏"<span style="color: rgba(0, 0, 0, 1)">
            }
      },
      {
            </span>"path": "pages/video/index"<span style="color: rgba(0, 0, 0, 1)">,
            </span>"style"<span style="color: rgba(0, 0, 0, 1)">: {
                </span>"navigationBarTitleText": "精美视频"<span style="color: rgba(0, 0, 0, 1)">
            }
      },
      {
            </span>"path": "pages/search/index"<span style="color: rgba(0, 0, 0, 1)">,
            </span>"style"<span style="color: rgba(0, 0, 0, 1)">: {
                </span>"navigationBarTitleText": "搜索"<span style="color: rgba(0, 0, 0, 1)">
            }
      },
      {
            </span>"path": "pages/mine/index"<span style="color: rgba(0, 0, 0, 1)">,
            </span>"style"<span style="color: rgba(0, 0, 0, 1)">: {
                </span>"navigationBarTitleText": "我的"<span style="color: rgba(0, 0, 0, 1)">
            }
      }
    ],
    </span>"globalStyle"<span style="color: rgba(0, 0, 0, 1)">: {
      </span>"navigationBarTextStyle": "black"<span style="color: rgba(0, 0, 0, 1)">,
      </span>"navigationBarTitleText": "uni-app"<span style="color: rgba(0, 0, 0, 1)">,
      </span>"navigationBarBackgroundColor": "#F8F8F8"<span style="color: rgba(0, 0, 0, 1)">,
      </span>"backgroundColor": "#F8F8F8"<span style="color: rgba(0, 0, 0, 1)">
    },
    </span>"tabBar"<span style="color: rgba(0, 0, 0, 1)">: {
      </span>"color": "#8a8a8a"<span style="color: rgba(0, 0, 0, 1)">,
      </span>"selectedColor": "#d4237a"<span style="color: rgba(0, 0, 0, 1)">,
      </span>"backgroundColor": "#fff"<span style="color: rgba(0, 0, 0, 1)">,
      </span>"position": "bottom"<span style="color: rgba(0, 0, 0, 1)">,
      </span>"borderStyle": "black"<span style="color: rgba(0, 0, 0, 1)">,
      </span>"list"<span style="color: rgba(0, 0, 0, 1)">: [{
                </span>"pagePath": "pages/home/index"<span style="color: rgba(0, 0, 0, 1)">,
                </span>"text": "首页"<span style="color: rgba(0, 0, 0, 1)">,
                </span>"iconPath": "./static/icon/_home.png"<span style="color: rgba(0, 0, 0, 1)">,
                </span>"selectedIconPath": "./static/icon/home.png"<span style="color: rgba(0, 0, 0, 1)">
            },
            {
                </span>"pagePath": "pages/horizontal/index"<span style="color: rgba(0, 0, 0, 1)">,
                </span>"text": "横屏"<span style="color: rgba(0, 0, 0, 1)">,
                </span>"iconPath": "./static/icon/_img.png"<span style="color: rgba(0, 0, 0, 1)">,
                </span>"selectedIconPath": "./static/icon/img.png"<span style="color: rgba(0, 0, 0, 1)">
            },
            {
                </span>"pagePath": "pages/video/index"<span style="color: rgba(0, 0, 0, 1)">,
                </span>"text": "精美视频"<span style="color: rgba(0, 0, 0, 1)">,
                </span>"iconPath": "./static/icon/_videocamera.png"<span style="color: rgba(0, 0, 0, 1)">,
                </span>"selectedIconPath": "./static/icon/videocamera.png"<span style="color: rgba(0, 0, 0, 1)">
            },
            {
                </span>"pagePath": "pages/search/index"<span style="color: rgba(0, 0, 0, 1)">,
                </span>"text": "搜索"<span style="color: rgba(0, 0, 0, 1)">,
                </span>"iconPath": "./static/icon/_search.png"<span style="color: rgba(0, 0, 0, 1)">,
                </span>"selectedIconPath": "./static/icon/search.png"<span style="color: rgba(0, 0, 0, 1)">
            },
            {
                </span>"pagePath": "pages/mine/index"<span style="color: rgba(0, 0, 0, 1)">,
                </span>"text": "我的"<span style="color: rgba(0, 0, 0, 1)">,
                </span>"iconPath": "./static/icon/_my.png"<span style="color: rgba(0, 0, 0, 1)">,
                </span>"selectedIconPath": "./static/icon/my.png"<span style="color: rgba(0, 0, 0, 1)">
            }
      ]
    }

}</span></pre>
</div>
<span class="cnblogs_code_collapse">pages.json</span></div>
<p>接下来我们需要在App.vue中全局引入字体图标文件。</p>
<div class="cnblogs_code"><img id="code_img_closed_12790ec9-9b55-4166-8d27-18f4d0e8f860" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_12790ec9-9b55-4166-8d27-18f4d0e8f860" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_12790ec9-9b55-4166-8d27-18f4d0e8f860" class="cnblogs_code_hide">
<pre>&lt;script&gt;<span style="color: rgba(0, 0, 0, 1)">
    export </span><span style="color: rgba(0, 0, 255, 1)">default</span><span style="color: rgba(0, 0, 0, 1)"> {
      onLaunch: </span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">() {
      },
      onShow: </span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">() {
      },
      onHide: </span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">() {
      }
    }
</span>&lt;/script&gt;

&lt;style&gt;<span style="color: rgba(0, 0, 0, 1)">
    @import </span>"./styles/iconfont.wxss"<span style="color: rgba(0, 0, 0, 1)">;
    @import </span>"./styles/base.wxss"<span style="color: rgba(0, 0, 0, 1)">;
</span>&lt;/style&gt;</pre>
</div>
<span class="cnblogs_code_collapse">App.vue</span></div>
<p>引入成功之后,就可以看到如下效果啦。</p>
<p><img src="https://img2018.cnblogs.com/i-beta/1783433/202003/1783433-20200301140219908-1839573506.png" alt="" width="352" height="490"></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><strong>&nbsp;注意:要记得把icon和styles文件夹放到项目中去哦。</strong></p>
<p>styles文件加放到和App.vue同层级目录下,icon文件夹放入static文件夹里面。</p>
<p>&nbsp;</p>
<h4>2.2 uni-ui介绍</h4>
<p>文档:&nbsp;https://uniapp.dcloud.io/component/README?id=uniui&nbsp;</p>
<p>uni-ui是DCloud提供的一个跨端ui库,它是基于vue组件的、flex布局的、无dom的跨全端ui框架。</p>
<p>&nbsp;uni-ui不包括基础组件,它是基础组件的补充:</p>
<p>&nbsp;数字角标、日历、卡片、折叠面板、倒计时、抽屉、悬浮按钮、收藏按钮、底部购物导航、宫格、图标、索引列表、列表、加载更多、自定义导航栏、通告栏、数字输入框、分页器、弹出层、评分、搜索栏、分段器、步骤条、滑动操作、轮播图指示点、标签。</p>
<p>&nbsp;</p>
<h3>3.首页模块开发准备</h3>
<h4>3.1&nbsp;功能分析</h4>
<p>1.修改导航栏外观</p>
<p>2.使用<strong>分段器组件</strong>搭建子页面</p>
<p>3.封装自己的异步请求</p>
<p>&nbsp;</p>
<h4>3.2&nbsp;搭建子页面</h4>
<ul>
<li>首页模块分为4个部分,分别是&nbsp;推荐、分类、最新、专辑</li>
新建自定义组件来代替上述的4个页面
<ul>
<li>home-recommend</li>
<li>home-category</li>
<li>home-new</li>
<li>home-album</li>
</ul>
</ul>
<h4>&nbsp;3.2.1 分段器介绍</h4>
<p>&nbsp;分段器是指uni-ui中的一个组件,其实就是俗称的标签页,tab栏(https://ext.dcloud.net.cn/plugin?id=54)</p>
<p><img src="https://img2020.cnblogs.com/i-beta/1783433/202003/1783433-20200306155051956-1808105151.png" alt="" width="450" height="220"></p>
<h4>3.2.2 分段器使用</h4>
<div class="cnblogs_code"><img id="code_img_closed_b754db25-aaad-4199-91c8-896d06bb1c68" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_b754db25-aaad-4199-91c8-896d06bb1c68" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_b754db25-aaad-4199-91c8-896d06bb1c68" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">template</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">view</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">view</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">uni-segmented-control
      </span><span style="color: rgba(255, 0, 0, 1)">:current</span><span style="color: rgba(0, 0, 255, 1)">="current"</span><span style="color: rgba(255, 0, 0, 1)">
      :values</span><span style="color: rgba(0, 0, 255, 1)">="items.map(v=&gt;v.title)"</span><span style="color: rgba(255, 0, 0, 1)">
      @clickItem</span><span style="color: rgba(0, 0, 255, 1)">="onClickItem"</span><span style="color: rgba(255, 0, 0, 1)">
      style-type</span><span style="color: rgba(0, 0, 255, 1)">="text"</span><span style="color: rgba(255, 0, 0, 1)">
      active-color</span><span style="color: rgba(0, 0, 255, 1)">="#d21974"</span>
      <span style="color: rgba(0, 0, 255, 1)">&gt;&lt;/</span><span style="color: rgba(128, 0, 0, 1)">uni-segmented-control</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">view </span><span style="color: rgba(255, 0, 0, 1)">class</span><span style="color: rgba(0, 0, 255, 1)">="content"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">view </span><span style="color: rgba(255, 0, 0, 1)">v-if</span><span style="color: rgba(0, 0, 255, 1)">="current === 0"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">view</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">view </span><span style="color: rgba(255, 0, 0, 1)">v-if</span><span style="color: rgba(0, 0, 255, 1)">="current === 1"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">view</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">view </span><span style="color: rgba(255, 0, 0, 1)">v-if</span><span style="color: rgba(0, 0, 255, 1)">="current === 2"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">view</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">view </span><span style="color: rgba(255, 0, 0, 1)">v-if</span><span style="color: rgba(0, 0, 255, 1)">="current === 3"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">view</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">view</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">view</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">view</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">template</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>

<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">script</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">
import { uniSegmentedControl } from </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">@dcloudio/uni-ui</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">;
export </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">default</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> {
components: {
    uniSegmentedControl
},
data() {
    </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">return</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> {
      items: [
      { title: </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">推荐</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> },
      { title: </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">分类</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> },
      { title: </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">最新</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> },
      { title: </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">专辑</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> }
      ],
      current: </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">0</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">
    };
},
methods: {
    onClickItem(e) {
      </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">if</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> (</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">this</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">.current </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">!==</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> e.currentIndex) {
      </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">this</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">.current </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> e.currentIndex;
      }
    }
}
};
</span><span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">script</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>

<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">style </span><span style="color: rgba(255, 0, 0, 1)">lang</span><span style="color: rgba(0, 0, 255, 1)">="scss"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>

<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">style</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span></pre>
</div>
<span class="cnblogs_code_collapse">分段器的使用</span></div>
<p>&nbsp;</p>
<h4>3.3&nbsp;封装自己的异步请求</h4>
<p><strong>为什么要封装?</strong></p>
<ol>
<li>原生的请求不支持promise;</li>
<li>uni-api的请求不能够方便的添加请求中效果;</li>
<li>uni-api的请求返回值是个数组,不方便取值;</li>
</ol>
<p><strong>封装的思路</strong></p>
<ol>
<li>基于原生promise来封装;</li>
<li>挂载到Vue的原型上;</li>
<li>通过this.request的方式来使用;</li>
</ol>
<div class="cnblogs_code"><img id="code_img_closed_f12aae58-5e09-4eb0-95ca-92ded37f9149" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_f12aae58-5e09-4eb0-95ca-92ded37f9149" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_f12aae58-5e09-4eb0-95ca-92ded37f9149" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">
基于原生promise封装request
发请求之前显示'加载中...'
请求完成之后隐藏'加载中...'
</span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">

export </span><span style="color: rgba(0, 0, 255, 1)">default</span> (params) =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
uni.showLoading({
    title: </span>'加载中'<span style="color: rgba(0, 0, 0, 1)">
});
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">new</span> Promise((resolve, reject)=&gt;<span style="color: rgba(0, 0, 0, 1)">{
    wx.request({
      ...params,
      success(res) {
      resolve(res.data);
      },
      fail(err) {
      reject(err);
      },
      complete(){
      uni.hideLoading();
      }
    })
})
}</span></pre>
</div>
<span class="cnblogs_code_collapse">request</span></div>
<p>在main.js里面将request函数挂载到Vue的原型上</p>
<p><img src="https://img2020.cnblogs.com/i-beta/1783433/202003/1783433-20200306174307724-191496377.png" alt=""></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h3>4.首页-推荐模块开发</h3>
<h4>4.1&nbsp;功能介绍</h4>
<ol>
<li>数据动态渲染;</li>
<li>moment.js的使用;</li>
<li>基于scroll-view的分页加载;</li>
</ol>
<h4><strong>4.2&nbsp;实现过程</strong></h4>
<p>首页推荐这个页面非常简单,没有任何技术含量。。。</p>
<p>首先我们把静态页面写出来,然后发送请求获取数据然后使用v-for指令循环渲染数据,渲染图片的时候注意接口有没有带rule这个属性,如果有需要把thumb属性和rule进行拼接,这里约定好&lt;Height&gt;的值为300,然后注意一下图像要使用widthFix还是aspectFill,这些都是非常基础的知识,大家可以自行到微信小程序的官方开发文档里面找到,如果你不懂,还不愿意自己去找资料学习,那我也没办法啦。</p>
<p>日期部分使用的是moment.js库,下面是他的文档地址:</p>
<p>http://momentjs.cn/docs/#/displaying/</p>
<p><img src="https://img2020.cnblogs.com/i-beta/1783433/202003/1783433-20200309121014277-33214869.png" alt="" width="479" height="391"></p>
<p>&nbsp;</p>
<p>接下来说一说分页,无非就是把最顶级的view 标签改成scroll-view标签,加上一个scroll-y属性,再加上一个触底事件@scrolltolower=“handleScrollToLower”即可,这些东西uni-app官网都有,由于这个项目是使用uni-app来开发,所以很多API和组件都需要在uni-app文档和微信小程序的文档穿插查找,搞技术嘛,就是要往上面砸时间,耐心点就完事了。</p>
<p>分页部分的逻辑其实很简单:</p>
<p>页面触底之后,发送请求获取数据,skip的值等于自身加上limit的值,然后limit的值加上30条,需要注意的是在触底之后发送请求之前要判断是否还有新的limit数据,可以在data里面设置一个状态,比如hasLimit:true,然后在请求函数里面判断一下是否还有新数据返回,如果没有的话就将hasLimit的值改为false并且提示用户。</p>
<div class="cnblogs_code"><img id="code_img_closed_1e16380c-7e82-4825-8906-d2bcce96a398" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_1e16380c-7e82-4825-8906-d2bcce96a398" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_1e16380c-7e82-4825-8906-d2bcce96a398" class="cnblogs_code_hide">
<pre>&lt;template&gt;
&lt;scroll-<span style="color: rgba(0, 0, 0, 1)">view
    scroll</span>-<span style="color: rgba(0, 0, 0, 1)">y
    @scrolltolower</span>="handleScrollToLower"<span style="color: rgba(0, 0, 0, 1)">
    class</span>="container"<span style="color: rgba(0, 0, 0, 1)">
    v</span>-<span style="color: rgba(0, 0, 255, 1)">if</span>="recommentList.length!==0"
&gt;
    &lt;!-- 推荐部分图片 start --&gt;
    &lt;view class="recomment-wrap"&gt;
      &lt;view class="item" v-<span style="color: rgba(0, 0, 255, 1)">for</span>="item in recommentList" :key="item.id"&gt;
      &lt;image :src="item.thumb" mode="widthFix" /&gt;
      &lt;/view&gt;
    &lt;/view&gt;
    &lt;!-- 推荐部分图片 end --&gt;

    &lt;!-- 月份图片部分 start --&gt;
    &lt;view class="month-wrap"&gt;
      &lt;view class="month-title"&gt;
      &lt;view class="month-info"&gt;
          &lt;view class="month-time"&gt;
            &lt;text class="day"&gt;{{monthList.day}} /&lt;/text&gt;
            &lt;text class="month"&gt;{{monthList.month}} 月&lt;/text&gt;
          &lt;/view&gt;
          &lt;view class="month-text"&gt;{{monthList.title}}&lt;/view&gt;
      &lt;/view&gt;
      &lt;view class="month-more"&gt;更多&gt;&lt;/view&gt;
      &lt;/view&gt;
      &lt;view class="month-content"&gt;
      &lt;view class="item" v-<span style="color: rgba(0, 0, 255, 1)">for</span>="item in monthList.items" :key="item.id"&gt;
          &lt;image :src="item.thumb + item.rule.replace('$&lt;Height&gt;',300)" mode="aspectFill" /&gt;
      &lt;/view&gt;
      &lt;/view&gt;
    &lt;/view&gt;
    &lt;!-- 月份图片部分 end --&gt;

    &lt;!-- 热门部分 start --&gt;
    &lt;view class="hot-wrap"&gt;
      &lt;view class="hot-title"&gt;
      &lt;text class="title-text"&gt;热门&lt;/text&gt;
      &lt;/view&gt;
      &lt;view class="hot-content"&gt;
      &lt;view class="hot-item" v-<span style="color: rgba(0, 0, 255, 1)">for</span>="item in hotList" :key="item.id"&gt;
          &lt;image :src="item.thumb" mode="widthFix" /&gt;
      &lt;/view&gt;
      &lt;/view&gt;
    &lt;/view&gt;
    &lt;!-- 热门部分 end --&gt;
&lt;/scroll-view&gt;
&lt;/template&gt;

&lt;script&gt;<span style="color: rgba(0, 0, 0, 1)">
export </span><span style="color: rgba(0, 0, 255, 1)">default</span><span style="color: rgba(0, 0, 0, 1)"> {
data() {
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> {
      params: {
      limit: </span>30<span style="color: rgba(0, 0, 0, 1)">,
      order: </span>"hot"<span style="color: rgba(0, 0, 0, 1)">,
      skip: </span>0<span style="color: rgba(0, 0, 0, 1)">
      },
      recommentList: [],
      monthList: [],
      hotList: [],
      hasLimit: </span><span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">
    };
},
mounted() {
    </span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.getList();
},
methods: {
    getList() {
      </span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.request({
      url: </span>"http://157.122.54.189:9088/image/v3/homepage/vertical"<span style="color: rgba(0, 0, 0, 1)">,
      data: </span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.params
      }).then(data </span>=&gt;<span style="color: rgba(0, 0, 0, 1)"> {
      </span><span style="color: rgba(0, 0, 255, 1)">if</span> (<span style="color: rgba(0, 0, 255, 1)">this</span>.monthList.length === 0<span style="color: rgba(0, 0, 0, 1)">) {
          </span><span style="color: rgba(0, 0, 255, 1)">this</span>.recommentList = data.res.homepage.items;
          </span><span style="color: rgba(0, 0, 255, 1)">this</span>.monthList = data.res.homepage;
          </span><span style="color: rgba(0, 0, 255, 1)">this</span>.monthList.day = <span style="color: rgba(0, 0, 255, 1)">this</span>.moment(<span style="color: rgba(0, 0, 255, 1)">this</span>.monthList.stime).format("DD"<span style="color: rgba(0, 0, 0, 1)">);
          </span><span style="color: rgba(0, 0, 255, 1)">this</span>.monthList.month = <span style="color: rgba(0, 0, 255, 1)">this</span>.moment(<span style="color: rgba(0, 0, 255, 1)">this</span>.monthList.stime).format("MM"<span style="color: rgba(0, 0, 0, 1)">);
      }
      </span><span style="color: rgba(0, 0, 255, 1)">if</span> (data.res.vertical.length === 0<span style="color: rgba(0, 0, 0, 1)">) {
          </span><span style="color: rgba(0, 0, 255, 1)">this</span>.hasLimit = <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;
          uni.showToast({
            title: </span>"没有更多数据啦"<span style="color: rgba(0, 0, 0, 1)">,
            icon: </span>"none"<span style="color: rgba(0, 0, 0, 1)">
          });
          </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)">;
      }
      </span><span style="color: rgba(0, 0, 255, 1)">this</span>.hotList = [...<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.hotList, ...data.res.vertical];
      </span><span style="color: rgba(0, 0, 255, 1)">this</span>.params.skip += <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.params.limit;
      </span><span style="color: rgba(0, 0, 255, 1)">this</span>.params.limit += 30<span style="color: rgba(0, 0, 0, 1)">;
      });
    },
    handleScrollToLower() {
      </span><span style="color: rgba(0, 0, 255, 1)">if</span> (<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.hasLimit) {
      </span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.getList();
      } </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
      uni.showToast({
          title: </span>"没有更多数据啦"<span style="color: rgba(0, 0, 0, 1)">,
          icon: </span>"none"<span style="color: rgba(0, 0, 0, 1)">
      });
      }
    }
}
};
</span>&lt;/script&gt;

&lt;style lang="scss"&gt;<span style="color: rgba(0, 0, 0, 1)">
.container {
height: calc(100vh </span>-<span style="color: rgba(0, 0, 0, 1)"> 35px);
}
</span><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)"> 推荐图片部分</span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">
.recomment</span>-<span style="color: rgba(0, 0, 0, 1)">wrap {
display: flex;
flex</span>-<span style="color: rgba(0, 0, 0, 1)">wrap: wrap;
</span>&gt;<span style="color: rgba(0, 0, 0, 1)"> .item {
    width: </span>50%<span style="color: rgba(0, 0, 0, 1)">;
    image {
      border: 3rpx solid #fff;
    }
}
}

</span><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)"> 月份图片部分 </span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">
.month</span>-<span style="color: rgba(0, 0, 0, 1)">wrap {
.month</span>-<span style="color: rgba(0, 0, 0, 1)">title {
    display: flex;
    justify</span>-content: space-<span style="color: rgba(0, 0, 0, 1)">between;
    padding: 20rpx 20rpx;
    .month</span>-<span style="color: rgba(0, 0, 0, 1)">info {
      display: flex;
      font</span>-<span style="color: rgba(0, 0, 0, 1)">weight: bold;
      .month</span>-<span style="color: rgba(0, 0, 0, 1)">time {
      color: $color;
      .day {
          font</span>-<span style="color: rgba(0, 0, 0, 1)">size: 32rpx;
      }

      .month {
          font</span>-<span style="color: rgba(0, 0, 0, 1)">size: 26rpx;
      }
      }

      .month</span>-<span style="color: rgba(0, 0, 0, 1)">text {
      margin</span>-<span style="color: rgba(0, 0, 0, 1)">left: 20rpx;
      color: #</span>666<span style="color: rgba(0, 0, 0, 1)">;
      font</span>-<span style="color: rgba(0, 0, 0, 1)">size: 32rpx;
      }
    }

    .month</span>-<span style="color: rgba(0, 0, 0, 1)">more {
      font</span>-<span style="color: rgba(0, 0, 0, 1)">size: 28rpx;
      color: $color;
    }
}

.month</span>-<span style="color: rgba(0, 0, 0, 1)">content {
    display: flex;
    flex</span>-<span style="color: rgba(0, 0, 0, 1)">wrap: wrap;
    .item {
      width: </span>33.33%<span style="color: rgba(0, 0, 0, 1)">;
      image {
      border: 5rpx solid #fff;
      }
    }
}
}

</span><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)"> 热门部分 </span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">
.hot</span>-<span style="color: rgba(0, 0, 0, 1)">wrap {
.hot</span>-<span style="color: rgba(0, 0, 0, 1)">title {
    padding: 20rpx;
    text.title</span>-<span style="color: rgba(0, 0, 0, 1)">text {
      padding</span>-<span style="color: rgba(0, 0, 0, 1)">left: 14rpx;
      color: $color;
      border</span>-<span style="color: rgba(0, 0, 0, 1)">left: 10rpx solid $color;
      font</span>-<span style="color: rgba(0, 0, 0, 1)">size: 28rpx;
      font</span>-<span style="color: rgba(0, 0, 0, 1)">weight: bold;
    }
}

.hot</span>-<span style="color: rgba(0, 0, 0, 1)">content {
    display: flex;
    flex</span>-<span style="color: rgba(0, 0, 0, 1)">wrap: wrap;
    .hot</span>-<span style="color: rgba(0, 0, 0, 1)">item {
      width: </span>33.33%<span style="color: rgba(0, 0, 0, 1)">;
      image {
      border: 5rpx solid #fff;
      }
    }
}
}
</span>&lt;/style&gt;</pre>
</div>
<span class="cnblogs_code_collapse">首页推荐组件代码</span></div>
<p>后续还要加上跳转功能,到时候会将跳转抽离成一个公共组件,到时在下文补充。</p>
<p>&nbsp;</p>
<h3>5.首页-专辑模块开发</h3>
<h4>&nbsp;5.1&nbsp;功能介绍</h4>
<ol>
<li>swiper轮播图部分</li>
<li>专辑列表部分</li>
</ol>
<h4><strong>5.2&nbsp;实现过程</strong></h4>
<p>轮播图的部分直接使用微信小程序官方提供的swiper组件,注意swiper组件默认宽度100%,高度是150px,而且swiper必须和swiper-item配对出现,否则会出问题,下面是小程序基础教程和官方文档:</p>
<p>基础教程:https://www.cnblogs.com/replaceroot/p/11262929.html</p>
<p>官方文档:https://developers.weixin.qq.com/miniprogram/dev/component/swiper.html</p>
<p>搞定了轮播之后就很容易了,写一下静态页面,发下请求然后渲染数据,注意对分页数据的判断就行啦,对你们来说绝对是小菜一碟,代码如下:</p>
<div class="cnblogs_code"><img id="code_img_closed_cb6efc8c-a6a9-418c-a6bc-6b4c4c0bb4b0" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_cb6efc8c-a6a9-418c-a6bc-6b4c4c0bb4b0" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_cb6efc8c-a6a9-418c-a6bc-6b4c4c0bb4b0" class="cnblogs_code_hide">
<pre>&lt;template&gt;
&lt;scroll-view scroll-y="true" @scrolltolower="handleScrollToLower" class="album-wrap"&gt;
    &lt;!-- 轮播图部分 start --&gt;
    &lt;swiper class="swiper" indicator-dots="true" autoplay="true" interval="3000" circular="true"&gt;
      &lt;swiper-item v-<span style="color: rgba(0, 0, 255, 1)">for</span>="item in banner" :key="item.id"&gt;
      &lt;image :src="item.thumb" mode="widthFix" /&gt;
      &lt;/swiper-item&gt;
    &lt;/swiper&gt;
    &lt;!-- 轮播图部分 end --&gt;

    &lt;!-- 专辑列表部分 start --&gt;
    &lt;view class="album-list"&gt;
      &lt;<span style="color: rgba(0, 0, 0, 1)">navigator
      :url</span>="`/pages/album/index?id=${item.id}`"<span style="color: rgba(0, 0, 0, 1)">
      class</span>="album-item"<span style="color: rgba(0, 0, 0, 1)">
      v</span>-<span style="color: rgba(0, 0, 255, 1)">for</span>="item in album"<span style="color: rgba(0, 0, 0, 1)">
      :key</span>="item.id"
      &gt;
      &lt;view class="album-image"&gt;
          &lt;image :src="item.cover" mode="aspectFill" /&gt;
      &lt;/view&gt;
      &lt;view class="album-info"&gt;
          &lt;view class="alubm-name ellipsis"&gt;{{item.name}}&lt;/view&gt;
          &lt;view class="alubm-desc ellipsis"&gt;{{item.desc}}&lt;/view&gt;
          &lt;view class="attention"&gt;
            &lt;view class="attention-btn"&gt;+关注&lt;/view&gt;
          &lt;/view&gt;
      &lt;/view&gt;
      &lt;/navigator&gt;
    &lt;/view&gt;
    &lt;!-- 专辑列表部分 end --&gt;

&lt;/scroll-view&gt;
&lt;/template&gt;

&lt;script&gt;<span style="color: rgba(0, 0, 0, 1)">
export </span><span style="color: rgba(0, 0, 255, 1)">default</span><span style="color: rgba(0, 0, 0, 1)"> {
data() {
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> {
      banner: [],
      album: [],
      params: {
      limit: </span>30<span style="color: rgba(0, 0, 0, 1)">,
      skip: </span>0<span style="color: rgba(0, 0, 0, 1)">,
      order: </span>"new"<span style="color: rgba(0, 0, 0, 1)">
      },
      hasLimit: </span><span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">
    };
},
methods: {
    getList() {
      </span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.request({
      url: </span>"http://157.122.54.189:9088/image/v1/wallpaper/album"<span style="color: rgba(0, 0, 0, 1)">,
      data: </span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.params
      }).then(data </span>=&gt;<span style="color: rgba(0, 0, 0, 1)"> {
      </span><span style="color: rgba(0, 0, 255, 1)">if</span> (<span style="color: rgba(0, 0, 255, 1)">this</span>.album.length === 0<span style="color: rgba(0, 0, 0, 1)">) {
          </span><span style="color: rgba(0, 0, 255, 1)">this</span>.banner =<span style="color: rgba(0, 0, 0, 1)"> data.res.banner;
      }
      </span><span style="color: rgba(0, 0, 255, 1)">if</span> (data.res.album.length === 0<span style="color: rgba(0, 0, 0, 1)">) {
          </span><span style="color: rgba(0, 0, 255, 1)">this</span>.hasLimit = <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;
          uni.showToast({
            title: </span>"没有更多的数据啦!"<span style="color: rgba(0, 0, 0, 1)">,
            icon: </span>"none"<span style="color: rgba(0, 0, 0, 1)">
          });
          </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)">;
      }
      </span><span style="color: rgba(0, 0, 255, 1)">this</span>.album = [...<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.album, ...data.res.album];
      </span><span style="color: rgba(0, 0, 255, 1)">this</span>.params.skip += <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.params.limit;
      </span><span style="color: rgba(0, 0, 255, 1)">this</span>.params.limit += 30<span style="color: rgba(0, 0, 0, 1)">;
      });
    },
    handleScrollToLower() {
      </span><span style="color: rgba(0, 0, 255, 1)">if</span> (<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.hasLimit) {
      </span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.getList();
      } </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
      uni.showToast({
          title: </span>"没有更多数据啦!"<span style="color: rgba(0, 0, 0, 1)">,
          icon: </span>"none"<span style="color: rgba(0, 0, 0, 1)">
      });
      }
    }
},
mounted() {
    </span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.getList();
}
};
</span>&lt;/script&gt;

&lt;style lang="scss"&gt;
<span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)"> 公共样式 </span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">
.ellipsis {
text</span>-<span style="color: rgba(0, 0, 0, 1)">overflow: ellipsis;
overflow: hidden;
white</span>-<span style="color: rgba(0, 0, 0, 1)">space: nowrap;
}

</span><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)"> 专辑轮播图部分 </span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">
.album</span>-<span style="color: rgba(0, 0, 0, 1)">wrap {
height: calc(100vh </span>-<span style="color: rgba(0, 0, 0, 1)"> 35px);
.swiper {
    height: 320rpx;
    image {
    }
}
}

</span><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)"> 专辑列表部分 </span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">
.album</span>-<span style="color: rgba(0, 0, 0, 1)">list {
padding: 10rpx;
.album</span>-<span style="color: rgba(0, 0, 0, 1)">item {
    display: flex;
    padding: 10rpx;
    border</span>-<span style="color: rgba(0, 0, 0, 1)">bottom: 3rpx solid #d5d5d5;
    .album</span>-<span style="color: rgba(0, 0, 0, 1)">image {
      flex: </span>1<span style="color: rgba(0, 0, 0, 1)">;
      image {
      width: 200rpx;
      height: 200rpx;
      }
    }

    .album</span>-<span style="color: rgba(0, 0, 0, 1)">info {
      flex: </span>3<span style="color: rgba(0, 0, 0, 1)">;
      margin</span>-<span style="color: rgba(0, 0, 0, 1)">left: 40rpx;
      overflow: hidden;
      .alubm</span>-<span style="color: rgba(0, 0, 0, 1)">name {
      color: #</span>000<span style="color: rgba(0, 0, 0, 1)">;
      }

      .alubm</span>-<span style="color: rgba(0, 0, 0, 1)">desc {
      color: #</span>666<span style="color: rgba(0, 0, 0, 1)">;
      }

      .attention {
      display: flex;
      justify</span>-content: flex-<span style="color: rgba(0, 0, 0, 1)">end;
      margin</span>-<span style="color: rgba(0, 0, 0, 1)">top: 10rpx;
      .attention</span>-<span style="color: rgba(0, 0, 0, 1)">btn {
          padding: </span>0<span style="color: rgba(0, 0, 0, 1)"> 5rpx;
          border: 3rpx solid $color;
          color: $color;
      }
      }
    }
}
}
</span>&lt;/style&gt;</pre>
</div>
<span class="cnblogs_code_collapse">home-album</span></div>
<p>&nbsp;</p>
<h3>6.专辑详情模块开发</h3>
<h4>6.1&nbsp;功能分析</h4>
<ol>
<li>头部背景图部分</li>
<li>专辑详情列表图片部分</li>
</ol>
<h4>6.2&nbsp;实现过程</h4>
<p>实现的过程也非常简单,首先放一张image图片当作背景图片,图片里面的文字都知道怎么做吧,直接用定位就完事了。</p>
<p>下面也是一样套路,先写静态页面,然后发请求,注意下图片的宽高,和mode模式就行了,具体的代码如下:</p>
<div class="cnblogs_code"><img id="code_img_closed_e488d57d-6aae-48e9-a71b-cffe59c57340" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_e488d57d-6aae-48e9-a71b-cffe59c57340" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_e488d57d-6aae-48e9-a71b-cffe59c57340" class="cnblogs_code_hide">
<pre>&lt;template&gt;
&lt;view class="album-detail-wrap"&gt;
    &lt;!-- 专辑详情背景部分 start --&gt;
    &lt;view class="album-background"&gt;
      &lt;image :src="album.cover" mode="widthFix" /&gt;
      &lt;view class="album-info"&gt;
      &lt;view class="album-name"&gt;{{album.name}}&lt;/view&gt;
      &lt;view class="attention"&gt;
          &lt;view class="attention-btn"&gt;关注专辑&lt;/view&gt;
      &lt;/view&gt;
      &lt;/view&gt;
    &lt;/view&gt;
    &lt;!-- 专辑详情背景部分 end --&gt;

    &lt;!-- 列表部分 start --&gt;
    &lt;view class="album-list"&gt;
      &lt;view class="album-title"&gt;
      &lt;view class="author"&gt;
          &lt;image :src="album.user.avatar" mode="aspectFill" /&gt;
          &lt;text class="author-name"&gt;{{album.user.name}}&lt;/text&gt;
      &lt;/view&gt;
      &lt;text class="album-desc"&gt;{{album.desc}}&lt;/text&gt;
      &lt;/view&gt;
      &lt;view class="album-content"&gt;
      &lt;view class="alubm-item" v-<span style="color: rgba(0, 0, 255, 1)">for</span>="item in wallpaper" :key="item.id"&gt;
          &lt;image :src="item.thumb + item.rule.replace('$&lt;Height&gt;',300)" mode="aspectFill" /&gt;
      &lt;/view&gt;
      &lt;/view&gt;
    &lt;/view&gt;
    &lt;!-- 列表部分 end --&gt;
&lt;/view&gt;
&lt;/template&gt;

&lt;script&gt;<span style="color: rgba(0, 0, 0, 1)">
export </span><span style="color: rgba(0, 0, 255, 1)">default</span><span style="color: rgba(0, 0, 0, 1)"> {
data() {
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> {
      params: {
      limit: </span>30<span style="color: rgba(0, 0, 0, 1)">,
      skip: </span>0<span style="color: rgba(0, 0, 0, 1)">,
      order: </span>"new"<span style="color: rgba(0, 0, 0, 1)">,
      first: </span>"1"<span style="color: rgba(0, 0, 0, 1)">
      },
      id: </span>""<span style="color: rgba(0, 0, 0, 1)">,
      album: [],
      wallpaper: [],
      hasLimit: </span><span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">
    };
},
methods: {
    getList() {
      </span><span style="color: rgba(0, 0, 255, 1)">if</span>(<span style="color: rgba(0, 0, 255, 1)">this</span>.album.length==0<span style="color: rgba(0, 0, 0, 1)">) {
      </span><span style="color: rgba(0, 0, 255, 1)">this</span>.params.first = '1'<span style="color: rgba(0, 0, 0, 1)">;
      }
      </span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.request({
      url: `http:</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">157.122.54.189:9088/image/v1/wallpaper/album/${this.id}/wallpaper`,</span>
      data: <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.params
      }).then(data </span>=&gt;<span style="color: rgba(0, 0, 0, 1)"> {
      </span><span style="color: rgba(0, 0, 255, 1)">if</span>(<span style="color: rgba(0, 0, 255, 1)">this</span>.album.length === 0<span style="color: rgba(0, 0, 0, 1)">) {
          </span><span style="color: rgba(0, 0, 255, 1)">this</span>.album =<span style="color: rgba(0, 0, 0, 1)"> data.res.album;
      }
      </span><span style="color: rgba(0, 0, 255, 1)">if</span>(data.res.wallpaper.length===0<span style="color: rgba(0, 0, 0, 1)">) {
          </span><span style="color: rgba(0, 0, 255, 1)">this</span>.hasLimit = <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;
          uni.showToast({
            title: </span>'没有数据啦'<span style="color: rgba(0, 0, 0, 1)">,
            icon: </span>'none'<span style="color: rgba(0, 0, 0, 1)">
          });
          </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)">;
      }
      </span><span style="color: rgba(0, 0, 255, 1)">this</span>.params.first = 0<span style="color: rgba(0, 0, 0, 1)">;
      </span><span style="color: rgba(0, 0, 255, 1)">this</span>.wallpaper = [...<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.wallpaper,...data.res.wallpaper];
      </span><span style="color: rgba(0, 0, 255, 1)">this</span>.params.skip += <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.params.limit;
      </span><span style="color: rgba(0, 0, 255, 1)">this</span>.params.limit += 30<span style="color: rgba(0, 0, 0, 1)">;
      });
    }
},
onReachBottom() {
    </span><span style="color: rgba(0, 0, 255, 1)">if</span>(<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.hasLimit) {
      </span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.getList();
    }</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
      uni.showToast({
      title: </span>'没有数据啦!'<span style="color: rgba(0, 0, 0, 1)">,
      icon: </span>'none'<span style="color: rgba(0, 0, 0, 1)">
      });
    }
},
onLoad(options) {
    </span><span style="color: rgba(0, 0, 255, 1)">this</span>.id =<span style="color: rgba(0, 0, 0, 1)"> options.id;
    </span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.getList();
}
};
</span>&lt;/script&gt;

&lt;style lang="scss"&gt;<span style="color: rgba(0, 0, 0, 1)">
.album</span>-detail-<span style="color: rgba(0, 0, 0, 1)">wrap {
</span><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)"> 专辑详情背景图部分 </span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">
.album</span>-<span style="color: rgba(0, 0, 0, 1)">background {
    position: relative;
    image {
    }

    .album</span>-<span style="color: rgba(0, 0, 0, 1)">info {
      position: absolute;
      bottom: </span>5%<span style="color: rgba(0, 0, 0, 1)">;
      display: flex;
      align</span>-<span style="color: rgba(0, 0, 0, 1)">items: center;
      justify</span>-content: space-<span style="color: rgba(0, 0, 0, 1)">between;
      width: </span>100%<span style="color: rgba(0, 0, 0, 1)">;
      padding: </span>0<span style="color: rgba(0, 0, 0, 1)"> 20rpx;
      .album</span>-<span style="color: rgba(0, 0, 0, 1)">name {
      color: #fff;
      font</span>-<span style="color: rgba(0, 0, 0, 1)">size: 32rpx;
      }

      .attention {
      display: flex;
      justify</span>-<span style="color: rgba(0, 0, 0, 1)">content: center;
      align</span>-<span style="color: rgba(0, 0, 0, 1)">items: center;
      .attention</span>-<span style="color: rgba(0, 0, 0, 1)">btn {
          padding: 10rpx 15rpx;
          background</span>-<span style="color: rgba(0, 0, 0, 1)">color: $color;
          color: #fff;
          border</span>-<span style="color: rgba(0, 0, 0, 1)">radius: 10rpx;
          font</span>-<span style="color: rgba(0, 0, 0, 1)">size: 26rpx;
      }
      }
    }
}

</span><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)"> 专辑详情列表部分 </span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">
.album</span>-<span style="color: rgba(0, 0, 0, 1)">list {
    .album</span>-<span style="color: rgba(0, 0, 0, 1)">title {
      padding: 10rpx;
      .author {
      display: flex;
      image {
          width: 60rpx;
          height: 60rpx;
      }

      text.author</span>-<span style="color: rgba(0, 0, 0, 1)">name {
          line</span>-<span style="color: rgba(0, 0, 0, 1)">height: 60rpx;
          margin</span>-<span style="color: rgba(0, 0, 0, 1)">left: 5rpx;
          color: #</span>000<span style="color: rgba(0, 0, 0, 1)">;
      }
      }

      text.album</span>-<span style="color: rgba(0, 0, 0, 1)">desc {
      color: #</span>666<span style="color: rgba(0, 0, 0, 1)">;
      font</span>-<span style="color: rgba(0, 0, 0, 1)">size: 26rpx;
      }
    }

    .album</span>-<span style="color: rgba(0, 0, 0, 1)">content {
      display: flex;
      flex</span>-<span style="color: rgba(0, 0, 0, 1)">wrap: wrap;
      .alubm</span>-<span style="color: rgba(0, 0, 0, 1)">item {
      width: </span>33.33%<span style="color: rgba(0, 0, 0, 1)">;
      image {
          height: 200rpx;
          border: 3rpx solid #fff;
      }
      }
    }
}
}
</span>&lt;/style&gt;</pre>
</div>
<span class="cnblogs_code_collapse">album/index.vue</span></div>
<p>最后有个小坑需要注意下,小程序里面的view标签不支持文本中的换行符,如果某些特殊场景中后台返回的文本里面包含换行符就直接使用text标签就完事了。</p>
<p><img src="https://img2020.cnblogs.com/i-beta/1783433/202003/1783433-20200309170217658-636383476.png" alt="" width="545" height="217"></p>
<p>&nbsp;</p>
<h3>7.图片详情模块开发</h3>
<h4>&nbsp;7.1&nbsp;功能分析</h4>
<ol>
<li>封装超链接组件</li>
<li>发送请求获取数据</li>
<li>使用moment.js处理特殊时间格式</li>
<li>封装手势滑动组件</li>
<li>调用API下载图片</li>
</ol>
<h4>7.2&nbsp;实现过程</h4>
<p>在components组件文件夹下面新建一个goDetail.vue的自定义组件</p>
<p><img src="https://img2020.cnblogs.com/i-beta/1783433/202003/1783433-20200314102455965-470228282.png" alt="" width="542" height="499"></p>
<div class="cnblogs_code"><img id="code_img_closed_e826b113-2bb1-4d10-b9e9-0245f5ede03c" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_e826b113-2bb1-4d10-b9e9-0245f5ede03c" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_e826b113-2bb1-4d10-b9e9-0245f5ede03c" class="cnblogs_code_hide">
<pre>&lt;template&gt;
&lt;view @click="handleClick"&gt;
    &lt;slot&gt;&lt;/slot&gt;
&lt;/view&gt;
&lt;/template&gt;

&lt;script&gt;<span style="color: rgba(0, 0, 0, 1)">
export </span><span style="color: rgba(0, 0, 255, 1)">default</span><span style="color: rgba(0, 0, 0, 1)"> {
props: {
    list: Array,
    index: Number
},
methods: {
    handleClick() {
      </span><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">
      1 将数据缓存下来 使用getApp()全局缓存方式
      2 实现点击跳转页面
      </span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">
   getApp().globalData.imgList </span>= <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.list;
   getApp().globalData.imgIndex </span>= <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.index;
   uni.navigateTo({
      url: </span>"/pages/imgDetail/index"<span style="color: rgba(0, 0, 0, 1)">
   });
    }
}
};
</span>&lt;/script&gt;

&lt;style&gt;
&lt;/style&gt;</pre>
</div>
<span class="cnblogs_code_collapse">goDetail.vue</span></div>
<p>这个地方用到了微信小程序的全局缓存数据的方法,我们把数据缓存在App.vue文件中,使用的时候直接通过getApp().globalData.属性的方法获取数据即可。</p>
<p><img src="https://img2020.cnblogs.com/i-beta/1783433/202003/1783433-20200314102732744-927854001.png" alt="" width="382" height="341"></p>
<p>&nbsp;</p>
<p>&nbsp;具体发请求获取数据渲染页面的部分自行看代码学习吧。</p>
<p>项目github地址:https://github.com/C4az6/dnpicture.git</p>
<p>项目API文档:https://www.showdoc.cc/414855720281749?page_id=3678621017219602</p>
<p>这个项目教程就此结束。</p>
<p>&nbsp;</p><br><br>
来源:https://www.cnblogs.com/sauronblog/p/12389126.html
頁: [1]
查看完整版本: 基于uni-app开发微信小程序__手牵手带你开发【懂你找图】项目