unicloud云开发进阶49-项目33 封装公共函数简化代码

939 阅读4分钟

改样式

如果用户只发布了一条标题,其他什么都没有发布。就会留下一些空白,这是因为图片和描述信息带的,不好看,可以通过判断是否有摘要和图片决定要不要显示摘要和图片的样式

image.png

这里之前是在首页中,直接引用的组件样式,在组件中,图片列表部分如果图片不存在就隐藏 描述信息部分通过if判断,没有摘要就不显示这个模块

    <!-- 内容部分 -->
    <view class="body">
      <view class="title" @click="goDetail">{{item.title}}</view>
      <!-- 有描述信息才显示这个模块 -->
      <view class="text" @click="goDetail" v-if="item.description">
        <view class="t">{{item.description}}</view>
      </view>
      <!-- 内容部分的缩略图 -->
      <!-- 有图片才显示这个模块 -->
      <view class="piclist" v-if="item.picurls.length">
        <!-- 如果只有一张图就给图片上下左右都加圆角 -->
        <view class="pic" :class="item.picurls.length==1 ? 'only':''" v-for="(pic, index) in item.picurls" :key="pic">
        <!-- <image :src="pic" mode="aspectFill"></image> -->
        <!-- 图片显示直接照上面这样写会报错,因为可能有一些没有图,得用三元表达式判断没有图的话这里显示一张默认图 -->
        <image @click="clickPic(index)" :src="pic != null ? pic :'../../static/images/pic2.jpg'" mode="aspectFill"></image>
        </view>
      </view>

用户名问题

如果是用手机号注册的,文章这里就不会有用户名和昵称,使用用户信息的地方多,可以抽一个方法出来

image.png

在工具类utils下的tools文件中定义一个方法

// 获取昵称
// 优先用昵称,其次是用户名,再次是手机号,最后是一个提示
export function giveName(item){
   return item.user_id[0].nickname || item.user_id[0].username ||item.user_id[0].mobile || "请设置昵称"
}

item是在blog-item中定义的属性

    props:{
      item:{
        type:Object,
        default(){
          return {}
        }
      }
    },

然后在子组件blog_item中引入

<script>
  import {giveName} from "../../utils/tools.js"
  export default {

还要把函数名写到methods中才能用,否则会报错,这是vue语法

    methods:{
      giveName,
      goDetail(){}

引入完成后,就可以在DOM结构中使用了 原来的代码是用昵称或用户名:

item.user_id[0].nickname ? item.user_id[0].nickname:item.user_id[0].username

现在改成昵称、用户名、手机号或者提示文字:

<!-- 如果有昵称就显示昵称,没有就显示用户名 -->
<view class="name">
    {{giveName(item)}}
</view>
以后在这里,有昵称的就显示昵称,没有就是用户名,没有用户名就是手机号或者提示

image.png

同样,头像部分也抽离到工具类中

// 获取默认头像
export function giveAvatar(item){
  // return item.user_id[0].avatar_file ? item.user_id[0].avatar_file.url : '../../static/images/user-default.jpg'
  // 使用可选链写法更简洁一些,然后前两个都不存在,就使用空值赋值
  return item.user_id[0]?.avatar_file?.url ?? '../../static/images/user-default.jpg'
}

引入

import { giveName, giveAvatar } from "../../utils/tools.js"
    methods:{
      giveName,
      giveAvatar,
      //点击跳转到详情页
      goDetail(){
        uni.navigateTo({
        ...

在子组件blog-item中使用

<view class="avatar">
    <!-- 有头像就用头像,没有就用默认头像 -->
    <image :src="giveAvatar(item)" 
    mode="aspectFill"></image>
</view>

在详情页detail中也使用这个公共方法,使用时传的参数就是detailObj了,因为这个页面定义的用户信息是这个对象

// 用户信息
detailObj:null
<view class="avatar">
    <image :src="giveAvatar(detailObj)" mode="aspectFill"></image>
</view>

根据登录状态修复详情页H5和小程序BUG

在未登录时进入详情页,会提示参数错误,因为会先判断登录信息,所以就会跳转到登录页面,之前在登录页面又写了一个退回到首页,所以,未登录时,进入详情页就会先跳转到登录页,紧接着就跳转到了首页

问题在detail中,获取详情页数据时,获取云空间中的用户ID:user_id==$cloudEnv_uid 并将点赞likeTemp表进行了联表查询db.collection(artTemp,userTemp,likeTemp) 但是用户未登录,这张表就是空的,就出现了参数有误提示

      // 获取数据库数据
      getData(){
        // 将主表副表都查出一个临时表来
        let artTemp = db.collection("quanzi_article").where(`_id=="${this.artId}"`).getTemp();
        let userTemp =  db.collection("uni-id-users").field("_id,username,nickname,avatar_file").getTemp();
        let likeTemp = db.collection("quanzi_like").where(`article_id=="${this.artId}" && user_id==$cloudEnv_uid`).getTemp();
        // 两张副表单独与主表关联,副表之间没有关系
        db.collection(artTemp,userTemp,likeTemp).get(
        {
          getOne:true
        }).then(res=>{
          console.log(res);
          // 如果data参数不存在吗,表示传递的参数id有误
          if(!res.result.data){
            this.errFun();
            return;
          }

          // 网络数据获取完成后将骨架屏状态重置为false
          this.loadState = false;
          // 是否点过赞
          let isLike = res.result.data._id.quanzi_like.length ? true : false;
          // 向返回值赋值 把是否点过赞赋给返回值
          res.result.data.isLike = isLike;
          // 把获取到的用户信息赋值
          this.detailObj = res.result.data
          uni.setNavigationBarTitle({
            // 将当前文章标题作为页面title
            title:this.detailObj.title
          })
        }).catch(err=>{
          this.errFun();
        })
      }

将联表查询时的likeTemp表删掉,然后将下面使用到这张表的代码注释掉就不会报错了

        // 两张副表单独与主表关联,副表之间没有关系
        db.collection(artTemp,userTemp).get(
        {
          getOne:true
        }).then(res=>{
          console.log(res);
          // 如果data参数不存在吗,表示传递的参数id有误
          if(!res.result.data){
            this.errFun();
            return;
          }

          // 网络数据获取完成后将骨架屏状态重置为false
          this.loadState = false;
          // 是否点过赞
          // let isLike = res.result.data._id.quanzi_like.length ? true : false;
          // 向返回值赋值 把是否点过赞赋给返回值
          // res.result.data.isLike = isLike;

判断hasLogin属性是否存在,先引入store.js

import { store } from "../../uni_modules/uni-id-pages/common/store.js"

测试haslogin

      // 获取数据库数据
      getData(){
        // 将主表副表都查出一个临时表来
        let artTemp = db.collection("quanzi_article").where(`_id=="${this.artId}"`).getTemp();
        let userTemp =  db.collection("uni-id-users").field("_id,username,nickname,avatar_file").getTemp();
        let likeTemp = db.collection("quanzi_like").where(`article_id=="${this.artId}" && user_id==$cloudEnv_uid`).getTemp();
        
        console.log(store.hasLogin);
        return;

返回true表示已经登录,返回false表示未登录,如果没有登陆,也不用查点赞表likeTemp了,联表查询时也不用写了进去了 image.png

      // 获取数据库数据
      getData(){
        // 将主表副表都查出一个临时表来
        let artTemp = db.collection("quanzi_article").where(`_id=="${this.artId}"`).getTemp();
        let userTemp =  db.collection("uni-id-users").field("_id,username,nickname,avatar_file").getTemp();
        let likeTemp = db.collection("quanzi_like").where(`article_id=="${this.artId}" && user_id==$cloudEnv_uid`).getTemp();
        // 如果已登录,就把点赞表push到数组中进行联表查询
        // push是向数组最后一位添加
        let tempArr = [artTemp,userTemp]
        if(store.hasLogin) tempArr.push(likeTemp)
        // 两张副表单独与主表关联,副表之间没有关系
        // 需要把数组tempArr展开才能放进来
        db.collection(...tempArr).get(
        {
          getOne:true
        }).then(res=>{
          console.log(res);
          // 如果data参数不存在吗,表示传递的参数id有误
          if(!res.result.data){
            this.errFun();
            return;
          }

下面是isLike部分

          // 是否点过赞
          // let isLike = res.result.data._id.quanzi_like.length ? true : false;
          // 向返回值赋值 把是否点过赞赋给返回值
          // res.result.data.isLike = isLike;
          
          // 如果已登录,将isLike变成true
          let isLike=false;
          // 如果登陆过,判断是否点过赞
          if(store.hasLogin) isLike = res.result.data._id?.quanzi_like?.length ? true : false;
          // 如果未登录过就是默认值false
          res.result.data.isLike = isLike;
          // 把获取到的用户信息赋值
          this.detailObj = res.result.data