记一次小程序开发过程及问题

509 阅读4分钟

对于小程序,近来总是面试中问到会不会小程序。总是回答看过但是没有实战经验。在上一家公司因为没有小程序需求,自己看文档也总是觉得看会即学会。现在在新公司有机会接触到小程序,当然放手一搏!但是但是...总是能遇见意想不到的问题。

从现在开始记录一下小程序中用到的一些api及组件 开始完善小程序之旅

正文

rich-text

rich-text是微信小程序的基础内容——富文本标签,1.4.0开始支持

使用

    <rich-text class="wrap" :nodes="contentDetail"></rich-text>
    // contentDetail 为后端接口返回的富文本字符串内容,格式如下图

image.png

介绍

该标签有两个属性:nodes,space;如下: image.png

借用官方文档:以下几点需要注意,否则node会显示有误哦

image.png

问题

image.png 查阅了一些信息,nodes属性最好使Array形式,使用String字符串传递会有性能问题,不推荐,并且也会显示上图红色内容警告

关于样式

对于后端返回的富文本内容是没有样式概念的(同样没有事件概念且该标签也不识别任何事件)

所以 对于rich-text,我们可以使用自定义的方式进行样式调整,可以使用replace()方法:

contentDetail.replace(
    /<img|<p|<span|<ul|<ol|<li|<h[1-6]/gi,
    (match: string) => `${match} class="rich-${match.substr(1)}"`

通过正则表达式可以帮助给每个标签加上类:'rich-标签'(个人习惯),通过这种事方式就可以更好的有利于我们控制富文本内容。 当然,直接写span{}标签样式,也是可以生效的,但是基于程序员的痛,不要这样!

tips:如果样式不生效,可以加!important ,vue可以加/deep/)

nodesRef.boundingClientRect

需求本身:

1.点击锚点,滚动到指定位置, 实现页面锚点定位

2.获取文章滚动位置与整片文章高度的占比

样式

image.png

结构

image.png

过程

  1. 设置侧边栏tab,要设置埋点,首先必须要在tab设置其id
    <view
        class="left-nav-item"
        v-for="(navItem, index) in channeList"
        :key="navItem.id"
        :class="{
            activeNav: activeNav === navItem.id
        }"
        :id="navItem.id"
        :data-id="navItem.id"
        :data-title="navItem.title"
        @click="clickCurNav"
    >
        {{ navItem.title }}
    </view>
  1. 设置右边滚动区域,设置滚动dom设置id(tips:不能是数字)
<scroll-view
    scroll-y="true"
    scroll-with-animation="true"
    :scroll-into-view="toViewId"
    :style="'height: ' + popHeight + 'px'"
    @scroll="pageScroll">
    <view class="right-nav-pad">
        <view
            class="right-nav_block stage-detail"
            v-for="item in list"
            :key="item.id"
        >
            <text class="navItem_title" :id="`stage_${item.id}`">{{
                item.title
            }}</text>
        </view>
    </view>
</scroll-view>

2.获取文档流总长度

自己遇到的问题:
    因为vue中可以使用ref进行拿到dom节点从而获取该节点的总长度,但是在小程序行不通

查询了下资料及看了下以前同事代码,了解到小程序中获取某个dom节点的高度,需要使用该方法进行获取 使用方式:

uni.createSelectorQuery()
    .in(this)
    .selectAll('类')
    .boundingClientRect((rect: any) => {
        _this.popHeight = rect[0].height
    })
    .exec()

3.问题

① uni.createSelectorQuery().select() 找不到对应的元素

② rect获取不到想要的高度

解释

  1. uni.createSelectorQuery()返回一个selectQuery对象实例,可以在这个实例上使用select等方法选择节点 需要在生命周期mounted后进行调用

image.png

  1. uni.createSelectorQuery().in(component) 将选择器的选取范围更改为某个conponent, 也返回一个selectQuery对象实力---支付宝小程序不支持 image.png

  2. .select(selector):在当前页面下选择第一个匹配选择器selector节点,返回一个NodeRef对象实例

    .selectAll(selector):在当前页面下选择匹配selector的所有节点

    .selectViewport():选择显示区域,可用于获取显示区域的尺寸,滚动位置等信息

    .exec(callback):执行所有请求,请求结果按请求次序构成数组,在cb的第一个参数中返回。

  3. NodeRef 用于获取节点信息的对象

nodesRef.fields(object,callback)

获取节点的相关信息,第一个参数是节点相关信息配置(必),第二个参数是方法的回调函数

nodesRef.boundingClientRect(callback)

添加节点的布局位置的查询请求,类似DOM的getBoundingClientRect, 返回NodeRef对应的SelectorQuery(截图来自官网) image.png eg:

uni.createSelectorQuery()
      .selectAll('.stage-detail')
      .boundingClientRect((rect: any) => {
      //rect为一个数组
        // rect[0].height ===> 可以拿到整个文档流的高度(若是加载接口数据形成的文档流, 需要在加载后获取高度,否则拿不到哦)
          const topArrTemp: any[] = []
          rect.forEach((item: any, index: number) => {
              _this.lineHeight += item.height
              // 获取每个节点的高度,用于点击nav时计算右侧滚动的高度
              let topTemp: number = 0
              for (let i = 0; i < index; i++) {
                  topTemp += rect[i].height
              }
              topArrTemp.push(topTemp)
          })
          _this.stageTopArr = stageTopArr
      })
      .exec()

nodesRef.scrollOffset(callback)

添加节点的滚动位置查询请求,以像素为单位,节点必须为scroll-view或者viewport,返回NodeRef对应的SelectorQuery

image.png

nodesRef.context(callback)

添加节点的Context对象的查询请求(部分小程序支持)

image.png

nodesRef.node(callback)

获取Node节点实例,目前支持Canvas