微信小程序学习笔记(5) -- todos案例

简介: 微信小程序学习笔记(5) -- todos案例

TODOS案例:



项目介绍


https://github.com/zce/weapp-todos


样式书写


导航栏


效果:

1dc618a0ed9580ce8bfa6facb208c08f.png

具体代码:


<view class="search">
     <image src="../../images/plus.png"></image>
     <input type="text" placeholder="Anything here..." />
  </view>


/* pages/todos/todos.wxss */
.container{
  border-top: 1rpx solid #E0E0E0;
}
.search{
  display: flex; 
  align-items: center;
  margin: 20rpx;
  padding: 20rpx;
  border: 1px solid #ccc;
  border-radius: 5rpx;
  box-shadow: 0 0 5rpx #E0E0E0;  
}
.search input{
  flex: 1;
  height: 40rpx;  
}
.search image{
  width: 40rpx;
  height: 40rpx;
  margin-right: 20rpx;
}


todos


<view class="todos">
      <view class="item">
        <icon type="success" />
        <text>Learning HTML</text>
         <icon type="clear" size="16"/>
      </view>
      <view class="item">
          <icon type="circle" />
          <text>Learning CSS</text>
          <icon type="clear" size="16"/>
      </view>
      <view class="item">
          <icon type="circle" />
          <text>Learning Javascript</text>
          <icon type="clear" size="16" />
      </view>
  </view>


.todos{
  margin: 20rpx;
  border: 1px solid #ccc;
  border-radius: 5rpx;
  box-shadow: 0 0 5rpx #E0E0E0;  
}
.todos .item{
  display: flex;
  align-items: center;
  padding: 20rpx;
  border-bottom: 1rpx solid #E0E0E0;
  /* margin-bottom: -1px; */
}
.todos .item:last-child{
  border-bottom: 0;
}
.item text{
  flex: 1;
  margin-left: 20rpx;
  font-size: 30rpx;
  color: #444;
}


footer


<view class="footers">
  <text>Toggle All</text>
  <text>2 items left</text>
  <text>Clear completed</text>
</view>


.footers{
  display: flex;
  /* 内容对其方式 */
  justify-content: space-between;
  margin: 20rpx;
  font-size: 30rpx;
   color: #333;
}
.footers text{
  flex: 1;
  }


现在整体效果已经产生:

1dc618a0ed9580ce8bfa6facb208c08f.png



数据绑定


抽象数据模型


// pages/todos/todos.js
Page({
  /**
   * 页面的初始数据
   */
  data: {
      //文本框数据模型
      search: '',
      //任务清单数据模型
      todos: [
        {name: 'Learning WEAPP',completed: false},
        {name: 'Learning JavaScript',completed: false},
        {name: 'Learning HTML',completed: false}
      ]
  }
})


界面数据绑定


// pages/todos/todos.js
Page({
  /**
   * 页面的初始数据
   */
  data: {
      //文本框数据模型
      search: '',
      //任务清单数据模型
      todos: [
        {name: 'Learning WEAPP',completed: false},
        {name: 'Learning JavaScript',completed: true},
        {name: 'Learning HTML',completed: false}
      ]
  }
})


<!--pages/todos/todos.wxml-->
<view class="container">
  <view class="search">
     <image src="../../images/plus.png"></image>
     <input type="text" placeholder="Anything here..." value="{{search}}"/>
  </view>
  <view class="todos">
      <view class="item{{ item.completed ? ' completed' : '' }}" wx:for="{{ todos}}" >
        <icon type="{{item.completed? 'success':'circle'}}"  />
        <text>{{item.name}}</text>
         <icon type="clear" size="16"/>
      </view>    
  </view>
  <view class="footers">
    <text>Toggle All</text>
     <text>{{ todos.length }} items left</text>
     <text>Clear completed</text>
  </view>
</view>


页面效果:

1dc618a0ed9580ce8bfa6facb208c08f.png


界面交互操作


新增


目标1: 搜索框中添加的数据,加入到列表当中:


<!--pages/todos/todos.wxml-->
<view class="container">
  <view class="header">
     <image src="../../images/plus.png" bindtap="addTodoHandle"></image>
     <input type="text" placeholder="Anything here..." value="{{input}}" bindinput="inputChangeHandle"/>
  </view>
  <view class="todos">
      <view class="item{{ item.completed ? ' completed' : '' }}" wx:for="{{ todos}}" >
        <icon type="{{item.completed? 'success':'circle'}}"  />
        <text>{{item.name}}</text>
         <icon type="clear" size="16"/>
      </view>    
  </view>
  <view class="footers">
    <text>Toggle All</text>
     <text>{{ todos.length }} items left</text>
     <text>Clear completed</text>
  </view>
</view>


// pages/todos/todos.js
Page({
  /**
   * 页面的初始数据
   */
  data: {
      //文本框数据模型
      input: '',
      //任务清单数据模型
      todos: [
        {name: 'Learning WEAPP',completed: false},
        {name: 'Learning JavaScript',completed: true},
        {name: 'Learning HTML',completed: false}
      ]
  },
  inputChangeHandle: function(e){
    //body
    console.log(e.detail.value);
    this.setData({
      input: e.detail.value
    });
  },
  //1.先让按钮点击时 执行一段代码
  //2. 拿到文本框里面的值
  // 2.1 由于小程序的数据绑定是单向的,
  //       必须要给文本框注册改变事件
  //3. 将这个值添加到列表中
  addTodoHandle: function(){
     //当添加按钮点击事件发生时执行的函数
     console.log(this.data.input)
     var todos =  this.data.todos;
     todos.push({       
         name: this.data.input,
         completed: false
      })  
     //必须显式的通过setData去改变数据,这样界面才能得到变化
     this.setData({
      todos: todos
     });
  }
})


效果:

1dc618a0ed9580ce8bfa6facb208c08f.png5d4c6812c8535adbb050f4ddf2e1bce8.png


新增逻辑优化


刚才的代码中,如果是input的内容为空,点击+号,还是会添加到todo的列表中:

46a9d80a6e05e4e3b19d57a0ee70bcdf.png

逻辑优化: 只需要一行代码:

1dc618a0ed9580ce8bfa6facb208c08f.png


切换任务完成状态


在列表项上添加事件,改变选中项的completed的状态,然后setData赋值即可:


<!--pages/todos/todos.wxml-->
<view class="container">
  <view class="header">
     <image src="../../images/plus.png" bindtap="addTodoHandle"></image>
     <input type="text" placeholder="Anything here..." value="{{input}}" bindinput="inputChangeHandle"/>
  </view>
  <view class="todos">
      <view class="item{{ item.completed ? ' completed' : '' }}" 
      wx:for="{{ todos}}" bindtap="toggleTodoHandle" data-index="{{ index }}">
        <icon type="{{item.completed? 'success':'circle'}}"  />
        <text>{{item.name}}</text>
         <icon type="clear" size="16"/>
      </view>    
  </view>
  <view class="footers">
    <text>Toggle All</text>
     <text>{{ todos.length }} items left</text>
     <text>Clear completed</text>
  </view>
</view>



// pages/todos/todos.js
Page({
  /**
   * 页面的初始数据
   */
  data: {
      //文本框数据模型
      input: '',
      //任务清单数据模型
      todos: [
        {name: 'Learning WEAPP',completed: false},
        {name: 'Learning JavaScript',completed: true},
        {name: 'Learning HTML',completed: false}
      ]
  },
  inputChangeHandle: function(e){
    //body
    console.log(e.detail.value);
    this.setData({
      input: e.detail.value
    });
  },
  //1.先让按钮点击时 执行一段代码
  //2. 拿到文本框里面的值
  // 2.1 由于小程序的数据绑定是单向的,
  //       必须要给文本框注册改变事件
  //3. 将这个值添加到列表中
  addTodoHandle: function(){ S
     //当添加按钮点击事件发生时执行的函数
     if(!this.data.input)return
     console.log(this.data.input)     
     var todos =  this.data.todos;
     todos.push({       
         name: this.data.input,
         completed: false
      })  
     //必须显式的通过setData去改变数据,这样界面才能得到变化
     this.setData({
      todos: todos
     });
  },
  toggleTodoHandle:function(e){
    //切换当前点中的item的完成状态
    console.log(e.currentTarget);
    var item = this.data.todos[e.currentTarget.dataset.index]
    console.log(item)
    item.completed = !item.completed
    console.log(this.data.todos)
    this.setData({
       todos: this.data.todos
    })
  }
})


效果:

1dc618a0ed9580ce8bfa6facb208c08f.png


剩余任务数量展示


实现目标有3点:


1.若未选中的item的项数大于1,则 应为items left


2.如果为1,则应为item left


3.若没有可选的项,则不显示任务数量


4.注意动态切换任务数量


步骤,主要有3点:


1.定义一个leftCount属性来显示剩余未选项


2.在输入框中的+号点击的时候,添加1


3切换列表的状态时,如果选中的列表项的completed为true则是+1.否则减1


<!--pages/todos/todos.wxml-->
<view class="container">
  <view class="header">
     <image src="../../images/plus.png" bindtap="addTodoHandle"></image>
     <input type="text" placeholder="Anything here..." value="{{input}}" bindinput="inputChangeHandle"/>
  </view>
  <view class="todos">
      <view class="item{{ item.completed ? ' completed' : '' }}" 
      wx:for="{{ todos}}" bindtap="toggleTodoHandle" data-index="{{ index }}">
        <icon type="{{item.completed? 'success':'circle'}}"  />
        <text>{{item.name}}</text>
         <icon type="clear" size="16"/>
      </view>    
  </view>
  <view class="footers">
    <text>Toggle All</text>
     <text wx:if="{{ leftCount }}"> {{ leftCount }} {{leftCount > 1 ? 'items' : 'item' }} left</text>  
     <text>Clear completed</text>
  </view>
</view>
// pages/todos/todos.js
Page({
  /**
   * 页面的初始数据
   */
  data: {
      //文本框数据模型
      input: '',
      //任务清单数据模型
      todos: [
        {name: 'Learning WEAPP',completed: false},
        {name: 'Learning JavaScript',completed: true},
        {name: 'Learning HTML',completed: false}
      ],
      leftCount: 2
  },
  inputChangeHandle: function(e){
    //body
    console.log(e.detail.value);
    this.setData({
      input: e.detail.value
    });
  },
  //1.先让按钮点击时 执行一段代码
  //2. 拿到文本框里面的值
  // 2.1 由于小程序的数据绑定是单向的,
  //       必须要给文本框注册改变事件
  //3. 将这个值添加到列表中
  addTodoHandle: function(){ 
     //当添加按钮点击事件发生时执行的函数
     if(!this.data.input)return
     console.log(this.data.input)     
     var todos =  this.data.todos;  
     todos.push({       
         name: this.data.input,
         completed: false
      })  
     //必须显式的通过setData去改变数据,这样界面才能得到变化
     this.setData({
      todos: todos,
       input:'',
       leftCount: this.data.leftCount + 1  
     });
  },
  toggleTodoHandle:function(e){
    //切换当前点中的item的完成状态
    console.log(e.currentTarget);
    var item = this.data.todos[e.currentTarget.dataset.index]
    console.log(item)
    item.completed = !item.completed
    //根据当前任务额完成状态决定增加一个或者减少一个
    var leftCount = this.data.leftCount + (item.completed ? -1 : 1)
    console.log(this.data.todos)
    this.setData({
       todos: this.data.todos,
       leftCount: leftCount
    })
  }
})


删除任务逻辑


注意点:事件冒泡问题,用catchtap事件


<!--pages/todos/todos.wxml-->
<view class="container">
  <view class="header">
     <image src="../../images/plus.png" bindtap="addTodoHandle"></image>
     <input type="text" placeholder="Anything here..." value="{{input}}" bindinput="inputChangeHandle"/>
  </view>
  <view class="todos">
      <view class="item{{ item.completed ? ' completed' : '' }}" 
      wx:for="{{ todos}}" bindtap="toggleTodoHandle" data-index="{{ index }}">
        <icon type="{{item.completed? 'success':'circle'}}"  />
        <text>{{item.name}}</text>
         <icon type="clear" size="16" catchtap="removeToDoHandle" data-index="{{ index }}"/>
      </view>    
  </view>
  <view class="footers">
    <text>Toggle All</text>
     <text wx:if="{{ leftCount }}"> {{ leftCount }} {{leftCount > 1 ? 'items' : 'item' }} left</text>  
     <text>Clear completed</text>
  </view>
</view>


// pages/todos/todos.js
Page({
  /**
   * 页面的初始数据
   */
  data: {
      //文本框数据模型
      input: '',
      //任务清单数据模型
      todos: [
        {name: 'Learning WEAPP',completed: false},
        {name: 'Learning JavaScript',completed: true},
        {name: 'Learning HTML',completed: false}
      ],
      leftCount: 2
  },
  inputChangeHandle: function(e){
    //body
    console.log(e.detail.value);
    this.setData({
      input: e.detail.value
    });
  },
  //1.先让按钮点击时 执行一段代码
  //2. 拿到文本框里面的值
  // 2.1 由于小程序的数据绑定是单向的,
  //       必须要给文本框注册改变事件
  //3. 将这个值添加到列表中
  addTodoHandle: function(){ 
     //当添加按钮点击事件发生时执行的函数
     if(!this.data.input)return
     console.log(this.data.input)     
     var todos =  this.data.todos;  
     todos.push({       
         name: this.data.input,
         completed: false
      })  
     //必须显式的通过setData去改变数据,这样界面才能得到变化
     this.setData({
      todos: todos,
       input:'',
       leftCount: this.data.leftCount + 1  
     });
  },
  toggleTodoHandle:function(e){
    //切换当前点中的item的完成状态
    console.log(e.currentTarget);
    var item = this.data.todos[e.currentTarget.dataset.index]
    console.log(item)
    item.completed = !item.completed
    //根据当前任务额完成状态决定增加一个或者减少一个
    var leftCount = this.data.leftCount + (item.completed ? -1 : 1)
    console.log(this.data.todos)
    this.setData({
       todos: this.data.todos,
       leftCount: leftCount
    })
  },
  removeToDoHandle:function(e){
    var item = this.data.todos[e.currentTarget.dataset.index]
    this.data.leftCount =  item.completed ? this.data.leftCount : (this.data.leftCount - 1) ;
    this.data.todos.splice(e.currentTarget.dataset.index, 1)
    this.setData({
      todos: this.data.todos,
      leftCount: this.data.leftCount
   })
  }
})

运行效果:

1dc618a0ed9580ce8bfa6facb208c08f.png

显示已经删除:

1dc618a0ed9580ce8bfa6facb208c08f.png


切换全部任务状态(全选)


页面添加一个事件toggleAllHandle


<!--pages/todos/todos.wxml-->
<view class="container">
  <view class="header">
     <image src="../../images/plus.png" bindtap="addTodoHandle"></image>
     <input type="text" placeholder="Anything here..." value="{{input}}" bindinput="inputChangeHandle"/>
  </view>
  <view class="todos">
      <view class="item{{ item.completed ? ' completed' : '' }}" 
      wx:for="{{ todos}}" bindtap="toggleTodoHandle" data-index="{{ index }}">
        <icon type="{{item.completed? 'success':'circle'}}"  />
        <text>{{item.name}}</text>
         <icon type="clear" size="16" catchtap="removeToDoHandle" data-index="{{ index }}"/>
      </view>    
  </view>
  <view class="footers">
    <text bindtap="toggleAllHandle">Toggle All</text>
     <text wx:if="{{ leftCount }}"> {{ leftCount }} {{leftCount > 1 ? 'items' : 'item' }} left</text>  
     <text>Clear completed</text>
  </view>
</view>


js书写逻辑:


// pages/todos/todos.js
Page({
  /**
   * 页面的初始数据
   */
  data: {
      //文本框数据模型
      input: '',
      //任务清单数据模型
      todos: [
        {name: 'Learning WEAPP',completed: false},
        {name: 'Learning JavaScript',completed: true},
        {name: 'Learning HTML',completed: false}
      ],
      leftCount: 2,
      allCompleted: false
  },
  inputChangeHandle: function(e){
    //body
    console.log(e.detail.value);
    this.setData({
      input: e.detail.value
    });
  },
  //1.先让按钮点击时 执行一段代码
  //2. 拿到文本框里面的值
  // 2.1 由于小程序的数据绑定是单向的,
  //       必须要给文本框注册改变事件
  //3. 将这个值添加到列表中
  addTodoHandle: function(){ 
     //当添加按钮点击事件发生时执行的函数
     if(!this.data.input)return
     console.log(this.data.input)     
     var todos =  this.data.todos;  
     todos.push({       
         name: this.data.input,
         completed: false
      })  
     //必须显式的通过setData去改变数据,这样界面才能得到变化
     this.setData({
      todos: todos,
       input:'',
       leftCount: this.data.leftCount + 1  
     });
  },
  toggleTodoHandle:function(e){
    //切换当前点中的item的完成状态
    console.log(e.currentTarget);
    var item = this.data.todos[e.currentTarget.dataset.index]
    console.log(item)
    item.completed = !item.completed
    //根据当前任务额完成状态决定增加一个或者减少一个
    var leftCount = this.data.leftCount + (item.completed ? -1 : 1)
    console.log(this.data.todos)
    this.setData({
       todos: this.data.todos,
       leftCount: leftCount
    })
  },
  removeToDoHandle:function(e){
    var item = this.data.todos[e.currentTarget.dataset.index]
    this.data.leftCount =  item.completed ? this.data.leftCount : (this.data.leftCount - 1) ;
    this.data.todos.splice(e.currentTarget.dataset.index, 1)
    this.setData({
      todos: this.data.todos,
      leftCount: this.data.leftCount
   })
  },
  toggleAllHandle: function(){
    //this在这里永远指向的是当前页面对象
    console.log(11)
    this.data.allCompleted = !this.data.allCompleted     
    var todos = this.data.todos  
    var that = this
    todos.forEach(function(item){
      item.completed = that.data.allCompleted 
    })
    this.setData({
      todos: this.data.todos,
      leftCount:  this.data.allCompleted? 0 : todos.length 
   })
  }
})


效果:

1dc618a0ed9580ce8bfa6facb208c08f.png


全选:

5d4c6812c8535adbb050f4ddf2e1bce8.png


全不选:

46a9d80a6e05e4e3b19d57a0ee70bcdf.png


清空已完成任务


在页面定义个clearHandle方法:


<!--pages/todos/todos.wxml-->
<view class="container">
  <view class="header">
     <image src="../../images/plus.png" bindtap="addTodoHandle"></image>
     <input type="text" placeholder="Anything here..." value="{{input}}" bindinput="inputChangeHandle"/>
  </view>
  <view class="todos">
      <view class="item{{ item.completed ? ' completed' : '' }}" 
      wx:for="{{ todos}}" bindtap="toggleTodoHandle" data-index="{{ index }}">
        <icon type="{{item.completed? 'success':'circle'}}"  />
        <text>{{item.name}}</text>
         <icon type="clear" size="16" catchtap="removeToDoHandle" data-index="{{ index }}"/>
      </view>    
  </view>
  <view class="footers">
    <text bindtap="toggleAllHandle">Toggle All</text>
     <text wx:if="{{ leftCount }}"> {{ leftCount }} {{leftCount > 1 ? 'items' : 'item' }} left</text>  
     <text bindtap="clearHandle">Clear completed</text>
  </view>
</view>
// pages/todos/todos.js
Page({
  /**
   * 页面的初始数据
   */
  data: {
      //文本框数据模型
      input: '',
      //任务清单数据模型
      todos: [
        {name: 'Learning WEAPP',completed: false},
        {name: 'Learning JavaScript',completed: true},
        {name: 'Learning HTML',completed: false}
      ],
      leftCount: 2,
      allCompleted: false
  },
  inputChangeHandle: function(e){
    //body
    console.log(e.detail.value);
    this.setData({
      input: e.detail.value
    });
  },
  //1.先让按钮点击时 执行一段代码
  //2. 拿到文本框里面的值
  // 2.1 由于小程序的数据绑定是单向的,
  //       必须要给文本框注册改变事件
  //3. 将这个值添加到列表中
  addTodoHandle: function(){ 
     //当添加按钮点击事件发生时执行的函数
     if(!this.data.input)return
     console.log(this.data.input)     
     var todos =  this.data.todos;  
     todos.push({       
         name: this.data.input,
         completed: false
      })  
     //必须显式的通过setData去改变数据,这样界面才能得到变化
     this.setData({
      todos: todos,
       input:'',
       leftCount: this.data.leftCount + 1  
     });
  },
  toggleTodoHandle:function(e){
    //切换当前点中的item的完成状态
    console.log(e.currentTarget);
    var item = this.data.todos[e.currentTarget.dataset.index]
    console.log(item)
    item.completed = !item.completed
    //根据当前任务额完成状态决定增加一个或者减少一个
    var leftCount = this.data.leftCount + (item.completed ? -1 : 1)
    console.log(this.data.todos)
    this.setData({
       todos: this.data.todos,
       leftCount: leftCount
    })
  },
  removeToDoHandle:function(e){
    var item = this.data.todos[e.currentTarget.dataset.index]
    this.data.leftCount =  item.completed ? this.data.leftCount : (this.data.leftCount - 1) ;
    this.data.todos.splice(e.currentTarget.dataset.index, 1)
    this.setData({
      todos: this.data.todos,
      leftCount: this.data.leftCount
   })
  },
  toggleAllHandle: function(){
    //this在这里永远指向的是当前页面对象
    console.log(11)
    this.data.allCompleted = !this.data.allCompleted     
    var todos = this.data.todos  
    var that = this
    todos.forEach(function(item){
      item.completed = that.data.allCompleted 
    })
    this.setData({
      todos: this.data.todos,
      leftCount:  this.data.allCompleted? 0 : todos.length 
   })
  },
  clearHandle:function(){ 
    var todos = this.data.todos.filter(function(item){
      return !item.completed
    })
     this.setData({todos: todos})
  }
})


效果:

1dc618a0ed9580ce8bfa6facb208c08f.png

点击clear Completed,只显示未完成的 任务:

5d4c6812c8535adbb050f4ddf2e1bce8.png


细节优化和总结


1:输入框中输入完成后,点击回车,就会添加


2:所有任务被清空后,不应该呈现列表和按钮


bindconfirm事件


第一个问题的处理: bindconfirm事件


1dc618a0ed9580ce8bfa6facb208c08f.png

5d4c6812c8535adbb050f4ddf2e1bce8.png


呈现问题–block


根据todos有没有数据,有数据就呈现todo列表和footer,没有就不显示


<!--pages/todos/todos.wxml-->
<view class="container">
  <view class="header">
     <image src="../../images/plus.png" bindtap="addTodoHandle"></image>
     <input type="text" placeholder="Anything here..." value="{{input}}" bindinput="inputChangeHandle" bindconfirm="addTodoHandle"/>
  </view>
  <block wx:if="{{ todos.length }}">
  <view class="todos">
      <view class="item{{ item.completed ? ' completed' : '' }}" 
      wx:for="{{ todos}}" wx:key="{{ index }}" bindtap="toggleTodoHandle" data-index="{{ index }}">
        <icon type="{{item.completed? 'success':'circle'}}"  />
        <text>{{item.name}}</text>
         <icon type="clear" size="16" catchtap="removeToDoHandle" data-index="{{ index }}"/>
      </view>    
  </view>
  <view class="footers">
    <text bindtap="toggleAllHandle">Toggle All</text>
     <text wx:if="{{ leftCount }}"> {{ leftCount }} {{leftCount > 1 ? 'items' : 'item' }} left</text>  
     <text bindtap="clearHandle">Clear completed</text>
  </view>
  </block>
   <view wx:else>
    <text>null</text>
   </view>
</view>


看下效果:

66ba272a0bfc97be54a5fa679e3d5482.png



会发现内容不见了,显示null,大功告成!



真机演示


点击预览:

1dc618a0ed9580ce8bfa6facb208c08f.png


出现个二维码,扫码就可在手机上看到效果.

5d4c6812c8535adbb050f4ddf2e1bce8.png

相关文章
|
1天前
|
小程序
【微信小程序】实战案例 -- 向订阅用户发送消息(范例:报名提醒)
【微信小程序】实战案例 -- 向订阅用户发送消息(范例:报名提醒)
4 0
|
8天前
|
小程序
微信小程序学习笔记(入门篇)
微信小程序学习笔记(入门篇)
7 0
|
2月前
|
新零售 小程序 搜索推荐
认养模式小程序系统开发|成熟技术|项目案例
随着新零售的发展,我们设想更多创新的商业模式和营销方式。
|
2月前
|
JSON 小程序 前端开发
【微信小程序】-- 案例 - 自定义 tabBar(四十六)
【微信小程序】-- 案例 - 自定义 tabBar(四十六)
|
2月前
|
小程序
【微信小程序】-- 自定义组件 - 数据监听器 - 案例 (三十五)
【微信小程序】-- 自定义组件 - 数据监听器 - 案例 (三十五)
|
2月前
|
JSON 小程序 API
【微信小程序】-- 案例 - 本地生活(列表页面)(三十)
【微信小程序】-- 案例 - 本地生活(列表页面)(三十)
|
2月前
|
小程序
【微信小程序】-- 页面事件 - 上拉触底 - 案例(二十七)
【微信小程序】-- 页面事件 - 上拉触底 - 案例(二十七)
|
1天前
|
小程序 开发者
uniapp实战 —— 开发微信小程序的调试技巧
uniapp实战 —— 开发微信小程序的调试技巧
7 1
|
1天前
|
小程序
【微信小程序-原生开发】富文本编辑器 editor 的使用教程
【微信小程序-原生开发】富文本编辑器 editor 的使用教程
8 0
【微信小程序-原生开发】富文本编辑器 editor 的使用教程
|
1天前
|
存储 小程序 API
【微信小程序-原生开发+云开发+TDesign】修改用户头像(含wx.chooseMedia,wx.cloud.uploadFile,wx.cloud.deleteFile的使用)
【微信小程序-原生开发+云开发+TDesign】修改用户头像(含wx.chooseMedia,wx.cloud.uploadFile,wx.cloud.deleteFile的使用)
4 0
【微信小程序-原生开发+云开发+TDesign】修改用户头像(含wx.chooseMedia,wx.cloud.uploadFile,wx.cloud.deleteFile的使用)