微信小程序的按钮toogle效果

创建一个公用的导航navBar组件,让它可以在所有页面使用,比如在index.wxml,引用navBar组件,方法如下
  • 1.在需要引用组件的页面中的json中定义这个组件
//index.json
{
  "usingComponents": {
    "nav-bar": "/component/navBar/navBar"//自定义组件的名称,组件的路径
  }
}
  • 2.在需要引用组件组件的页面中的wxml中引用这个组件
//index.wxml
<nav-bar></nav-bar>
  • 3.在组件的json文件中“开启组件”
//navBar.json
{
  "component": true
}
  • 4.组件navBar.wxml内部的代码
//navBar.wxml
<view>我是navBar</view>
<!--渲染列表btnChildrenArray,并且绑定了clickTest方法,设置索引为index-->
<view class="test" wx:for="{{btnChildrenArray}}" bindtap='clickTest' data-index="{{index}}" wx:key="{{item.id}}">
    {{item.name}}
    <!--每个一级菜单的下拉的部分,wx:if根据js中的status[index]的值,来控制是否渲染某一个下拉部分-->
      <view wx:if="{{status[index]}}">
      <!--每一个一级菜单的下拉部分的列表渲染,渲染msg部分-->
        <block wx:for="{{item.msg}}" wx:for-item="todo"  wx:key="todo.id">
          <!--wx:if判断todo.url是否成立,成立就渲染navigator标签-->
          <navigator  wx:if="{{todo.url}}">
              {{todo.msgName}}
          </navigator> 
          <!--wx:if判断todo.methods是否成立,成立就渲染text标签-->
          <text  wx:elif="{{todo.methods}}" bindtap='{{todo.methods}}'>{{todo.msgName}}</text> 
          <!--wx:if判断todo.isContact,成立就渲染button标签-->
          <button wx:else="{{todo.isContact}}" open-type="contact" class='testClass'>{{todo.msgName}}</button> 
        </block>           
      </view>
</view>
  • 5.组件的wxss
//简单的样式,没什么好说的
.test{
  float: left;
  width: 200rpx;
  height:60rpx;
  line-height: 60rpx;
  text-align: center;
  border:1px solid;
}
  • 6.在组件的js中定义的数据和方法
//navBar.js

function statusList() {//定义在组件外部的函数,为了让内部的函数每次能够重新调用
  return [false, false, false];
}
Component({
  /**
   * 组件的属性列表
   */
  properties: {

  },

  /**
   * 组件的初始数据
   */
  data: {
    status: statusList(),//调用一次外部函数
    btnChildrenArray: [
      {
        id: 0,
        name: "按钮一",
        msg: [
          {
            id: 10,
            msgName: '000',
            url: '/aa'
          },
          {
            id: 20,
            msgName: '111',
            url: '/bb'
          },
          {
            id: 30,
            msgName: '222',
            url: '/ccaa'
          }
        ]
      },
      {
        id: 1,
        name: "按钮二",
        msg: [
          {
            id: 11,
            msgName: '999',
            url: '/aa'
          },
          {
            id: 12,
            msgName: '111',
            isContact: true
          },
          {
            id: 13,
            msgName: '222',
            url: '/aa'
          }
        ]
      },
      {
        id: 2,
        name: "按钮三",
        status: false,
        msg: [
          {
            id: 21,
            msgName: '888',
            url: '/aa'
          },
          {
            id: 22,
            msgName: '111',
            url: '/aa'
          },
          {
            id: 23,
            msgName: 'test',
            methods: 'test1'
          }
        ]
      },
    ]
  },

  /**
   * 组件的方法列表
   */
  methods: {
    test1: function () {//data中methods属性的值对应的函数
      console.log('test1234')
    },
    clickTest: function (e) {
      var index = parseInt(e.currentTarget.dataset.index)//可以console.log(e)查看到获取每次点击的索引值
      var listData = this.data.status//这是定义在data中的数组,第一次点击时为外部函数返回的数组
      //当点击第二次的时候,这里的数组值为上一次存储的值(setData方法),即某一个被改变了的值的数组
      var newStatusList = statusList()//这是调用外部函数,返回的数组
      //第二次点击之后,重新变为全部都是false,重点就在这里,每次返回的都是新的数组,即三个false
      if (listData[index] === false) {//我们要判断的数组值的这个数组,一定是data中定义的数组,即listData,不会判断外部函数返回的数组。因为newStatusList,这是每执行一次点击事件,都会重新调用外部函数,所以每一次走到这里时,它的值都是固定的值,都是外部函数返回的值。而data中的status只会调用一次外部函数,所以,他的值时相对固定的,不会再被外部函数改变
        newStatusList[index] = true//此时改变内部调用函数所返回的数组,如果改变的是listData,那下面的setData也要改成listData,这时如果第二次的index值不一样,那么status里第一次被更改的值无法被恢复,所以这也是有两个数组,且其中一个是每一次都会恢复默认值得原因
      } else {
        //console.log("haha")
      }
      this.setData({
        status: newStatusList//status等于方法返回的数组(即被改变的数组)
      })
      //console.log(newStatusList)
      //console.log(status)
    },
  }
})

这里面的点击toogle效果的主要实现过程,首先设置下拉的部分全部wx:if="status[index]",status数组中的每一项都为false,根据点击的index值,判断数组中索引为index的的项的值为是否为false,改写为true,即可渲染出下拉部分。

我们要实现第二次点击其他一级菜单的时候,第一次展开的一级菜单下的目录全部隐藏,只渲染当前一级菜单下的目录,就要在每第二次点击的时候,让status的每一项的值恢复为默认的全部为false的状态,然后再改变当前点击的index索引对应的status数组中的值。

但是我们又要实现,连续点击两次同一个按钮时,这个一级菜单有toggle效果,如果像上面那样把status恢复初始值,就不能实现toggle效果。

所以这个时候,需要两个数组,为了方便,可以在外部新建一个函数,返回一个数组,比如statusList()函数返回数组,在data中的status属性调用一次函数,此时可以在点击事件内部定义一个变量newStatusList,重新调用一次外部的函数,返回另一个数组。这时的两个数组的完全独立的。然后如果当前点击索引的值是否为false,就改变newStatusList的值,最后把newStatusList赋值给data中的status属性;如果为true,因为此时的点击事件内部会再一次调用外部函数statusList(),所以newStatusList得值会被恢复为初始状态,所以对应的true,会被改写成false,从而实现了toogle效果

具体的过程可以看上面的注释

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据提供的引用内容,可以看出uni-picker-custom和uni-picker-toggle是在一个Vue组件中使用的。在这个组件中,uni-picker-custom是一个自定义的选择器组件,而uni-picker-toggle是用来控制选择器的显示和隐藏的开关。当点击按钮时,会触发open方法,该方法会改变toogle的值,从而控制选择器的显示和隐藏。在样式中,uni-picker-toggle类被用来控制选择器的可见性和位置。\[1\]根据引用\[2\]中提供的信息,可以看出这个组件是在一个UI框架中使用的,可能是用于构建用户界面的工具。至于uni-picker-custom和uni-picker-toggle的具体实现和功能,需要查看更多的代码或文档来了解。 #### 引用[.reference_title] - *1* [uni picker 遮罩从下滑出](https://blog.csdn.net/sugang666/article/details/99692091)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [React Components](https://blog.csdn.net/Fuohua/article/details/79109478)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值