微信小程序首次进入引导提示自定义组件

实现效果展示
在这里插入图片描述

实现步骤

第一步(新建组件)

组件代码

<!--wxml-->
<view class="guide" wx:if="{{showGuide}}">
  <view style="{{guideStyle}}" class="guide-box">
    <view class="tips guide-step-tips" style="{{tipPosition}}">
      <view class="text">{{ guideList[index].tips }}</view>
      <view class="tool-btn">
        <text bind:tap="skip">跳过</text>
        <view class="next" style="" bind:tap="next">下一步</view>
      </view>
    </view>
    <view class="arrow" style="{{arrowTop}}"></view>
  </view>
  <!-- 遮罩层,防止点击 -->
  <view class="v-model"></view>
</view>
/* wxss */
.v-model {
    position: fixed;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    z-index: 1000;
}
.guide {
    z-index: 1001;
}
.guide-box {
    position: absolute;
    z-index: 10001;
    transition: all 0.2s;
    
}
.guide-box::before {
    content: '';
    height: 100%;
    width: 100%;
    border: 1px dashed #fff;
    border-radius: 8rpx;
    position: absolute;
    top: -8rpx;
    left: -8rpx;
    padding: 7rpx;
}
.arrow {
    height: 20rpx;
    width: 20rpx;
    background: #1cbbb4;
    position: absolute;
    top: 144rpx;
    left: 45%;
    transform: rotate(45deg);
}
.tips {
    width: 400rpx;
    background: linear-gradient(180deg, #1cbbb4, #0081ff);
    box-shadow: 0px 2px 9px 0px rgba(0, 0, 0, 0.1);
    color: #fff;
    position: absolute;
    top: 152rpx;
    left: -50%;
    padding: 15rpx 20rpx;
    font-size: 28rpx;
    border-radius: 12rpx;
}
 .tool-btn {
     display: flex;
     justify-content: space-between;
     align-items: center;
     padding-right: 0rpx;
     margin-top: 20rpx;
 }
 .next {
     background: #fff;
     height: 48rpx;
     width: 100rpx;
     text-align: center;
     border-radius: 8rpx;
     color: #666;
     line-height: 48rpx;
     font-size: 24rpx
 }
//json
{
    "component": true,
    "usingComponents": {}
}
// components/xky-guideStep/xky-guideStep.js
Component({
  /**
   * 组件的属性列表
   */
  properties: {
    step: {
      type: Object,
      default: () => {},
    },
  },

  /**
   * 组件的初始数据
   */
  data: {
    stepName: "step", //该提示步骤的名称,用于不在重复展示
    guideList: [],
    index: 0, // 当前展示的索引
    showGuide: true, // 是否显示引导
    guideStyle: "", // 默认样式
    arrowTop: "", //步骤提示三角形的定位
    tipPosition: "", //步骤提示的定位
    systemInfo: "", //屏幕宽度高度等信息
    tipWidth: 200, //步骤提示默认的宽度
  },

  /**
   * 组件的方法列表
   */
  methods: {
    // 展示新手提示
    viewTips(data, scrollTop) {
        console.log(data, scrollTop);
      let {
        systemInfo,
        tipWidth,
        index,
        guideList,
        arrowTop,
        tipPosition,
        guideStyle,
      } = this.data;
      if (data) {
          console.log(systemInfo);
        // 如果dom宽度大于或者等于窗口宽度,需要重新调整dom展示宽度
        let newWidth = systemInfo.windowWidth - 20;
        if (data.width >= newWidth) {
          data.width = newWidth;
        }
        // 如果距离左边为0,自动增加一点左边距
        if (data.left == 0) {
          data.left = 10;
        }
        let domRW = systemInfo.windowWidth - data.left;
        let left = 0;
        // 如果dom距离右边没有tips的宽度大的话,就要让tips向左便宜
        if (domRW < tipWidth) {
          left = domRW - tipWidth - 30;
        }
        // const index = index;
        // 步骤条展示的高度需要加上屏幕滚动的高度
        data.top += scrollTop;
        // 根据实际情况需要滚动到展示区域
        wx.pageScrollTo({
          scrollTop: data.top > 20 ? data.top - 20 : 0,
          duration: 100,
        });
        let obj = Object.assign(guideList[index], data);
        // 设置三角形高度
        let arrArrowTop = data.height + 9;
        arrowTop = "top:" + arrArrowTop + "px;";
        // 设置提示框定位
        tipPosition = "top:" + (arrArrowTop + 5) + "px;left:" + left + "px;";
        // 重新设置guideList的值
        guideList.splice(index, 1, obj);
        guideStyle = this.getStyle();
        console.log(arrowTop, tipPosition, guideList, guideStyle);
        this.setData({
          arrowTop,
          tipPosition,
          guideList,
          guideStyle,
        });
      } else {
        index += 1;
        this.setData({
          index,
        });
        this.getDomInfo();
      }
    },
    // 获取步骤提示的主要样式
    getStyle() {
        const { guideList, index } = this.data;
      const { width, height, left, top, style } = guideList[index];
      let newstyle = "width:" + width + "px;";
      newstyle += "height:" + height + "px;";
      newstyle += "left:" + left + "px;";
      newstyle += "top:" + top + "px;";
      newstyle +=
        "box-shadow: rgb(33 33 33 / 80%) 0px 0px 0px 0px, rgb(33 33 33 / 50%) 0px 0px 0px 5000px;";
      newstyle += style;
      return newstyle;
    },
    // 获取dom信息
    getDomInfo() {
        
      const { guideList, index } = this.data;
      console.log(guideList, index);
      const { el } = guideList[index];
         console.log(el);
    //   const query = wx.createSelectorQuery().in(this.$root);
      const query = wx.createSelectorQuery();
    //   console.log(query);
      setTimeout(() => {
        query.select(el).boundingClientRect();
        query.selectViewport().scrollOffset();
        var _this = this;
        query.exec(function (res) {
          console.log("打印demo的元素的信息", res);
          let data = res[0]; // #the-id节点的上边界坐标
          let scrollTop = res[1].scrollTop; // 显示区域的竖直滚动位置
          _this.viewTips(data, scrollTop);
        });
      }, 10);
    },
    skip() {
      this.setData({
        showGuide: false,
      });
      wx.setStorageSync(this.data.stepName, "true");
    },
    // 下一步
    next() {
      let { index, guideList, stepName } = this.data;
      if (index === guideList.length - 1) {
        this.setData({
          showGuide: false,
        });
        wx.setStorageSync(stepName, "true");
      } else {
        index += 1;
         this.setData({
           index,
         });
        this.getDomInfo();
      }
    },
  },
  lifetimes: {
    attached: function () {
      console.log(this.properties);
      const { step } = this.properties;
      let { guideList, stepName } = this.data;
      guideList = step.guideList;
      stepName = step.name;
    //   const systemInfo = wx.getSystemInfoSync();
    //   systemInfo = systemInfo;
      this.setData({
        guideList,
        stepName,
        systemInfo: wx.getSystemInfoSync(),
      });
      const guide = wx.getStorageSync(step.name);
      if (!guide) {
        this.getDomInfo();
      } else {
          this.setData({
            showGuide:false,
          });
        // this.showGuide = false;
      }
    },
    detached: function () {
      // 在组件实例被从页面节点树移除时执行
    },
  },
});

组件引入

在需要的页面,通过配置json文件引入

{
  "usingComponents": {
    "van-notice-bar": "@vant/weapp/notice-bar/index",
    "guideStep":"../../components/xky-guideStep/xky-guideStep"
    //注意组件引用的路径
  }
}
组件使用

在需要页面的wxml中引入,然后js文件的data配置中step属性。
注意:在页面需要高亮的部分,需要在节点中添加class。
在这里插入图片描述

<guideStep step="{{step}}"> </guideStep>
 <!--组件可以放在任意位置,建议放在页面的底部  -->

在这里插入图片描述
组件也可以在不同的页面复用,使用方法一样。

  • 6
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
微信小程序自定义组件是一种可以复用的UI组件,可以在不同的面中使用。在微信小程序中,我们可以通过使用`Component`函数来创建自定义组件。 要创建一个自定义组件,你需要在`components`目录下创建一个新的文件夹,并在该文件夹中创建一个`.json`、`.wxml`、`.wxss`和`.js`文件。其中,`.json`文件用于配置组件的属性、样式等信息,`.wxml`文件用于定义组件的结构,`.wxss`文件用于定义组件的样式,`.js`文件用于编写组件的逻辑。 在`.json`文件中,你可以配置组件的属性、样式等信息。例如: ```json { "component": true, "usingComponents": {}, "properties": {}, "data": {}, "methods": {} } ``` 在`.wxml`文件中,你可以使用标签和组件来定义组件的结构,并通过`{{}}`来绑定数据。例如: ```xml <view> <text>{{title}}</text> </view> ``` 在`.wxss`文件中,你可以定义组件的样式。例如: ```css text { color: #333; font-size: 16px; } ``` 在`.js`文件中,你可以编写组件的逻辑代码。例如: ```javascript Component({ properties: {}, data: {}, methods: {} }) ``` 然后,在需要使用自定义组件面中引入组件,并在面的`.json`文件中配置组件的路径。例如: ```json { "usingComponents": { "custom-component": "/components/custom-component/custom-component" } } ``` 最后,在面的`.wxml`文件中使用自定义组件。例如: ```xml <custom-component title="Hello World"></custom-component> ``` 这样就完成了一个简单的微信小程序自定义组件的创建和使用。希望能对你有所帮助!如果有更多问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值