# dnpicture **Repository Path**: xuzeting/dnpicture ## Basic Information - **Project Name**: dnpicture - **Description**: 懂你找图项目,uni-app vue - **Primary Language**: Unknown - **License**: MulanPSL-1.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 3 - **Forks**: 0 - **Created**: 2020-10-16 - **Last Updated**: 2022-04-17 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## 懂你找图项目(uni-app 开发)项目记录 ### 快速使用说明 进入项目 ``` npm install npm run dev:mp-weixin ``` 在微信开发者工具中导入dist/dev/mp-weixin 即可体验 ##### 用脚手架创建 uni-app 项目 ``` vue create -p dcloudio/uni-preset-vue my-project ``` ##### 安装插件 ``` npm i sass-loader node-sass ``` ##### 编译成微信小程序 ``` npm run dev:mp-weixin ``` 创建 pages 页面下的 tabbar 上的五个 vue 组件,并在 page.json 中配置 pages 和 tabBar。 ==对文件进行修改后,小程序容易报错,可以尝试重启== ==tip:在 vue 文件中导入 wxss 文件时,一定不要忘记加后缀== #### 首页推荐页面 ##### uni-ui ``` npm install @dcloudio/uni-ui -D ``` 在 `script` 中引用组件: ```javascript import { uniBadge } from '@dcloudio/uni-ui' //import uniBadge from '@dcloudio/uni-ui/lib/uni-badge/uni-badge.vue' //也可使用此方式引入组件 export default { components: { uniBadge }, } ``` 在 `template` 中使用组件: ```html ``` 使用分段器把首页的四个选项 bar 写好并完成样式。 ##### 异步请求封装 然后就是封装自己的异步请求,在 src 下简历 utils 文件,在下创建 request.js,在其中写入 ```javascript // es6 promise 微信小程序的api的铺垫 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 中引入上述文件并挂在到 vue 原型上 ```javascript import request from './utils/request' ``` ##### 推荐页面后端接口 "http://157.122.54.189:9088/image/v3/homepage/vertical" ##### moment.js 利用 moment.js 第三方库来对时间戳进行修改 安装 ``` npm i moment ``` ```javascript //将时间戳进行修改 this.months.MM = moment(this.months.stime).format('MM') this.months.DD = moment(this.months.stime).format('DD') ``` ##### 图片大小调整 在后端接口获取图片后,需要再加上大小参数,具体如下 ```html ``` ##### v-if 优化渲染 ```vue v-if="recommends.length>0" ``` ##### 滚动改造 scroll-view ```html ``` ##### 分页处理(触底加载新的图片) ```javascript handleToLower() { /* 1 修改参数 skip+=limit; 2 重新发送请求 getList() 3 请求回来成功 hots 数据的叠加 */ if (this.hasMore) { this.params.skip += this.params.limit; this.getList(); } else { // 弹窗提示用户 uni.showToast({ title: "没有数据了", icon: "none", }); } }, //热门数据列表,利用es6拼接刷新 this.hots = [...this.hots, ...result.res.vertical]; //判断是否还有新的数据 if (result.res.vertical.length === 0) { this.hasMore = false; uni.showToast({ title: "没有更多数据了", icon: "none" }); return; } ``` #### 首页专辑页面 ##### 专辑页面后端接口 "http://157.122.54.189:9088/image/v1/wallpaper/album", ##### 轮播 ```css .album_swiper { swiper { // 750rpx 326.0869565217392 // height: calc(750rpx / 2.3 ); height: 326.1rpx; image { height: 100%; } } } ``` ```html ``` ##### 列表 文字单行显示且尾部省略号表示 ```css text-overflow: ellipsis; overflow: hidden; white-space: nowrap; ``` 父容器需要加上以下 css,防止其溢出撑开父容器 ```css overflow: hidden; ``` ##### 分页处理 ```javascript handleToLower() { // console.log("武汉加油!!"); if (this.hasMore) { this.params.skip += this.params.limit; this.getList(); } else { uni.showToast({ title: "没有数据了", icon: "none" }); } } } ``` 请求函数 ```javascript getList() { this.request({ url: "http://157.122.54.189:9088/image/v1/wallpaper/album", data: this.params }).then(result => { if (this.banner.length === 0) { this.banner = result.res.banner; } if (result.res.album.length === 0) { this.hasMore = false; uni.showToast({ title: "没有更多数据了", icon: "none" }); return; } this.album = [...this.album, ...result.res.album]; }); }, ``` ##### 专辑详情 在 pages 下增加 album 文件夹,下面加 index.vue 文件,并在 pages.json 中进行配置 ##### 给详情页传 id ```javascript :url="`/pages/album/index?id=${item.id} ``` ```javascript onLoad(options) { console.log(options);//打印参数 this.id = options.id;//将参数中的id赋值给全局变量id }, ``` ##### 关于换行的一些 tip 如果接口返回的字符串中含有一些特殊符号如换行符‘\n’,则千万别用 view,要是用 text 标签 ##### 处理一个数组是否有内容 ```javascript if (Object.keys(this.album).length === 0) ``` ##### 接口挂了 再尝试首页图片导航的时候,发现提供的接口已经挂了,所以采用王俊凯的那个接口进行统一替代 #### 图片详情 ##### 全局存储数据和页面跳转 首先在各个需要传递参数的页面内传递参数 ```vue ``` 然后在 components 下的 goDetail.vue 组件内接收参数 ```javascript handleClick() { // 1 将数据缓存下拉 getApp().globalData.imgList = this.list; getApp().globalData.imgIndex = this.index; uni.navigateTo({ url: "/pages/imgDetail/index",//页面跳转 }); }, ``` ##### 图片详情页获取全局存储的数据 ```javascript data() { return { imgDetail: {}, }; }, onLoad() { console.log(getApp().globalData);//打印获取的列表 const { imgList, imgIndex } = getApp().globalData; this.imgDetail = imgList[imgIndex]; }, ``` ##### 防止因数据还未加载而先渲染报错 在加载时先设置变量进行赋值,再传给标签进行渲染可防止报错 ```javascript onLoad() { console.log(getApp().globalData); const { imgList, imgIndex } = getApp().globalData; this.imgDetail = imgList[imgIndex]; this.imgDetail.newThumb = this.imgDetail.thumb + this.imgDetail.rule.replace("$", 360); console.log(this.imgDetail.newThumb); }, ``` ##### 加载缩略图 ```javascript this.imgDetail.newThumb = this.imgDetail.thumb + this.imgDetail.rule.replace('$', 360) ``` ##### uni-ui 的点赞和收藏图标 ```vue {{ imgDetail.rank }} 收藏 ``` ##### 再次使用 moment 库处理时间 ```javascript this.imgDetail.cnTime = moment(this.imgDetail.atime * 1000).fromNow() ``` 将格式处理成中文 ```javascript moment.locale('zh-cn') ``` ##### 评论部分 获取评论接口数据 ```javascript getComments(id) { this.request({ url: `http://157.122.54.189:9088/image/v2/wallpaper/wallpaper/${id}/comment`, }).then((result) => { console.log(result); }); }, ``` 然后在 onload 中调用 ```javascript this.getComments(this.imgDetail.id) ``` ##### 接口再次出了一些问题 由于原来接口请求返回内容中缺少了 album,所以我采用全局存储的 imgList 来取代 album,具体 如下 ```javascript getComments(id) { this.request({ url: `http://157.122.54.189:9088/image/v2/wallpaper/wallpaper/${id}/comment`, }).then((result) => { this.album = getApp().globalData.imgList; console.log(this.album, "hello"); this.hot = result.res.hot; this.comment = result.res.comment; }); }, ``` ##### 只想循环第一项 目前只想到了在循环项上加上 v-if 限制,不过这样 eslint 会报错, 之后再完善吧 ##### swiperAction 组件 ```vue /* 1 slot 2 对外提供数据 滑动的方向 */ ``` imgDetail 中的处理 ```javascript handleSwiperAction(e) { /* 1 用户 左滑 imgIndex++ 2 用户 右滑 imgIndex-- 3 判断 数组是否越界问题!! 4 左滑 e.direction==="left"&&this.imgIndex0 */ const { imgList } = getApp().globalData; if (e.direction === "left" && this.imgIndex < imgList.length - 1) { // 可以进行 左滑 加载下一页 this.imgIndex++; this.getData(); } else if (e.direction === "right" && this.imgIndex > 0) { // 右滑 加载上一页 this.imgIndex--; this.getData(); } else { uni.showToast({ title: "没有数据了", icon: "none", }); } }, ``` ##### 下载图片 ```javascript async handleDownload() { // uni.downloadFile // uni.saveImageToPhotosAlbum await uni.showLoading({ title: "下载中", }); // 1 将远程文件下载到小程序的内存中 tempFilePath const result1 = await uni.downloadFile({ url: this.imgDetail.img }); const { tempFilePath } = result1[1]; // 2 将小程序内存中的临时文件下载到本地上 const result2 = await uni.saveImageToPhotosAlbum({ filePath: tempFilePath, }); // console.log(result2); // 3 提示用户下载成功 // console.log("下载城市"); uni.hideLoading(); await uni.showToast({ title: "下载成功", // icon }); }, ``` #### 分类页面 ##### 温故滚动窗口,以及flex与滚动标签之间的小冲突解决 ```vue ``` ```css .category_tab_content { display: flex; flex-wrap: wrap; height: calc(100vh - 36px);//这是关键!!!!!!!!!!!!!!!!! .cate_item { width: 33.33%; border: 5rpx solid #fff; } } ``` ##### 解决一些分页小bug ```javascript this.params.skip = 0;//将跳过数据重置 this.vertical = [];//将数据列表重置 ``` ##### 点击两次相同分页呢? ```javascript if (this.current !== e.currentIndex) { this.current = e.currentIndex; } else { // 点击的是相同的标题 return; } ``` ##### 使用统一组件显示页面时如何重新请求数据 ```javascript watch: { urlobj() { // console.log("参数发生变化了"); // console.log(this.urlobj); this.videowp=[]; this.getList(); } }, ``` ##### 背景滤镜 ```CSS image { position: absolute; width: 100vw; height: 100vh; z-index: -1; // css3 滤镜 filter: blur(20px); } ``` ##### 视频标签写法 ```HTML ``` ##### 视频下载实现 ```javascript async handleDownload() { await uni.showLoading({ title: "下载中" }); // 1 将远程文件 下载到小程序内存中 const { tempFilePath } = ( await uni.downloadFile({ url: this.videoObj.video }) )[1]; // 2 将内存中的文件 下载到本地上 await uni.saveVideoToPhotosAlbum({ filePath: tempFilePath, }) ```