网友真实露脸自拍10p,成人国产精品秘?久久久按摩,国产精品久久久久久无码不卡,成人免费区一区二区三区

小程序模板網(wǎng)

微信小程序開發(fā)一些經(jīng)驗(yàn)

發(fā)布時(shí)間:2018-05-16 15:06 所屬欄目:小程序開發(fā)教程

對(duì)于微信小程序開發(fā)入門,還是比較簡(jiǎn)單的,只需要具備基本的css+js知識(shí)就可以了,成本比較低。 寫了小程序和RN之后,有一種原生很笨重的感覺(jué),就是小程序或者是RN等這些新的開發(fā)方式在效率上面真的有比較大的優(yōu)勢(shì),唯一不足就是運(yùn)行速度了(使用Canvas就會(huì)有這樣子的感覺(jué))。 感覺(jué)目前所接觸的種類前端開發(fā)(包括移動(dòng)端),都是基本一個(gè)套路:UI,網(wǎng)絡(luò),數(shù)據(jù)保存,富文本,圖片/視頻。 本文也是從這幾個(gè)方向去總結(jié)自己的小程序開發(fā)經(jīng)驗(yàn)。

小程序的入門

其實(shí)小程序的開發(fā)過(guò)程一直都是查看文檔,按照文檔去操作就可以了。 一般流程是先看簡(jiǎn)易教程。看完之后,再去看組件。之后可以開始嘗試寫需求,這個(gè)過(guò)程中,開始不斷的去查API和框架即可。

多列列表

在開發(fā)中,有一個(gè)需求是需要實(shí)現(xiàn)類似Android的GridView網(wǎng)格列表的。但是微信中并沒(méi)有提供這樣子的組件,但是小程序是跟html/css前端很類似的,他可以通過(guò)指定 display:flex ,然后去設(shè)置 flex-wrap:wrap 就可以。例如,有一個(gè)數(shù)組 data:["A","B","C","D","E","F","G","H","I","J","K","L","M","N"] 需要顯示為一個(gè)三列的列表,可以如下處理:


//GridPage.wxml
<view class='grid-container'>
  <view wx:for="{{data}}" wx:key="{{item}}" class="grid-list">
  <view class='grid-item'>
  <text class='grid-item-text'>{{item}}</text>
  </view>
  </view>
</view>

//GridPage.wxss
Page {
  min-height: 100%;
  background-color: #fff;
}
.grid-container {
  margin-left: 4rpx;
  margin-right: 4rpx;
  display: flex;
  flex-wrap: wrap;
  flex-direction: row;
}
.grid-list {
  width: 33.33%;
}
.grid-item {
  margin: 2rpx;
  background: #999;
  display: flex;
  justify-content: center;
  align-items: center;
}
.grid-item-text {
  color: black;
}

這里的重點(diǎn)就是 grid-container 中的 flex-wrap 為 wrap ,方向是 row 了。然后他的每一個(gè)item寬度都是 33.33% 。需要注意的是一定是去設(shè)置外部的contanier而不是內(nèi)部的list。

層級(jí)布局

在CSS中,需要使用層級(jí)布局,就是類似Android的FrameLayout效果,可以使用z-index,也可以使用一個(gè)絕對(duì)定位。比如,我們有一個(gè)需求是:下面是一個(gè)圖片,上面是文字。


//PositionPage.wxml
<view class='root'>
<image src='https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=3756982450,995202616&fm=27&gp=0.jpg' class='image'></image>
<text class='text'>我是權(quán)律二啊</text>
</view>
//PositionPage.wcss
.root{
  align-items: center;
  display: flex;
  flex-direction: column;
  position: relative;
}
.image{
  width: 300rpx;
  height: 300rpx;
}
.text{
  background-color: #999;
  position: absolute;
}

主要是兩點(diǎn):父布局的 position 必須是 relative ,它本身 position 必須是 absolute

網(wǎng)絡(luò)請(qǐng)求

小程序的網(wǎng)絡(luò)請(qǐng)求是使用wx.request()方法,但是該方法太臃腫,并沒(méi)有使用Promise那樣子簡(jiǎn)潔。幸運(yùn)的是小程序支持Promise,所以我們可以把http封裝一下,變成有條理。說(shuō)到這里,大家做的時(shí)候需要注意去微信后臺(tái)配置各種request域名,upload域名,downloadFIle域名。 下面封裝的例子的數(shù)據(jù)返回格式都是json格式post請(qǐng)求方式發(fā)出的:


//真正發(fā)起請(qǐng)求
function _request(url, param) {
    if (isDebug) {
        Log.i("http==> params->" + JSON.stringify(param));
        Log.i("http==> url->" + url);
    }
    return new Promise((resolve, reject) => {
        wx.request({
            url: url,
            data: param,
            header: {
                'content-type': 'application/json',
                "Accept": "application/json"
            },
            method: "POST",
            success: function (response) {
                if (isDebug) {
                    const jsonResponse = JSON.stringify(response);
                    Log.i("http==> response->" + jsonResponse);
                }
                const {data, statusCode, ok = false} = response;
                //只有ok為true的是時(shí)候才返回成功,data不一定是包含數(shù)據(jù)的
                if (statusCode === 200 && data && data.ok) {
                    resolve(data, ok);
                } else {
                    if (statusCode != 404 && statusCode < 500 && statusCode > 300) {
                        ToastUtil.showError();
                    }
                    reject(data);
                }
            },
            fail: reject
        });
    });

}

使用:


function getInfo(fid) {
    const params = {};
    params.token = user.token;
    params.uid = user.uid;
    return _request("INFO_URL", params);
}

然后需要發(fā)起請(qǐng)求就調(diào)用該方法即可,處理Promise。

上傳圖片到阿里云

需要注意微信upload接口配置目前好像不可以直接配置阿里云的URL,需要阿里云先 跟我們的域名綁定,之后再去把設(shè)置到微信后臺(tái)的upload接口中。可以參考博客: 小程序圖片上傳阿里OSS使用方法 ,獲取簽名阿里云Demo地址: JavaScript客戶端簽名直傳 ,通過(guò)打log獲得policy和signature(簽名時(shí)間可以稍微設(shè)置久一點(diǎn))之后,就開始封裝upload方法了。 如下:


/**
    * 真實(shí)上傳代碼
    */
    function _upload(file, success, fail) {
        const suffix = file.substring(file.lastIndexOf("."));
        //做一下md5處理
        const fileName = hex_md5(file);
        Log.i("fileName=" + (fileName + suffix));
        wx.uploadFile({
            url: ALIYUNPHOTOADDRESS,
            formData: {
                "OSSAccessKeyId": "你的阿里云accessKey",
                "key": DIR+ (fileName + suffix),
                "policy": "你的policy",
                "success_action_status": '200',
                "signature": "你的signature"
            },
            filePath: file,
            name: 'file',
            success: function (res) {
                const {statusCode} = res;
                if (statusCode === 200) {
                    console.log(JSON.stringify(res));
                    success("" + fileName + suffix);
                } else {
                    console.log("上傳失敗");
                    fail(res);
                }
            },
            fail: function (e) {
                fail(e);
                console.log("上傳失敗");
                console.log("e=" + JSON.stringify(e));
            }, complete: function () {
                console.log("上傳過(guò)程結(jié)束");
            }
        })
    }

}

其中 url 是上傳OOS的地址,key是需要上傳的文件夾+上傳之后的文件名。這里的fileName我們通過(guò)一個(gè)md5去計(jì)算得來(lái),保證唯一性又沒(méi)有什么特殊字符。md5的算法來(lái)自JS-MD5加密。

我們可以順帶封裝一個(gè)上傳多張圖片的方法,而且使用Promise返回:


/**
* files需要上傳的文件,是一個(gè)數(shù)組,里面是文件的絕對(duì)路徑
*/
function uploadFiles(files) {
  if (!files || files.length <= 0) {
    wx.showModal({
      title: '圖片錯(cuò)誤',
      content: '請(qǐng)重試',
      showCancel: false,
    });
    return Promise.reject();
  }
  Log.i("開始上傳" + files);

  return new Promise((resolve, reject) => {
    //上傳成功的文件名稱
    let uploadPaths = [];
    for (let i = 0; i < files.length; i++) {
      _upload(files[i], (path) => {
        //成功的文件名
        uploadPaths[uploadPaths.length] = path;
        if (uploadPaths.length >= files.length) {
          //把url+name返回
          resolve([ALIYUNPHOTOADDRESS + "/" +DIR, uploadPaths]);
        }
      }, () => {
        //error
        reject(res);
      });
    }

  });

Canvas使用

  • 由于需要使用Canvas畫一棵樹,所以還是在這里走了比較多的坑的。我的需求是Canvas全屏,除了畫一個(gè)樹之外還需要畫別的一些獨(dú)立Button。 首先,設(shè)置Canvas全屏和不可滑動(dòng),可以通過(guò)以下方式:

<canvas  disable-scroll='true' style="width: {{width}}px; height: {{height}}px;background-color:#efeff4;flex:1;" canvas-id="canvas" bindtouchstart="touchStart" bindtouchmove="touchMove" bindtouchend="touchEnd"></canvas>
  • 其中,在設(shè)置了disable-scroll設(shè)置為true,同時(shí)需要綁定三個(gè)touch事件,才能響應(yīng)畫布的觸摸event。其中這里的width+height是通過(guò)wx.getSystemInfo()獲得。
  • 其次,canvas沒(méi)有類似View的catchtap事件,只有一些touch事件,詳情可以看Canvas
  • 然后在微信小程序中Canvas是層級(jí)最高的,無(wú)法通過(guò)設(shè)置z-index去調(diào),所以假如你的Canvas全屏,還需要一些其他的Button,那么只能通過(guò)最后canvas去draw了。
  • 在canvas中,假如通過(guò)moveTo+lineTo去畫線,一般需要先調(diào)用canvas.beginPath()畫完成之后,先調(diào)用canvas.stoke(),然后在調(diào)用canvas.closePath();

c.beginPath();
    c.setLineWidth(this.arrowPaint.width);
    c.setStrokeStyle(this.arrowPaint.color);
    c.setLineCap("square");

    c.moveTo(this.arrowStartPointF.x, this.arrowStartPointF.y);
    c.lineTo(this.arrowCenterPointF.x, this.arrowCenterPointF.y);
    c.moveTo(this.arrowCenterPointF.x, this.arrowCenterPointF.y);
    c.lineTo(this.arrowEndPointF.x, this.arrowEndPointF.y);
    c.stroke();
    c.closePath();
  • 在連續(xù)畫多種圖片/線條的時(shí)候,不要連續(xù)多次調(diào)用draw(true)方法, 消耗性能,一般最后調(diào)用fill()/stoke()方法即可。比如

//繪制點(diǎn)
        c.beginPath();
        let y = node.noteView.pointFrameCenter.y + Constant.FRAME_HEIGHT / 2 + Constant.GAP_BETWEEN_DOT + Constant.RADIUS_DOT;

        c.setFillStyle(Constant.LINE_COLOR_RED);
        c.setLineWidth(Constant.LINE_WIDTH);
        c.arc(node.noteView.pointFrameCenter.x, y, Constant.RADIUS_DOT, 0, 2 * Math.PI);

        //
        y += (Constant.GAP_BETWEEN_DOT + Constant.RADIUS_DOT);
        c.arc(node.noteView.pointFrameCenter.x, y, Constant.RADIUS_DOT, 0, 2 * Math.PI);
        //
        //
        y += (Constant.GAP_BETWEEN_DOT + Constant.RADIUS_DOT);
        c.arc(node.noteView.pointFrameCenter.x, y, Constant.RADIUS_DOT, 0, 2 * Math.PI);

        c.fill();
        c.closePath();
  • 對(duì)于draw方法,建議只是調(diào)用draw()就好,不要調(diào)用draw(true)方法,draw(true)是在原畫布之上再去畫,不會(huì)清空舊畫布,draw()會(huì)清空。一般,我們會(huì)在所有的image,rectangle,line,circle去fill/stoke完之后,再調(diào)用draw()方法,這樣子就可以避免draw(true)多次,性能耗損。而且再次去reDraw的時(shí)候也不用先去清空畫布。
  • Canvas的跟隨手勢(shì)拖動(dòng)

//index.wxml
  <canvas disable-scroll='true' style="width: {{width}}px; height: {{height}}px;background-color:#efeff4;" canvas-id="canvas" bindtouchstart="touchStart" bindtouchmove="touchMove" bindtouchend="touchEnd"></canvas>
//index.wcss
Page {
  overflow: hidden;
  display: flex;
}
//index.js
const app = getApp()

Page({
  data: {
    width: 0,
    height: 0,
  },
  onLoad: function (e) {
    this.time = (new Date()).valueOf();
    this.x = 0;
    this.y = 0;
    this.moveX = 0;
    this.moveY = 0;

    const that = this;
    wx.getSystemInfo({
      success: function (res) {
        that.setData({ width: res.screenWidth, height: res.screenHeight })
      },
    })
    const ctx = wx.createCanvasContext("canvas", this)
    this.canvas = ctx;
  },
  onReady: function () {
    this.draw();
  },
  draw: function () {
    this.canvas.fillRect(10, 10, 150, 100)
    this.canvas.fill();
    this.canvas.draw()
  },
  touchMove: function (e) {
    console.log("touchMove")
    let xOffset = e.touches[0].x - this.x;
    let yOffset = e.touches[0].y - this.y;
    this.x = e.touches[0].x;
    this.y = e.touches[0].y;
    this.moveX = this.moveX + xOffset;
    this.moveY = this.moveY + yOffset;
    this.canvas.translate(this.moveX, this.moveY);
    this.draw();
  },
  touchStart: function (e) {
    this.x = e.touches[0].x;
    this.y = e.touches[0].y;
  },
  touchEnd: function (e) {
    console.log("touchEnd")
  }
})

其他的scale等方法類似。


易優(yōu)小程序(企業(yè)版)+靈活api+前后代碼開源 碼云倉(cāng)庫(kù):starfork
本文地址:http://www.xiuhaier.com/wxmini/doc/course/24421.html 復(fù)制鏈接 如需定制請(qǐng)聯(lián)系易優(yōu)客服咨詢:800182392 點(diǎn)擊咨詢
QQ在線咨詢
AI智能客服 ×