摘要:前言原生開發小程序有了兩個項目,在原生開發小程序經驗技巧方面有一些自己的總結,此篇文章做原創分享本文適合老手查看,新手請參閱官方文檔,同步至。
前言
原生開發小程序有了兩個項目,在原生開發小程序經驗技巧方面有一些自己的總結,此篇文章做原創分享!
本文適合老手查看,新手請參閱官方文檔,同步至github。
1.發布訂閱處理復雜邏輯支持先訂閱后發布,以及先發布后訂閱
方法源碼
var Event = (function() { var clientList = {}, pub, sub, remove; var cached = {}; sub = function(key, fn) { if (!clientList[key]) { clientList[key] = []; } // 使用緩存執行的訂閱不用多次調用執行 cached[key + "time"] == undefined ? clientList[key].push(fn) : ""; if (cached[key] instanceof Array && cached[key].length > 0) { //說明有緩存的 可以執行 fn.apply(null, cached[key]); cached[key + "time"] = 1; } }; pub = function() { var key = Array.prototype.shift.call(arguments), fns = clientList[key]; if (!fns || fns.length === 0) { //初始默認緩存 cached[key] = Array.prototype.slice.call(arguments, 0); return false; } for (var i = 0, fn; (fn = fns[i++]); ) { // 再次發布更新緩存中的 data 參數 cached[key + "time"] != undefined ? (cached[key] = Array.prototype.slice.call(arguments, 0)) : ""; fn.apply(this, arguments); } }; remove = function(key, fn) { var fns = clientList[key]; // 緩存訂閱一并刪除 var cachedFn = cached[key]; if (!fns && !cachedFn) { return false; } if (!fn) { fns && (fns.length = 0); cachedFn && (cachedFn.length = 0); } else { if (cachedFn) { for (var m = cachedFn.length - 1; m >= 0; m--) { var _fn_temp = cachedFn[m]; if (_fn_temp === fn) { cachedFn.splice(m, 1); } } } for (var n = fns.length - 1; n >= 0; n--) { var _fn = fns[n]; if (_fn === fn) { fns.splice(n, 1); } } } }; return { pub: pub, sub: sub, remove: remove }; })();
全局掛載使用
// app.js App({ onLaunch: function(e) { // 注冊 storage,這是第二條 wx.Storage = Storage; // 注冊發布訂閱模式 wx.yue = Event; } });
使用實例
// 添加收貨地址頁面訂閱 onLoad: function (options) { wx.yue.sub("addAddress", function (data) { y.setData({ addAddress: data }) }) } /** * 生命周期函數--監聽頁面隱藏 */ onHide: function () { // 取消多余的事件訂閱 wx.Storage.removeItem("addAddress"); }, onUnload: function () { // 取消多余的事件訂閱 wx.yue.remove("addAddress"); }
// 傳遞地址頁面獲取好數據傳遞 wx.yue.pub("addAddress", data.info); // 補充跳轉返回
注意:使用完成數據后要注意卸載,在頁面被關閉時操作2.Storage
storage 管理封裝,用法和上面的一致,掛載在全局對象上調用,使用介紹就不列了
const Storage = { // 第一個 key 參數可以省略,直接傳遞 obj 對象,支持 callback setItem: function(key, obj, callback) { const getType = function(a) { var typeArray = Object.prototype.toString.call(a).split(" "); return typeArray[1].slice(0, -1); }; var firstParamType = getType(arguments[0]); if (firstParamType === "Object") { var keyArrayLength = Object.keys(arguments[0]).length; var index = 0; for (var keyName in arguments[0]) { index++; wx.setStorage({ key: keyName, data: arguments[0][keyName], success: index == keyArrayLength ? arguments[1] : function() {} }); } } if (firstParamType === "String") { wx.setStorage({ key: key, data: obj, success: callback || function() {} }); } }, getItem: function(key) { return wx.getStorageSync(key); }, removeItem: function(key) { wx.removeStorage({ key: key }); } };例子
wx.Storage.setItem( { class_pid: that.data.class_pid, class_id: that.data.class_id, is_import: that.data.is_import, shop_type: 1 }, function() { console.log("Storage 已設置完畢!"); } );3.filter 計算屬性
小程序也有計算屬性,你知道嗎?
// 文件名稱為 :filter.wxs // 不支持es6,Date,Number function filterOrderTitleName(status) { switch (status) { case "1": return "待支付"; case "2": return "待配送"; case "3": return "配送中"; case "4": return "已完成"; } } function filterPrice(str) { // 四舍五入 格式化數字 // toFix(8440.55,1) => 8440.6 var times = Math.pow(10, 2); var roundNum = Math.round(str * times) / times; return roundNum.toFixed(2); } module.exports = { filterOrderTitleName: filterOrderTitleName, filterPrice: filterPrice };
使用實例,過濾處理打折后的金額小數位數
// 當前文件名:shoppingCart.wxml // wxs 文件頂部導入4.flex Style¥{{filter.filterPrice(item.plus*100*item.price/1000)}} 會員{{item.dazhe}}折
分享我常使用的自定義的一套 flex 樣式,快速實現布局
/* -------------------------------------------------------------flex------------------------------------------------------- */ .center { display: flex; align-items: center; justify-content: center; } /* 單行水平垂直 */ .oneLineCenter { display: flex; display: -webkit-flex; justify-content: center; align-items: center; } /* 單行垂直居中,水平向左 */ .oneLineStart { display: flex; display: -webkit-flex; justify-content: flex-start; align-items: center; } /* 單行垂直居中,水平向右 */ .oneLineEnd { display: flex; display: -webkit-flex; justify-content: flex-end; align-items: center; } /* 單行垂直居中,水平保持間距 */ .oneLineAround { display: flex; display: -webkit-flex; justify-content: space-around; align-items: center; } /* 單行垂直居中,兩端對齊 */ .oneLineBetween { display: flex; display: -webkit-flex; justify-content: space-between; align-items: center; } /* 超過單行設置的最大寬度,允許換行顯示 */ .f-wrap { flex-wrap: wrap; } /* 多軸線方向,一般配合 wrap 使用 */ /* 寬度不足換行后,垂直方向靠上排列 */ .mulitLineStart { display: flex; display: -webkit-flex; flex-wrap: wrap; align-content: flex-start; } /* 寬度不足換行后,垂直方向居中排列 */ .mulitLineCenter { display: flex; display: -webkit-flex; flex-wrap: wrap; align-content: center; } /* 寬度不足換行后,垂直方向靠下排列 */ .mulitLineEnd { display: flex; display: -webkit-flex; flex-wrap: wrap; align-content: flex-end; } /* 寬度不足換行后,垂直方向上保持間隔排列 */ .mulitLineAround { display: flex; display: -webkit-flex; flex-wrap: wrap; align-content: space-around; } /* 寬度不足換行后,垂直方向上靠兩側最頂開始間隔排列 */ .mulitLineBetween { display: flex; display: -webkit-flex; flex-wrap: wrap; align-content: space-between; } /* 縱軸變主軸,垂直靠上,水平居中 */ .columnStart { display: flex; display: -webkit-flex; flex-direction: column; justify-content: flex-start; align-items: center; } /* 縱軸變主軸,垂直靠下,水平居中 */ .columnEnd { display: flex; flex-direction: column; justify-content: flex-end; align-items: center; } /* 縱軸變主軸,垂直居中,水平居中 */ .columnCenter { display: flex; flex-direction: column; justify-content: center; align-items: center; } /* 縱軸變主軸,垂直間隔排列,水平居中 */ .columnAround { display: flex; flex-direction: column; justify-content: space-around; align-items: center; } /* 縱軸變主軸,垂直上下兩側按間隔排列,水平居中 */ .columnBetween { display: flex; flex-direction: column; justify-content: space-between; align-items: center; } /* 縱軸變主軸,垂直上下兩側按間隔排列,水平靠左 */ .columnBetweenStart { display: flex; flex-direction: column; justify-content: space-between; align-items: flex-start; } /* 縱軸變主軸,垂直上下兩側按間隔排列,水平靠右 */ .columnBetweenEnd { display: flex; flex-direction: column; justify-content: space-between; align-items: flex-end; }5.async await
使用runtime.js,使小程序支持 async await,拷貝文件至項目目錄下。
實例用法
const regeneratorRuntime = require("../../utils/runtime.js"); Page({ shopCartInit() { var y = this; // 拿到商鋪位置信息再去渲染購物計算當前的address符合不符合規定 var showCartList = function() { // 顯示全局的地址信息 var globalAddress = wx.Storage.getItem("globalAddress"); if (globalAddress) { y.setData({ globalAddress: globalAddress, addr_id: globalAddress.id }); y.calculateDistance( qqmapsdk, globalAddress.latitude, globalAddress.longitude ); } else { y.setData({ globalAddress: {} }); } }; // await 等待獲取商鋪位置信息 async function getShopPosTionMsg() { await util.promiseRequest(api.merchant_addr, {}).then(res => { var data = res.data.response_data.lists[0]; y.setData({ shop_lat: data.latitude, // 商鋪緯度 shop_lng: data.longitude, // 商鋪經度 peiSongFanWei: data.scope // 配送范圍 }); }); } async function initData() { await getShopPosTionMsg(); await showCartList(); util.closeLoading(); y.setData({ loading: false }); } // 開始執行 initData(); } });6.addKey Api
使用自定義屬性的方法輔助完成業務邏輯,已發布至 addKey
/** * 為數組添加新的自定義鍵值以及過濾每個子項的方法 * * @param {*} arr * @param {*} obj { isShow:false,isStar:false} * @param {*} filterFn * @returns */ function addKey(sourceArray, extendObj, filterFn) { var getType = function(a) { var typeArray = Object.prototype.toString.call(a).split(" "); return typeArray[1].slice(0, -1); }; var secondParamType = getType(arguments[1]); if (!getType(sourceArray) == "Array") { throw new Error("The first argument must be an array type"); } if (secondParamType === "Object") { return sourceArray.forEach((v, index, sourceArray) => { for (var key in extendObj) { v[key] = extendObj[key]; } typeof filterFn === "function" ? filterFn(v, index, sourceArray) : ""; }); } else if (secondParamType === "Function") { return sourceArray.forEach((v, index, sourceArray) => { arguments[1](v, index, sourceArray); }); } else { return sourceArray; } }
使用實例
util.addKey(data, { y_isCheck: false }, function(v) { v.dazhe = Number(v.plus); }); this.setData({ cartList: data });7. 組件化復用開發實踐
組件化解構項目元件,提高開發效率,可參照官方介紹起步 !
這里介紹一個自定義的跑馬燈的輪播圖組件實例
(1) 第一步,查看目錄結構劃分,主要為 Carousel 組件 在 index 頁面的使用│ ├───component │ └───Carousel │ Carousel.js │ Carousel.json │ Carousel.wxml │ Carousel.wxss │ ├───filter │ filter.wxs │ ├───pages │ └───index │ index.js │ index.json │ index.wxml │ index.wxss │ └───utils api.js runtime.js util.js(2) 第二步我們分析看如何使用,設計 組件需要的 props
數據項,必須 bannerList
輪播圖的固定高度 swiperHeight
自定義輪播按鈕小點,寬與高一致,圓形 dotWidthAndHeight
輪播按鈕盒子距離頂部的高度 dotTop
最終在 index.wxml 的實際使用
(3).業務代碼編寫
Carousel.json
開啟自定義組件模式
{ "component": true }
Carousel.wxml
Carousel.js
Component({ /** * 組件的屬性列表 必須 */ properties: { bannerList: { // 屬性名 type: Array, // 類型(必填),目前接受的類型包括:String, Number, Boolean, Object, Array, null(表示任意類型) value: [], // 屬性初始值(可選),如果未指定則會根據類型選擇一個 observer: function(newVal, oldVal) {} // 屬性被改變時執行的函數(可選),也可以寫成在methods段中定義的方法名字符串, 如:"_propertyChange" }, dotWidthAndHeight: String, swiperHeight: String, // swiper 高度 dotTop: String // 小點距離頂部高度 }, /** * 組件的初始數據 */ data: { swiperCurrentIndex: 0, indicatorDots: false // 自定義輪播按鈕 }, /** * 組件的方法列表 */ methods: { swiperChange: function(e) { var source = e.detail.source; if (source === "autoplay" || source === "touch") { this.setData({ swiperCurrentIndex: e.detail.current }); } }, selectCarouselByIndex: function(e) { this.setData({ swiperCurrentIndex: Number(e.currentTarget.id) }); }, // 輪播圖跳轉至內部頁面 toHref(e) { const data = e.currentTarget.dataset; // type = 2,根據 goods_id 展示商品詳情 // type = 3, 展示富文本的活動詳情頁面 if (data.type === "2") { wx.navigateTo({ url: `../sort_detail/sort_detail?id=${data.id}` }); } else if (data.type === "3") { wx.yue.pub("renderData", data.content); wx.navigateTo({ url: `../activity_detail/activity_detail` }); } } } });更多
wxapp-rainbow 安利一下自己寫的小程序組件庫(偏功能性)
uploadImg 上傳圖片
carousel 輪播圖
authorization 授權登錄
loading 加載中
參考https://juejin.im/post/5c14b2...
微信小程序自定義組件VS vue組件實踐與理解
生態圈ColorUI 鮮亮的高飽和色彩,專注視覺的小程序組件庫
taro 多端統一開發框架,支持用 React 的開發方式編寫一次代碼,生成能運行在微信小程序、H5 、 React Native 等的應用
uni-app 使用 Vue.js 開發跨平臺應用的前端框架
微信小程序開發資源匯總
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/102816.html
摘要:無論是還是,對許多應用來說,這個大小都是完全可以接受的。但是為了不用,放棄向后兼容那我覺得還是用得了。自從年雙十一正式上線,累計處理了億錯誤事件,付費客戶有金山軟件百姓網等眾多品牌企業。 譯者按: 看來 jQuery 還是有一些用武之地的。 原文: Why Im Still Using jQuery in 2019 譯者: Fundebug 為了保證可讀性,本文采用意譯而非直譯...
摘要:我們的目標是找出最有職業投資回報率的主題和技術。比特幣在幾年內增長了若干個量級。比特幣倍拐點在這個圖表中,每個箭頭始于倍點,指向價格修正后的最低點。 showImg(https://segmentfault.com/img/remote/1460000017919159); 圖:Jon Glittenberg Happy New Year 2019 (CC BY 2.0) 又到了一年的...
摘要:云計算技術完全依賴于硬件和軟件的虛擬化及其面向服務的架構和其他一些增值服務。其次,一些政府贊成取消有利于網絡中立和促進競爭的法規。因此,云計算成為可行的選擇。盡管如此,云基礎架構必須與適當的安全和備份解決方案相輔相成,以確保數據安全。 隨著互聯網的高速發展,計算和軟件開發的進步,任何人都可以坐在他/她的廚房桌旁享受世界上最好的技術。幾乎所有小型或大型企業都無所謂,似乎已將注意力轉移到考...
摘要:云計算技術完全依賴于硬件和軟件的虛擬化及其面向服務的架構和其他一些增值服務。其次,一些政府贊成取消有利于網絡中立和促進競爭的法規。因此,云計算成為可行的選擇。盡管如此,云基礎架構必須與適當的安全和備份解決方案相輔相成,以確保數據安全。 隨著互聯網的高速發展,計算和軟件開發的進步,任何人都可以坐在他/她的廚房桌旁享受世界上最好的技術。幾乎所有小型或大型企業都無所謂,似乎已將注意力轉移到考...
摘要:月日,在阿里云峰會北京站上,阿里巴巴旗下的阿里云支付寶淘寶釘釘高德等聯合發布阿里巴巴小程序繁星計劃提供億元補貼,扶持萬小程序開發者萬商家。會上,阿里云正式發布了小程序云。看到繁星計劃已上熱搜。通過小程序云服務可以極大的降低交付部署成本。3月21日,在2019阿里云峰會·北京站上,阿里巴巴旗下的阿里云、支付寶、淘寶、釘釘、高德等聯合發布阿里巴巴小程序繁星計劃:提供20億元補貼,扶持200萬+小...
閱讀 1017·2023-04-25 22:27
閱讀 872·2021-11-22 14:56
閱讀 984·2021-11-11 16:54
閱讀 1678·2019-08-30 15:54
閱讀 3500·2019-08-30 13:20
閱讀 1213·2019-08-30 10:55
閱讀 2080·2019-08-26 13:34
閱讀 3281·2019-08-26 11:53