avatar

uni-app项目实战(懂你找图)

前言

uni-app简介

  • uni-app 是一个使用 Vue.js语法来开发所有前端应用的框架,称为全端开发框架

配置环境

  • 脚手架搭建项目

    1. 全局安装
      • npm install -g @vue/cli
    2. 创建项目
      • vue create -p dcloudio/uni-preset-vue my-project
    3. 启动项目
      • npm run dev:mp-weixin
    4. 微信小程序开发工具导入项目
  • 项目目录

    │  App.vue             应用配置,用来配置App全局样式以及监听
    │ main.js Vue初始化入口文件
    │ manifest.json 配置应用名称、appid、logo、版本等打包信息
    │ pages.json 配置页面路由、导航条、选项卡等页面类信息
    │ uni.scss 内置的sass变量,可以直接使用

    |─pages
    │ └─index
    │ index.vue 页面组件

    └─static 静态资源
    logo.png
  • 样式和sass

    • 支持小程序的rpx 和 h5的vw、vh
    • 内置有sass的配置了,只需要 安装对应的依赖即可 “ npm install sass-loader node-sass ”
    • vue组件中,在 style 标签上 加入 属性 “

      模块基本功能

      image-20200513093805433

      搭建首页子页面

      • 首页模块分为 4个部分,分别是 推荐、分类、最新、专辑
      • 新建自定义组件来代替 上述的4个页面
      • home-recommend
      • home-category
      • home-new
      • home-album

      image-20200513105741735

      分段器使用

      image-20200513105830130

      <template>
      <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="#e63a7d"
      ></uni-segmented-control>
      </view>
      <view class="iconfont iconsearch"></view>
      </view>
      <view class="home_tab_content">
      <view v-if="current === 0">
      <recommend></recommend>
      </view>
      <view v-if="current === 1">
      <category></category>
      </view>
      <view v-if="current === 2">
      <anew></anew>
      </view>
      <view v-if="current === 3">
      <album></album>
      </view>
      </view>
      </view>
      </template>

      <script>
      import recommend from "./home-recommend/index.vue";
      import category from "./home-category/index.vue";
      import anew from "./home-new/index.vue";
      import album from "./home-album/index.vue";
      //引入
      import uniSegmentedControl from "../../../node_modules/@dcloudio/uni-ui/lib/uni-segmented-control/uni-segmented-control.vue";

      export default {
      components: {
      recommend,
      category,
      anew,
      album,
      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_title {
      position: relative;
      .title_inner {
      width: 70%;
      margin: 0 auto;
      }
      .iconsearch {
      position: absolute;
      top: 45%;
      transform: translateY(-50%);
      right: 6%;
      }
      }
      .home_tab_content {
      }
      </style>

      封装自己的异步请求

      • 为什么要封装

        • 原生的请求不支持 promise
        • uni-api 的请求不能够方便的添加 请求中 效果
        • uni-api 的请求返回值是个数组,不方便
      • 封装思路

        • 基于原生的promise来封装
        • 挂载到Vue的原型上
        • 通过 this.request 的方式来使用
      export default (params) => {
      uni.showLoading({
      title: "加载中",
      });

      return new Promise((resolve, reject) => {
      wx.request({
      ...params,
      success(res) {
      resolve(res.data);
      },
      fail(err) {
      resolve(err);
      },
      complete() {
      uni.hideLoading();
      },
      });
      });
      };

      首页推荐模块

      • 数据动态渲染

      • moment.js 的使用

      • 基于scroll-view的分页加载

      • 绑定滚动条触底事件 scrolltolower

      • 实现分页逻辑

        <template>
        <scroll-view
        @scrolltolower="handleToLower"
        class="recommend_view"
        scroll-y
        v-if="recommends.length"
        >
        <!-- 推荐开始 -->
        <view class="recommend_wrap">
        <navigator
        class="recommend_item"
        v-for="(item, index) in recommends"
        :key="index"
        :url="`/pages/ablum/index?id=${item.target}`"
        >
        <image mode="widthFix" :src="item.thumb"></image>
        </navigator>
        </view>
        <!-- 推荐结束 -->

        <!-- 月份开始 -->
        <view class="moneths_wrap">
        <view class="moneths_title">
        <view class="moneths_title_info">
        <view class="moneths_info">
        <text>{{ monthes.DD }}</text>
        /{{ monthes.MM }}月
        </view>
        <view class="moneths_text">{{ monthes.title }}</view>
        </view>
        <view class="moneths_title_more">更多 ></view>
        </view>
        <view class="moneths_content">
        <view
        class="moneths_item"
        v-for="(item, index) in monthes.items"
        :key="index"
        >
        <godetail :list="monthes.items" :index="index">
        <image
        mode="aspectFill"
        :src="item.thumb + item.rule.replace('$<Height>', 360)"
        ></image>
        </godetail>
        </view>
        </view>
        </view>
        <!-- 月份结束 -->

        <!-- 热门开始 -->
        <view class="hots_wrap">
        <view class="hots_title">
        <text>热门</text>
        </view>
        <view class="hots_content">
        <view class="hot_item" v-for="(item, index) in hots" :key="index">
        <godetail :list="hots" :index="index">
        <image mode="widthFix" :src="item.thumb"></image>
        </godetail>
        </view>
        </view>
        </view>
        <!-- 热门结束 -->
        </scroll-view>
        </template>

        <script>
        import moment from "moment";
        import godetail from "../../../components/goDetail";
        export default {
        data() {
        return {
        recommends: [],
        monthes: {},
        hots: [],
        params: {
        limit: 30,
        order: "hot",
        skip: 0,
        },
        havemore: true,
        };
        },
        components: {
        godetail,
        },
        mounted() {
        uni.setNavigationBarTitle({
        title: "推荐",
        });
        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.havemore = false;
        return;
        }
        if (this.recommends.length === 0) {
        this.recommends = result.res.homepage[1].items;
        this.monthes = result.res.homepage[2];
        this.monthes.MM = moment(this.monthes.stime).format("MM");
        this.monthes.DD = moment(this.monthes.stime).format("DD");
        }
        this.hots = [...this.hots, ...result.res.vertical];
        });
        },
        handleToLower: function() {
        if (this.havemore) {
        this.params.skip += this.params.limit;
        this.getList();
        } else {
        uni.showTabBar({
        title: "到底了",
        icno: "none",
        });
        }
        },
        },
        };
        </script>

        <style lang="scss" scoped>
        .recommend_view {
        height: calc(100vh - 36px);
        }

        .recommend_wrap {
        display: flex;
        flex-wrap: wrap;
        .recommend_item {
        width: 50%;
        border: 5rpx solid #fff;
        }
        }

        .moneths_wrap {
        .moneths_title {
        display: flex;
        justify-content: space-between;
        padding: 20rpx;
        .moneths_title_info {
        display: flex;
        .moneths_info {
        color: $themeColor;
        font-weight: 600;
        text {
        font-size: 36rpx;
        }
        }

        .moneths_text {
        padding-left: 15rpx;
        font-weight: 600;
        font-size: 34rpx;
        color: #666;
        }
        }

        .moneths_title_more {
        font-size: 24rpx;
        color: $themeColor;
        font-weight: 600;
        }
        }

        .moneths_content {
        display: flex;
        flex-wrap: wrap;
        .moneths_item {
        width: 33.33%;
        border: 5rpx solid #fff;
        }
        }
        }

        .hots_wrap {
        .hots_title {
        padding: 20rpx;
        text {
        padding-left: 20rpx;
        border-left: 10rpx solid $themeColor;
        font-size: 30rpx;
        font-weight: 600;
        }
        }

        .hots_content {
        display: flex;
        flex-wrap: wrap;
        .hot_item {
        width: 33.33%;
        border: 5rpx solid #fff;
        }
        }
        }
        </style>

        视频图片下载功能

        async handledownload() {
        await uni.showLoading({ title: "下载中" });

        const { temFilePath } = (
        await uni.downloadFile({ url: this.videoObj.video })
        )[1];
        await uni.saveVideoToPhotosAlbum({
        filePath: temFilePath,
        });

        uni.hideLoading();
        await uni.showToast({
        title: "下载成功",
        });
        },

        页面展示

        image-20200513111559242

        image-20200513111636461

        image-20200513111714246

        image-20200513111828261

        image-20200513112032881

文章作者: Lhl
文章链接: https://lhl-cpu.github.io/2020/04/30/uni-app/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 趁年轻
打赏
  • 微信
    微信
  • 支付宝
    支付宝

评论