微信小程序手记

微信小程序手记

Swiper使用

 <swiper indicator-dots='true' interval='3000' autoplay='true'>
    <swiper-item>
      <image src='/images/wx.png'></image>
    </swiper-item>
    <swiper-item>
      <image src='/images/vr.png'></image>
    </swiper-item>
    <swiper-item>
      <image src='/images/iqiyi.png'></image>
    </swiper-item>
  </swiper>

其中swiper-item代表的是一张元素

indicator-dots='true’属性为是否有页标记点

interval=‘3000’ 属性为轮播时间

aotoplay='true’属性为是否自动进行轮播

小程序的生命周期

列表渲染wx-if

  <!-- wx:if="true" 此属性只能赋bool值,如果为空或者不为true都判断为false不显示 -->
 <image wx:if="true" src='/images/iqiyi.png'></image>

先看一段JS文件代码

Page({

  /**
   * 页面的初始数据
   */
  data: {
      name:"张三";
  },
      /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
      var local_database = [
          {
              name: "张三",
          },
          {
              name: "李四",
          },
      ]
      //数据绑定,当前的数据是声明在onLoad里面,我上面提了数据必须在data里才可以,所有我们要调用this.setData({})
      this.setData({
          //post_key是代表在data中的名称,我们在前端for循环绑定的时候也能用到,后面就是声明的变量直
          post_key: local_database
      });
  }
});

列表渲染wx-for

  <block wx:for='{{post_key}}' wx:key='' wx:for-item="item" wx:for-index="idx">
        <!-- 这里我们可以在{{}}中对值进行拼接,或者进行简单计算 -->
        <text>{{"当前下标为:"+idx}}</text>
      <text>{{item.name}}</text>
  </block>
</view>

{{}}是绑定值的意思,这个值是后台传过来的必须要包含在js文件里的data中

wx:key=’’ 这个属性可以不加,控制台会报一个警告

wx:for-item="item"属性可以理解为单个对象的名称,默认直为item

wx:for-index="idx"属性就是标识,当前是第几条数据,默认值为index

小程序的事件捕捉

  <view class='moto-container' bind:tap="onTap">
     <text class='user-moto' catch:tap="onSubTap">开启小程序之旅</text>
  </view>

bind:tap="onTap"为监听事件

catch:tap="onTap"也是一种事件监听,

catch和bind的区别在于,catch会阻止向父类监听

就向上面如果在‘开启小程序之旅’这个标签中使用bind:tap的话会触发两次监听,

第一次为onsubTap,第二次为onTap

但是如果设置为catch:tap的话就不会进行触发上一级也就是父级

JS事件监听以及跳转代码

Page({
  onTap:function(){
    //跳转界面 这种跳转是带有返回键的
    /*wx.navigateTo({
      url: '../posts/posts'
    });*/
    //使用redirectTo跳转是没有返回的
    wx.redirectTo({
      url: '../posts/posts',
    });
  },
 /* onContainerTap:function(){
    console.log("Container Tap");
  },
  onSubTap: function () {
    console.log("Sub Tap");
  },*/
  //卸载页面事件
  onUnload:function(){
    console.log("onUnload");
  },
  //关闭页面事件
  onHide:function(){
    console.log("onHide");
  }
})

这里有两个事件一种是卸载界面,一种是关闭(隐藏)页面事件

如果没有返回按钮的跳转情况也就是使用redirectTo这时候应该触发卸载页面事件

如果有返回按钮的跳转情况也就是使用navigateTo这时候应该触发关闭页面页面事件

将业务数据分离到单独的数据

//当前文件为data.js  
onLoad: function (options) {
      var local_database = [
          {
              name: "张三",
          },
          {
              name: "李四",
          },
      ]
// 定义一个导出的输出口
module.exports = {
    postList: local_database
}

module.exports定义输出接口,一会会在写一个介入接口

如果在调用这个文件呢?

//引入定义的数据js文件
var data=require('../../data/data.js')
Page({

  /**
   * 页面的初始数据
   */
  data: {
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    //数据绑定
    this.setData({
      //这里data为介入声明的变量名,postList是我们在输出接口定义的名称
      //post_key为data中的名称,前端进行数据绑定的时候能用到
      post_key: data.postList
    });
  }
});

var data=require(’…/…/data/data.js’)为导入外部js文件

@import “…/…/data/data.wxss”;为导入wxss文件

定义template模板

template模板是组件化思想

定义一套代码可以在多个文件中引入进行使用

<template name="postItem">
<view class='post-container'>
        <text class='post-name'>{{item.name}}</text>
    </view>
</template>

其中name属性为temlate的名字,在引入的时候能够用到

使用template模板

<import src="post-item/post-item-template.wxml"/>
<view>
    <template  is="postItem"/>
</view>

is属性的值就是我们定义的template的name

使用进行引入

当然既然模板已经分离出去了,那么wxss样式文件也需要分离出去.

在css中引入的方式应该为:

@import “…/…/data/data.wxss”;为导入wxss文件

模板文件传递参数

 <block wx:for='{{post_key}}' wx:key='' wx:for-item="item" wx:for-index="idx">
  <view bind:tap="onPostTap" data-postID='{{item.postId}}'>
   <!-- wx:if="" 如果为空的话默认为false -->
   <!-- ...为ES6的语法,意思是将数据结构中的大括号去掉,这样也就不用使用item.name直接写name就可以,所有传递参数的名字就没有了限制 -->
    <template  is="postItem" data="{{...item}}"/>
  </view>
  </block>

<template name="postItem">
<view class='post-container'>
      <view class='post-author-date'>
        <image src='{{avatar}}' class='post-author'></image>
          <!-- 本来为   <text class='post-date'>{{item.date}}</text> -->
        <text class='post-date'>{{date}}</text>
      </view>
    <!--   <text class='post-title'>{{item.title}}</text> -->
      <text class='post-title'>{{title}}</text>
      <image class='post-image' src='{{headImgSrc}}'></image>
      <text class='post-content'>{{content}}</text>
      <view class='post-like'>
        <image class='post-like-image' src='../../images/icon/chat.png'></image>
        <text class='post-like-font'>{{collection}}</text>
        <image class='post-like-image' src='../../images/icon/view.png'></image>
        <text class='post-like-font'>{{reading}}</text>
      </view>
    </view>
</template>

{{…item}}其中…是ES6语法代表将数据结构中的{}删除掉这样就可以直接获取到对象

点击事件获取当前对象的id,跳转界面根据id显示相应的值

 <block wx:for='{{post_key}}' wx:key='' wx:for-item="item" wx:for-index="idx">
  <view bind:tap="onPostTap" data-postID='{{item.postId}}'>
    <!-- 这里不能直接在template里添加点击事件,因为他本身就是一个占位符,在代码中是不显示的,所有我在外边加了一个view -->
    <template  is="postItem" data="{{...item}}"/>
  </view>
  </block>

在view使用bind:tap监听了一个事件,并且定义了data-postId属性,值就是要拿到的id

这里需要注意,定义值的属性之前必须以data-开头

还有就是小程序会默认把data-后面的第一个名字所有的大写自动转换为小写

例如:data-postID 在js文件中需要获取 postid,才能够拿到值,是不需要加data-的

如果有多个 - 的情况下,小程序会使用驼峰命名法

例如:data-postiD-name 在js中需要获取postidName,才能拿到直,如果实在不清楚建议打印log在console中查看

Storage缓存

 onLoad: function (options) {
    //创建缓存
    wx.setStorageSync('post','123456');
    wx.setStorageSync('icac', {
      name:'张三',
      age:20
    });
  },
  storage: function(){
    //获取缓存
    var data=wx.getStorageSync('post');
    console.log(data);
  },
  removestorage: function(){
    //清理单个缓存
    //wx.removeStorageSync('post');
    //清理多个缓存
    wx.clearStorageSync();
  },

setStorageSyncsetStorage的区别在于setStorageSync****不是异步缓存setStorage是异步的

目前小程序对缓存的限制为10MB(总缓存大小),单个缓存大小为1MB

当数据量比较小的时候可以考虑使用setStorageSync同步缓存,数据量大的话使用异步缓存,效率更高

showToast

   wx.showToast({
      title: collected?'收藏成功':'取消成功',//提示文字
      duration:1000,//动画持续时间
      icon: 'success'//这里有三种 1.success,2.loading 3.none
    })

showModal

//获取缓存
    var postsCollected = wx.getStorageSync('postsCollected');
    //获取到单个对象
    var collected = postsCollected[this.data.currentPostId];
    //如果当前文字是收藏的状态:是否取消收藏
    //如果当前文字是取消收藏的状态:是否收藏
    wx.showModal({
      // title: '收藏',//标题文字
      content: collected ? '是否取消收藏该文字' :'是否收藏该文字',//内容
      showCancel:true,//是否显示取消按钮,默认为true
      cancelText:'取消',//设置取消按钮的文字
      confirmText:'确认',//设置确认按钮的文字
      cancelColor:'#333',//修改取消按钮颜色
      confirmColor:'#405f80',//修改确认按钮颜色
      //只有用户点击收藏或者不收藏的时候才会弹出来
      // success:function(res){ //ES6语法箭头函数,处理this获取值的问题
      success: (res) => {//ES6语法 箭头函数
        //点的收藏还是不收藏
        if(res.confirm){
          //赋相反值
          collected = !collected;
          postsCollected[this.data.currentPostId] = collected;
          wx.setStorageSync('postsCollected', postsCollected);
          //刷新data里面的值
          this.setData({ collected });
        }
      }
    })

tabBar选项卡

"tabBar": {
    "borderStyle":"white",//选项卡上面的黑线颜色改变
    "position":"top",//选项卡的显示位置:top、bottom,注意这里如果选则使用top的话图标将不会进行显示。
    "list": [
      {
        "pagePath": "pages/posts/posts",//页面路径,注意这里不能够使用绝对路径
        "text": "阅读",//文字
        "iconPath": "/images/tab/yuedu.png",//默认icon图片
        "selectedIconPath": "/images/tab/yuedu_hl.png"//选中时icon图片
      },
      {
        "pagePath": "pages/demo/demo",
        "text": "Demo",
        "iconPath": "/images/tab/dianying.png",
        "selectedIconPath": "/images/tab/dianying_hl.png"
      }
    ]
  }

扩展

//在小程序中药跳转到带有tabBar的页面中去必须使用以下方式进行跳转 
wx.switchTab({
      url: '../posts/posts',
    });
参加比赛的作品,开发周期一个月,使用了 Wafer2 框架,后台采用腾讯云提供的 Node.js SDK 接入对象存储 API ,前端核心代码实现了类似于图片编辑器的功能,支持图片和文字的移动、旋转、缩放、生成预览图以及编辑状态的保存,动画部分采用 CSS 动画实现小程序中的模态输入框部分使用了自己封装的 InputBox 组件代码已移除 AppId 等敏感信息,可自行添加自己的 AppId 和 AppSecret 以配置后台环境,实现登录测试,详细添加方法见下文「使用方法」,若本地运行可通过修改 app.json 文件中 page 字段的顺序来查看不同页面微信小程序定制需求请联系作者微信:aweawds (注明来意)效果展示      使用方法首先点击右上角 Star ʕ •ᴥ•ʔ获取Demo代码执行 git clone https://github.com/goolhanrry/Weapp-Demo-LemonJournal.git或 点击此处 下载最新版本的代码解压后在微信开发者工具中打开 Weapp-Demo-LemonJournal 文件夹即可如需进行登录测试,还要执行以下步骤准备好自己的 AppId 和 AppSecret(可在微信公众平台注册后获取)在 project.config.json 的 appid 字段中填入 AppId在 /client/utils/util.js 中相应位置填入 AppId 和 AppSecret在微信开发者工具中重新导入整个项目,上传后台代码后编译运行即可核心代码组件的移动、旋转和缩放主要思路是把  标签(对应图片)和  标签(对应文字)封装在同一个自定义组件  中,通过对外暴露的 text 变量是否为空来进行条件渲染,然后绑定 onTouchStart() 、onTouchEnd() 和 onTouchMove() 三个事件来对整个组件的位置、角度、大小、层级以及 “旋转” 和 “移除” 两个按钮的行为进行操作onTouchStart: function (e) {     // 若未选中则直接返回     if (!this.data.selected) {         return     }     switch (e.target.id) {         case 'sticker': {             this.touch_target = e.target.id             this.start_x = e.touches[0].clientX * 2             this.start_y = e.touches[0].clientY * 2             break         }         case 'handle': {             // 隐藏移除按钮             this.setData({                 hideRemove: true             })             this.touch_target = e.target.id             this.start_x = e.touches[0].clientX * 2             this.start_y = e.touches[0].clientY * 2             this.sticker_center_x = this.data.stickerCenterX;             this.sticker_center_y = this.data.stickerCenterY;             this.remove_center_x = this.data.removeCenterX;             this.remove_center_y = this.data.removeCenterY;             this.handle_center_x = this.data.handleCenterX;             this.handle_center_y = this.data.handleCenterY;             this.scale = this.data.scale;             this.rotate = this.data.rotate;             break         }     } }, onTouchEnd: function (e) {     this.active()     this.touch_target = ''     // 显示移除按钮     this.setData({         removeCenterX: 2 * this.data.stickerCenterX - this.data.handleCenterX,         removeCenterY: 2 * this.data.stickerCenterY - this.data.handleCenterY,         hideRemove: false     })     // 若点击移除按钮则触发移除事件,否则触发刷新数据事件     if (e.target.id === 'remove') {         this.triggerEvent('removeSticker', this.data.sticker_id)     } else {         this.triggerEvent('refreshData', this.data)     } }, onTouchMove: function (e) {     // 若无选中目标则返回     if (!this.touch_target) {         return     }     var current_x = e.touches[0].clientX * 2     var current_y = e.touches[0].clientY * 2     var diff_x = current_x - this.start_x     var diff_y = current_y - this.start_y     switch (e.target.id) {         case 'sticker': {             // 拖动组件则所有控件同时移动             this.setData({                 stickerCenterX: this.data.stickerCenterX   diff_x,                 stickerCenterY: this.data.stickerCenterY   diff_y,                 removeCenterX: this.data.removeCenterX   diff_x,                 removeCenterY: this.data.removeCenterY   diff_y,                 handleCenterX: this.data.handleCenterX   diff_x,                 handleCenterY: this.data.handleCenterY   diff_y             })             break         }         case 'handle': {             // 拖动操作按钮则原地旋转缩放             this.setData({                 handleCenterX: this.data.handleCenterX   diff_x,                 handleCenterY: this.data.handleCenterY   diff_y             })             var diff_x_before = this.handle_center_x - this.sticker_center_x;             var diff_y_before = this.handle_center_y - this.sticker_center_y;             var diff_x_after = this.data.handleCenterX - this.sticker_center_x;             var diff_y_after = this.data.handleCenterY - this.sticker_center_y;             var distance_before = Math.sqrt(diff_x_before * diff_x_before   diff_y_before * diff_y_before);             var distance_after = Math.sqrt(diff_x_after * diff_x_after   diff_y_after * diff_y_after);             var angle_before = Math.atan2(diff_y_before, diff_x_before) / Math.PI * 180;             var angle_after = Math.atan2(diff_y_after, diff_x_after) / Math.PI * 180;             this.setData({                 scale: distance_after / distance_before * this.scale,                 rotate: angle_after - angle_before   this.rotate             })             break         }     }     this.start_x = current_x;     this.start_y = current_y; }编辑状态的保存一篇手帐包含的组件类型包括 sticker(软件自带的贴纸)、image(用户上传的图片)和 text(自定义文字)三种,全部保存在一个如下格式的 json 对象中,每个独立组件都包含了一个不重复的 id 以及相关的信息,保存时由客户端生成该对象并编码成 json 字符串存储在数据库,恢复编辑状态时通过解析 json 字符串获得对象,再由编辑页面渲染{     "backgroundId": "5",                                        背景图id     "assemblies": [         {             "id": "jhjg",                                       组件id             "component_type": "image",                          组件类型(自定义图片)             "image_url": "https://example.com/jhjg.png",        图片地址             "stickerCenterX": 269,                              中心横坐标             "stickerCenterY": 664,                              中心纵坐标             "scale": 1.7123667831396403,                        缩放比例             "rotate": -3.0127875041833434,                      旋转角度             "wh_scale": 1,                                      图片宽高比             "z_index": 19                                       组件层级         },         {             "id": "gs47",             "component_type": "text",                           组件类型(文字)             "text": "test",                                     文字内容             "stickerCenterX": 479,             "stickerCenterY": 546,             "scale": 1.808535318980528,             "rotate": 29.11614626607893,             "z_index": 10         },         {             "id": "chjn",             "component_type": "sticker",                        组件类型(贴纸)             "sticker_type": "food",                             贴纸类型             "sticker_id": "1",                                  贴纸id             "image_url": "https://example.com/weapp/stickers/food/1.png",             "stickerCenterX": 277,             "stickerCenterY": 260,             "scale": 1.3984276885130673,             "rotate": -16.620756913892055,             "z_index": 5         }     ] }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值