前言:
適用於小程序的條形碼插件不多,目前只找到這一個能用的,工期限制,暫時就先用這一個了。
在使用插件的過程中也發現了不少問題,也做了一些改進,這里就做下總結,希望能給其它遇到下面問題的小伙伴有所幫助。
插件地址:
方法1——npm安裝:
npm install wxbarcode
import wxbarcode from 'wxbarcode' //條形碼 wxbarcode.barcode('barcode', '1234567890123456789', 680, 200); //二維碼 wxbarcode.qrcode('qrcode', '1234567890123456789', 420, 420);
支付寶小程序支持npm,所以這種用法還好,微信小程序用就有點麻煩了。所以可以單獨的把插件腳本拿出來直接用。
方法2——直接飲用插件腳本:
調用:
var wxbarcode = require('../../utils/index.js'); Page({ onLoad: function() { wxbarcode.barcode('barcode', '1234567890123456789', 680, 200); wxbarcode.qrcode('qrcode', '1234567890123456789', 420, 420); } })
如果現有項目已經有了二維碼插件,只需要條形碼插件,那么可以單獨使用條形碼插件就好了,如下:
utils/index.js
//調用封裝腳本改造 var barcode = require('./barcode'); function convert_length(length) { return Math.round(wx.getSystemInfoSync().windowWidth * length / 750); } function barc(id, code, width, height) { barcode.code128(wx.createCanvasContext(id), code, convert_length(width), convert_length(height)) } export function barc(id, code, width, height) { barcode.code128(wx.createCanvasContext(id), code, convert_length(width), convert_length(height)) }
page.js
//方法調用 import { barc } from '../../utils/index.js' Page({ data: {}, onLoad: function() { barc('barcode', '1234567890123456789', 680, 200); } })
page.wxml
<!--多個條形碼生成--> <view class="barcode" wx:for="{{code}}"> <view class="barnum">{{item}}</view> <canvas canvas-id="barcode{{index}}" /> </view>
utils/index.js
//調用封裝腳本改造 var barcode = require('./barcode'); function convert_length(length) { return Math.round(wx.getSystemInfoSync().windowWidth * length / 750); } function barc(id, code, width, height) { barcode.code128(wx.createCanvasContext(id), code, convert_length(width), convert_length(height)) } export function barc(id, code, width, height) { barcode.code128(wx.createCanvasContext(id), code, convert_length(width), convert_length(height)) }
page.wxml
//方法調用 import { barc } from '../../utils/index.js' Page({ data: { code: ['11111111', '22222222', '33333333'] }, onLoad: function() { var code = this.data.code for (var i in code) { barc('barcode' + i, code[i], 680, 200); } } })
如果需要在多個頁面模板中生成條形碼,那么最好封裝成組件。
支付寶小程序中,封裝組件正常。
具體代碼如下:
barcode/index.axml
<view class="barcode"> <canvas id="barcode{{index}}"/> <view class="couponNumber">{{couponNumber}}</view> </view>
barcode/index.js
import barcode from './barcode'; Component({ mixins: [], data: {}, props: { couponNumber: [String] || '', index: [Number] || 0 }, didMount() { this.barc("barcode" + this.props.index, this.props.couponNumber, this.convert_length(960), this.convert_length(440)); }, methods: { convert_length(length) { return Math.round(my.getSystemInfoSync().windowWidth * length / 750); }, barc(id, code, width, height) { barcode.code128(my.createCanvasContext(id), code, this.convert_length(width), this.convert_length(height)) } } });
page.wxml
<barcode class="iblock" value="{{item.couponNumber}}" width="540"/>
如上,支付寶小程序中將條形碼組件的合成放到組件中是沒問題的。
但是在微信小程序中則不然,微信小程序中按這種方法條形碼是不展示的,估計是跟微信小程序的一些機制有關吧,時間有限,就不做深入研究了。
如果一定要封裝到組件中,那么可以采取馬甲的方式來封裝,即把 插件中的 canvas 通過組件的slot插槽放到頁面中去進行渲染,這樣條形碼就能正常展示了。
具體實現如下:
barcode/index.wxml
<view class='barcode'> <slot name="content2" bindlongpress="saveImg" data-index="{{index}}"></slot> <view class="couponNumber">{{couponNumber}}</view> </view>
barcode/index.js
// components/barcode/index.js import barcode from './barcode'; Component({ /** * 組件的屬性列表 */ options: { multipleSlots: true // 在組件定義時的選項中啟用多slot支持 }, properties: { couponNumber: String, index: Number }, attached: function() { setTimeout(()=>{ this.barc("barcode" + this.data.index, this.data.couponNumber, this.convert_length(960), this.convert_length(440)); },500) }, /** * 組件的方法列表 */ methods: { convert_length(length) { return Math.round(wx.getSystemInfoSync().windowWidth * length / 750); }, barc(id, code, width, height) { barcode.code128(wx.createCanvasContext(id), code, this.convert_length(width), this.convert_length(height)) }, saveImg: function() { //獲取畫布中圖片的臨時地址 wx.canvasToTempFilePath({ canvasId: 'barcode' + this.data.index, success: function(data) { //保存圖片 wx.showActionSheet({ itemList: ['保存圖片'], success: function(res) { console.log(res.tapIndex) if (res.tapIndex == 0) { wx.saveImageToPhotosAlbum({ filePath: data.tempFilePath, complete(e){ console.log(e) } }) } } }) } }) } } })
注:
1.條形碼合成的邏輯進行了延遲500ms的處理——解決華為部分機型不展示條形碼的問題
2.長按保存圖片的實現——插件本身沒有實現,這里先用 wx.canvasToTempFilePath 獲取canvas中圖片的臨時地址,然后再調用 wx.saveImageToPhotosAlbum 進行保存。當然,感興趣的小伙伴可以直接對插件進行改造。
3.支付寶小程序中提供的保存圖片的api並不支持base64格式的圖片,所以支付寶小程序中暫時未做保存圖片處理,后續有時間再研究。
1.條碼識別不正確:條形碼長款尺寸最好按demo提供的比例配置,不然可能會導致生成出來的條形碼展示不全,掃碼識別會出現不對的結果;
2.微信小程序組件封裝:微信小程序不能把canvas封裝到組件中,要用插槽放到頁面中;
3.微信小程序華為手機不顯示條形碼:加500ms延遲吧;
4.奇數字符串生成條形碼識別最后一位是下划線:
插件bug,做如下調整:
barcode.js
//ok some type of shift is nessecary if (shifter != -1) { result.push(shifter); result.push(codeValue(chr1));//插件中是chr2,改成chr1就可以了 } else { if (currcs == CODESET.C) { //include next as well result.push(codeValue(chr1, chr2)); } else { result.push(codeValue(chr1)); } }
如上,高亮部分即為原插件bug修復,調整后奇數字符串最后一位就正常了。