日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

小程序----面试题总结

發(fā)布時(shí)間:2023/12/31 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 小程序----面试题总结 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1. 簡單描述下微信小程序的相關(guān)文件類型

微信小程序項(xiàng)目結(jié)構(gòu)主要有四個(gè)文件類型

  • WXML(WeiXin Markup Language)是框架設(shè)計(jì)的一套標(biāo)簽語言,結(jié)合基礎(chǔ)組件、事件系統(tǒng),可以構(gòu)建出頁面的結(jié)構(gòu)。內(nèi)部主要是微信自己定義的一套組件
  • WXSS (WeiXin Style Sheets)是一套樣式語言,用于描述 WXML 的組件樣式
  • js 邏輯處理,網(wǎng)絡(luò)請求
  • json 小程序設(shè)置,如頁面注冊,頁面標(biāo)題及tabBar

主要文件

  • app.json
    必須要有這個(gè)文件,如果沒有這個(gè)文件,項(xiàng)目無法運(yùn)行,因?yàn)槲⑿趴蚣馨堰@個(gè)作為配置文件入口,整個(gè)小程序的全局配置。包括頁面注冊,網(wǎng)絡(luò)設(shè)置,以及小程序的
    window 背景色,配置導(dǎo)航條樣式,配置默認(rèn)標(biāo)題

  • app.js 必須要有這個(gè)文件,沒有也是會(huì)報(bào)錯(cuò)!但是這個(gè)文件創(chuàng)建一下就行
    什么都不需要寫以后我們可以在這個(gè)文件中監(jiān)聽并處理小程序的生命周期函數(shù)、聲明全局變量

  • app.wxss 可選

2. 簡述微信小程序原理

微信小程序采用 JavaScript、WXML、WXSS 三種技術(shù)進(jìn)行開發(fā),本質(zhì)就是一個(gè)單頁面應(yīng)用,所有的頁面渲染和事件處理,都在一個(gè)頁面內(nèi)進(jìn)行,但又可以通過微信客戶端調(diào)用原生的各種接口

微信的架構(gòu),是數(shù)據(jù)驅(qū)動(dòng)的架構(gòu)模式,它的 UI 和數(shù)據(jù)是分離的,所有的頁面更新,都需要通過對數(shù)據(jù)的更改來實(shí)現(xiàn)

小程序分為兩個(gè)部分 webview 和 appService 。其中 webview 主要用來展現(xiàn) UI ,appService 有來處理業(yè)務(wù)邏輯、數(shù)據(jù)及接口調(diào)用。它們在兩個(gè)進(jìn)程中運(yùn)行,通過系統(tǒng)層 JSBridge 實(shí)現(xiàn)通信,實(shí)現(xiàn) UI 的渲染、事件的處理

3. 小程序的雙向綁定和vue哪里不一樣

小程序直接 this.data 的屬性是不可以同步到視圖的,必須調(diào)用:

this.setData({// 這里設(shè)置 })

4. 小程序的wxss和css有哪些不一樣的地方

WXSS 和 CSS 類似,不過在 CSS 的基礎(chǔ)上做了一些補(bǔ)充和修改

  • 尺寸單位 rpx

rpx 是響應(yīng)式像素,可以根據(jù)屏幕寬度進(jìn)行自適應(yīng)。規(guī)定屏幕寬為 750rpx。如在 iPhone6 上,屏幕寬度為 375px,共有 750 個(gè)物理像素,則 750rpx = 375px = 750 物理像素

  • 使用 @import 標(biāo)識符來導(dǎo)入外聯(lián)樣式。@import 后跟需要導(dǎo)入的外聯(lián)樣式表的相對路徑,用;表示語句結(jié)束
/** index.wxss **/ @import './base.wxss';.container{color: red; }

5. 小程序頁面間有哪些傳遞數(shù)據(jù)的方法

  • 使用全局變量實(shí)現(xiàn)數(shù)據(jù)傳遞 在 app.js 文件中定義全局變量 globalData, 將需要存儲(chǔ)的信息存放在里面
// app.jsApp({// 全局變量globalData: {userInfo: null} })

使用的時(shí)候,直接使用 getApp() 拿到存儲(chǔ)的信息

  • 使用 wx.navigateTo 與 wx.redirectTo 的時(shí)候,可以將部分?jǐn)?shù)據(jù)放在 url 里面,并在新頁面 onLoad
    的時(shí)候初始化
//pageA.js// Navigate wx.navigateTo({url: '../pageD/pageD?name=raymond&gender=male', })// Redirect wx.redirectTo({url: '../pageD/pageD?name=raymond&gender=male', })// pageB.js ... Page({onLoad: function(option){console.log(option.name + 'is' + option.gender)this.setData({option: option})} })

需要注意的問題:
wx.navigateTo 和 wx.redirectTo 不允許跳轉(zhuǎn)到 tab 所包含的頁面
onLoad 只執(zhí)行一次

  • 使用本地緩存 Storage 相關(guān)

6. 小程序的生命周期函數(shù)

  • onLoad 頁面加載時(shí)觸發(fā)。一個(gè)頁面只會(huì)調(diào)用一次,可以在 onLoad 的參數(shù)中獲取打開當(dāng)前頁面路徑中的參數(shù)

  • onShow() 頁面顯示/切入前臺(tái)時(shí)觸發(fā)

  • onReady() 頁面初次渲染完成時(shí)觸發(fā)。一個(gè)頁面只會(huì)調(diào)用一次,代表頁面已經(jīng)準(zhǔn)備妥當(dāng),可以和視圖層進(jìn)行交互

  • onHide() 頁面隱藏/切入后臺(tái)時(shí)觸發(fā)。 如 navigateTo 或底部 tab 切換到其他頁面,小程序切入后臺(tái)等

  • onUnload() 頁面卸載時(shí)觸發(fā)。如 redirectTo 或 navigateBack 到其他頁面時(shí)

詳見 生命周期回調(diào)函數(shù)

7. 怎么封裝微信小程序的數(shù)據(jù)請求

參考 這里
網(wǎng)絡(luò)請求小程序提供了wx.request, 仔細(xì)看一下 api,這不就是n年前的 $.ajax 嗎,好古老啊。

// 官方例子 wx.request({url: 'test.php', //僅為示例,并非真實(shí)的接口地址data: {x: '' ,y: ''},header: {'content-type': 'application/json' // 默認(rèn)值},success: function(res) {console.log(res.data)} })

小程序支持ES6,那么就應(yīng)該支持Promise 了,很開心~, 話不多說直接上代碼吧

Promise封裝

const baseUrl = 'https://api.it120.cc';const http = ({ url = '', param = {}, ...other } = {}) => {wx.showLoading({title: '請求中,請耐心等待..'});let timeStart = Date.now();return new Promise((resolve, reject) => {wx.request({url: getUrl(url),data: param,header: {'content-type': 'application/json' // 默認(rèn)值 ,另一種是 "content-type": "application/x-www-form-urlencoded"},...other,complete: (res) => {wx.hideLoading();console.log(`耗時(shí)${Date.now() - timeStart}`);if (res.statusCode >= 200 && res.statusCode < 300) {resolve(res.data)} else {reject(res)}}})}) }const getUrl = (url) => {if (url.indexOf('://') == -1) {url = baseUrl + url;}return url }// get方法 const _get = (url, param = {}) => {return http({url,param}) }const _post = (url, param = {}) => {return http({url,param,method: 'post'}) }const _put = (url, param = {}) => {return http({url,param,method: 'put'}) }const _delete = (url, param = {}) => {return http({url,param,method: 'put'}) } module.exports = {baseUrl,_get,_post,_put,_delete }// 使用 const api = require('../../utils/api.js') // 單個(gè)請求 api.get('list').then(res => {console.log(res) }).catch(e => {console.log(e) })// 一個(gè)頁面多個(gè)請求 Promise.all([api.get('list'),api.get(`detail/${id}`) ]).then(result => {console.log(result) }).catch(e => {console.log(e) })

登陸問題
做一個(gè)應(yīng)用,肯定避免不了登錄操作。用戶的個(gè)人信息啊,相關(guān)的收藏列表等功能都需要用戶登錄之后才能操作。一般我們使用token做標(biāo)識。

小程序并沒有登錄界面,使用的是 wx.login 。 wx.login 會(huì)獲取到一個(gè) code,拿著該 code 去請求我們的后臺(tái)會(huì)最后返回一個(gè)token到小程序這邊,保存這個(gè)值為 token 每次請求的時(shí)候帶上這個(gè)值。

一般還需要把用戶的信息帶上比如用戶微信昵稱,微信頭像等,這時(shí)候就需要使用 wx.getUserInfo ,這里涉及到一個(gè)用戶授權(quán)的問題

帶上用戶信息就夠了嘛? too young too simple!我們的項(xiàng)目不可能只有小程序,相應(yīng)的微信公眾平臺(tái)可能還有相應(yīng)的App,我們需要把賬號系統(tǒng)打通,讓用戶在我們的項(xiàng)目中的賬戶是同一個(gè)。這就需要用到微信開放平臺(tái)提供的 UnionID 。

登陸

//app.js App({onLaunch: function () {console.log('App onLaunch');var that = this;// 獲取商城名稱wx.request({url: 'https://api.it120.cc/'+ that.globalData.subDomain +'/config/get-value',data: {key: 'mallName'},success: function(res) {wx.setStorageSync('mallName', res.data.data.value);}})this.login();this.getUserInfo();},login : function () {var that = this;var token = that.globalData.token;// 如果有tokenif (token) {// 檢查token是否有效wx.request({url: 'https://api.it120.cc/' + that.globalData.subDomain + '/user/check-token',data: {token: token},success: function (res) {// 如果token失效了if (res.data.code != 0) {that.globalData.token = null;that.login(); // 重新登陸}}})return;}// 【1】調(diào)用微信自帶登陸wx.login({success: function (res) {// 【2】 拿到code去訪問我們的后臺(tái)換取其他信息wx.request({url: 'https://api.it120.cc/'+ that.globalData.subDomain +'/user/wxapp/login',data: {code: res.code},success: function(res) {// 如果說這個(gè)code失效的if (res.data.code == 10000) {// 去注冊that.registerUser();return;}// 如果返回失敗了if (res.data.code != 0) {// 登錄錯(cuò)誤 wx.hideLoading();// 提示無法登陸wx.showModal({title: '提示',content: '無法登錄,請重試',showCancel:false})return;}// 【3】 如果成功后設(shè)置token到本地that.globalData.token = res.data.data.token;// 保存用戶信息wx.setStorage({key: 'token',data: res.data.data.token})}})}})},// 注冊?? [這個(gè)看需求]registerUser: function () {var that = this;wx.login({success: function (res) {var code = res.code; // 微信登錄接口返回的 code 參數(shù),下面注冊接口需要用到wx.getUserInfo({success: function (res) {var iv = res.iv;var encryptedData = res.encryptedData;// 下面開始調(diào)用注冊接口wx.request({url: 'https://api.it120.cc/' + that.globalData.subDomain +'/user/wxapp/register/complex',data: {code:code,encryptedData:encryptedData,iv:iv}, // 設(shè)置請求的 參數(shù)success: (res) =>{wx.hideLoading();that.login();}})}})}})},// 獲取用戶信息getUserInfo:function() {wx.getUserInfo({success:(data) =>{this.globalData.userInfo = data.userInfo;wx.setStorage({key: 'userInfo',data: data.userInfo})return this.globalData.userInfo;}})},globalData:{userInfo:null,subDomain:"34vu54u7vuiuvc546d",token: null} })

授權(quán)問題

getUserInfo: function () {// 先調(diào)用wx.getSetting 獲取用戶權(quán)限設(shè)置wx.getSetting({success(res) {console.log('1');if (!res.authSetting['scope.userInfo']) {wx.authorize({scope: 'scope.userInfo',success() {// 用戶已經(jīng)同意小程序使用錄音功能,后續(xù)調(diào)用 wx.getUserInfo接口不會(huì)彈窗詢問wx.getUserInfo({success: (data) => {this.globalData.userInfo = data.userInfo;wx.setStorage({key: 'userInfo',data: data.userInfo})return this.globalData.userInfo;}})}})} else {console.log(2);}}})},

授權(quán)2
小程序登錄流程
這里引用下官方的一張登錄流程圖,我就按照登錄流程圖來講下我的理解。

第一步
客戶端(小程序)獲取當(dāng)前微信登錄用戶的登錄憑證(code)
可通過wx.login api獲得。這里有地方需要注意
1.wx.login不會(huì)彈授權(quán)彈框
2.wx.login換取的code只能使用一次,如果需要新code只能重新調(diào)用wx.login接口

wx.login({success:(res)=>{let code= res.code}})

第二步
通過上一步獲得的臨時(shí)登錄憑證傳給服務(wù)器端獲取openid和session_key.服務(wù)器端需要通過appid、appsecret、(這里的數(shù)據(jù)可以從小程序管理后臺(tái)獲得)code(第一步獲取到的code)向微信服務(wù)端發(fā)送請求獲取seeeion_key和openid。為了安全。建議將獲得的session_key加密后再傳給客戶端。

第三步
客戶端獲得加密后的登錄態(tài)后把登錄態(tài)存在本地以便后面進(jìn)行業(yè)務(wù)請求。由于小程序中不存在cookie機(jī)制。所以可以把登錄態(tài)存儲(chǔ)在storage中。

以上就是微信官方登錄流程圖的一個(gè)大體過程。

但是在實(shí)際應(yīng)用中可能要復(fù)雜點(diǎn)?我們接下來看。

登錄態(tài)在實(shí)際應(yīng)用中的維護(hù)

這里看一下微信官方的說明
通過 wx.login 接口獲得的用戶登錄態(tài)擁有一定的時(shí)效性。
用戶越久未使用小程序,用戶登錄態(tài)越有可能失效。

反之如果用戶一直在使用小程序,則用戶登錄態(tài)一直保持有效。
具體時(shí)效邏輯由微信維護(hù),對開發(fā)者透明。

開發(fā)者只需要調(diào)用 wx.checkSession 接口檢測當(dāng)前用戶登錄態(tài)是否有效。

這說明如果用戶一直在使用小程序。登錄態(tài)就不會(huì)過期。反之就會(huì)過期。這里可以通過wx.checkSession api 來判斷登錄態(tài)是否過期。

接下來上代碼。來看下在應(yīng)用中的登錄態(tài)維護(hù)。
目前在小程序中需要拉起微信登錄授權(quán)的彈框。需要在wxml文件中調(diào)用button組件來調(diào)用:如下

<button bindgetuserinfo="getInfo" hover-class="none" open-type="getUserInfo"></button>

這樣用戶點(diǎn)擊按鈕的時(shí)候會(huì)彈出授權(quán)獲取用戶信息的彈窗。用戶點(diǎn)擊允許我們就可以拿到數(shù)據(jù)進(jìn)行登錄并進(jìn)行業(yè)務(wù)請求。 如果點(diǎn)擊拒絕可以獲取不需要登錄可查看的數(shù)據(jù)請求,并安利用戶拒絕后的結(jié)果。重新引導(dǎo)用戶進(jìn)行授權(quán)。

下面是用戶非首次進(jìn)入應(yīng)用的一個(gè)登錄態(tài)維護(hù)(首次進(jìn)入通過button來授權(quán)。所以success回調(diào)是不會(huì)執(zhí)行的。直接fail的回調(diào)。)

// 小程序啟動(dòng)判斷用戶是否授權(quán),根據(jù)是否授權(quán)來請求不同的業(yè)務(wù)數(shù)據(jù) wx.getSetting({success: (res) => {//用戶已授權(quán)if (res.authSetting['scope.userInfo']) {// 判斷登錄態(tài)是否過期wx.checkSession({// 登錄態(tài)未過期,直接進(jìn)行業(yè)務(wù)請求success: (res) => {//業(yè)務(wù)請求代碼。。。},// 登錄態(tài)已過期 。重新調(diào)用wx.login進(jìn)行登錄換取codefail: (res) => {// 可以在這里進(jìn)行重新登錄后的回調(diào)wx.login({success: function(res) {let code = res.code;}})}})}// 為授權(quán) else {// 執(zhí)行未授權(quán)的業(yè)務(wù)代碼}} })

附上登錄態(tài)過期的回調(diào)。

/*** 登錄失敗后重新登錄*/getToken: function(fn) {let that = this;let getLogin = new Promise((resolve, reject) => {//登錄獲取codewx.login({success: function(res) {var code = res.code;that.globalData.code = code;resolve([fn, code]);},fail: function(res) {reject();}})});getLogin.then(([fn, code]) => {return new Promise((resolve, reject) => {//使用該api需要在頁面通過button組件觸發(fā)授權(quán)彈窗wx.getUserInfo({success: function(res) {//這里的iv,encryptedData等數(shù)據(jù)是用來服務(wù)器端進(jìn)行解密的。let requestData = {"Data": {"IV": res.iv,"EncryptedData": res.encryptedData,"JsCode": code,},}//發(fā)送請求wx.request({url: that.apiList.login.getLogin,data: requestData,method: "POST",success: function(res) {//獲取到自定義登錄態(tài)存入storageif (res.data && res.data.Success) {that.globalData.token = res.data.Data.Key;wx.setStorageSync('LoginSessionKey', res.data.Data.Key);resolve(fn);} else {reject();}},fail: function() {Hq.tipMaskNoneIcon('您的網(wǎng)絡(luò)開小差了');}})}})});}).then((fn) => {that.getCountryInfo(fn);}, function() {}))},//執(zhí)行fn回調(diào)函數(shù)getCountryInfo: function(fn) {if (typeof fn == 'function') {//登錄成功后進(jìn)行業(yè)務(wù)請求。fn();} else {Hq.afterSend();}},

以上就是我的一些理解。有語句不通,邏輯不清晰的地方,請不吝留言賜教!

8. 哪些方法可以用來提高微信小程序的應(yīng)用速度

1、提高頁面加載速度
2、用戶行為預(yù)測
3、減少默認(rèn) data 的大小
4、組件化方案

9. 微信小程序的優(yōu)劣勢

優(yōu)勢

  • 即用即走,不用安裝,省流量,省安裝時(shí)間,不占用桌面
  • 依托微信流量,天生推廣傳播優(yōu)勢
  • 開發(fā)成本比 App 低

缺點(diǎn)

  • 用戶留存,即用即走是優(yōu)勢,也存在一些問題
  • 入口相對傳統(tǒng) App 要深很多
  • 限制較多,頁面大小不能超過2M。不能打開超過10個(gè)層級的頁面

10. 怎么解決小程序的異步請求問題

小程序支持大部分 ES6 語法

  • 在返回成功的回調(diào)里面處理邏輯
  • Promise 異步

11. 小程序關(guān)聯(lián)微信公眾號如何確定用戶的唯一性

如果開發(fā)者擁有多個(gè)移動(dòng)應(yīng)用、網(wǎng)站應(yīng)用、和公眾帳號(包括小程序),可通過 unionid 來區(qū)分用戶的唯一性,因?yàn)橹灰峭粋€(gè)微信開放平臺(tái)帳號下的移動(dòng)應(yīng)用、網(wǎng)站應(yīng)用和公眾帳號(包括小程序),用戶的 unionid 是唯一的。換句話說,同一用戶,對同一個(gè)微信開放平臺(tái)下的不同應(yīng)用,unionid 是相同的

12. 如何實(shí)現(xiàn)下拉刷新

  • 首先在全局 config 中的 window 配置 enablePullDownRefresh
  • 在 Page 中定義 onPullDownRefresh 鉤子函數(shù),到達(dá)下拉刷新條件后,該鉤子函數(shù)執(zhí)行,發(fā)起請求方法
  • 請求返回后,調(diào)用 wx.stopPullDownRefresh 停止下拉刷新

參考 這里:(https://juejin.im/post/5a781c756fb9a063606eb742)
下拉刷新和上拉加載是業(yè)務(wù)上一個(gè)很常見的需求,在微信小程序里,提供了下拉刷新的方法 onPullDownRefresh 。而實(shí)現(xiàn)上拉加載相對來說就比較不方便了。
下拉刷新
雖然微信的官方文檔有很多坑,但下拉刷新介紹的還是很全面的。在這里稍稍帶過。

  • 首先在全局 config 中的 window 配置 enablePullDownRefresh .
  • 在 Page 中定義 onPullDownRefresh 鉤子函數(shù)。到達(dá)下拉刷新條件后,該鉤子函數(shù)執(zhí)行,發(fā)起請求方法。
  • 請求返回后,調(diào)用 wx.stopPullDownRefresh 停止下拉刷新。

config

config = {pages: ['pages/index'],window: {backgroundTextStyle: 'light',navigationBarBackgroundColor: '#ccc',navigationBarTitleText: 'WeChat',navigationBarTextStyle: '#000',enablePullDownRefresh: true}}

page

onPullDownRefresh() {wepy.showNavigationBarLoading() setTimeout(()=>{this.getData = '數(shù)據(jù)拿到了'wepy.stopPullDownRefresh()wepy.hideNavigationBarLoading()this.$apply()},3000) }

效果如下:

你會(huì)發(fā)現(xiàn)下拉的過程有些僵硬。這實(shí)際上是沒有添加背景色的原因,加上背景色后再試試。

現(xiàn)在感覺好多了吧。下拉刷新有現(xiàn)成的配置和方法,很容易實(shí)現(xiàn),可上拉加載就不同了。

上拉加載

首先看一下要實(shí)現(xiàn)的效果,這是3g端的上拉加載。小程序要實(shí)現(xiàn)同樣的效果。

首先功能有

  • 點(diǎn)擊回到頂部 這個(gè)很好實(shí)現(xiàn),有對應(yīng)的回到頂部函數(shù)
  • 滑動(dòng)屏幕記錄當(dāng)前頁數(shù) 這個(gè)也很好實(shí)現(xiàn),主要是監(jiān)聽滾動(dòng)事件,判斷對應(yīng)滾動(dòng)條高度,去計(jì)算其與子容器的高度即可。
  • 上拉加載動(dòng)畫

這里有兩個(gè)實(shí)現(xiàn)的方案。一個(gè)是 page 自帶的下拉觸底鉤子事件 onReachBottom 能做的只是下拉到底部的時(shí)候通知你觸底了,一個(gè)是 scroll-view 標(biāo)簽自帶事件。現(xiàn)在用兩個(gè)方法分別實(shí)現(xiàn)一下上拉加載。

上拉觸底事件 onReachBottom

模板

<template><view class="loading"></view><view class="container" @touchmove="moveFn" @touchstart="startFn" @touchend="endFn"style="transform:translate3d(0,{{childTop}}px,0)"><repeat for="{{list}}" key="index" index="index" item="item"><view>{{ item }}<text>{{index}}</text></view></repeat></view> </template>

鉤子函數(shù)

data = {getData: '',top: 0,lastTop: 0,canDrag: false,list: [] } onReachBottom() {this.canDrag = true } methods = {moveFn(ev) {let nowY = ev.changedTouches[0].clientYnowY = nowY-this.lastTopif(nowY > 0 )this.canDrag = falseif( nowY<=0 && this.canDrag ) {this.top = nowY}if( -this.top>= this.maxTop )this.top = -this.maxTop},startFn(ev) {this.lastTop = ev.changedTouches[0].clientY },endFn() {if(this.top <= -this.maxTop) {this.text = "去請求數(shù)據(jù)了"setTimeout(()=>{this.text = "請求回來了"this.canDrag = falsethis.list.push(...["數(shù)據(jù)","數(shù)據(jù)","數(shù)據(jù)"])this.$apply()this.top = 0;return},1000)}},gotoTop() {wepy.pageScrollTo({scrollTop: 0})} }

滾動(dòng)容器實(shí)現(xiàn)上拉加載
scroll-view: 可滾動(dòng)視圖區(qū)域。

它的具體用法不贅述,看官方文檔就行了。這里提解決上述問題的方法即可。

  • bindscrolltolower 類比原生全局鉤子 onReachBottom

模板

<scroll-view scroll-y id="content" @scroll="scroll" @scrolltolower="lower" scroll-top="{{gotoTopNum}}" lower-threshold="100" style="transform:translate3d(0,{{childTop}}px,0)"><view class="sty-search" @touchmove="moveContent" @touchstart="startContent" @touchend="endContent">...</view> </scroll-view>

以上就是最終的模板,你可能在想為什么這么復(fù)雜。雖然復(fù)雜,但每個(gè)屬性都是有用的,當(dāng)然這其中有幾個(gè)坑在等著我們。

首先節(jié)點(diǎn)分為滾動(dòng)容器和子容器。

Q:為什么滾動(dòng)容器里嵌套一個(gè)子容器,并且將拖動(dòng)的三個(gè)方法綁定在它上面。
A:這是第一個(gè)坑,因?yàn)?scroll-view 容器不能綁定 touchmove 事件,那如果綁定了會(huì)怎么樣呢?不會(huì)怎么樣,事件鉤子不會(huì)調(diào)用。(這個(gè)坑在官方文檔查不出來,當(dāng)時(shí)綁定了不調(diào)用,在社區(qū)找到了解決方法,就是將touchmove事件綁定到子容器)

再來看代碼

methods = {async lower() {this.canDrag = true},scroll (ev) {this.scrollTop = ev.detail.scrollTopif (ev.detail.deltaY > 0) {this.canDrag = false}let nowSet = this.documentHeight+this.scrollTop-this.contentHeaderlet num = Math.ceil(nowSet/this.listHeight) - 1num = Math.floor(num / this.pageBean.pageSize) + 1num = (num > this.pageBean.pageNo) ? this.pageBean.pageNo : num if(num != this.page) {this.page = numthis.$apply()}},startContent(ev) {this.lastTop = ev.changedTouches[0].clientYif(!this.documentHeight){this.documentHeight = wx.getSystemInfoSync().windowHeight}/* 這句是解決回到頂部的bug */if (this.gotoTopNum || this.gotoTopNum==0) { this.gotoTopNum = undefined }},moveContent (ev) {let {pageNo,pageSize,totalCount} = this.pageBeanlet nowY = ev.changedTouches[0].clientYnowY = nowY-this.lastTopif (this.canDrag && nowY) {this.state = 1;if (nowY <= -this.maxMove) {nowY = -this.maxMove}if (nowY <= 0) {this.childTop = nowY} }},async endContent(ev) {let {pageNo,pageSize,totalCount} = this.pageBeanif (this.childTop === -this.maxMove) {/* 狀態(tài) */if (pageNo >= this.maxPage || pageNo * pageSize >= totalCount) {this.state = 0} else {this.pageBean.pageNo++ await this.fillData()this.childTop = 0this.canDrag = falsethis.$apply()}}/* 如果沒超過刷新高度則重置 */this.childTop = 0},gotoTop() {this.gotoTopNum = 0}, }

Q: 為什么要在 touchStart 的時(shí)候 將 gotoTopNum 置為 undefined?
A: 因?yàn)檫@個(gè)頁面有一個(gè)回到頂部的功能,當(dāng)回到頂部時(shí),gotoTopNum 置為0,再次下翻時(shí),雖然實(shí)際的 scrollTop 改變了,但是 gotoTopNum 還為0,再次點(diǎn)擊回到頂部時(shí),因?yàn)閿?shù)據(jù)未改變,視圖層就不會(huì)去更新。所以在 touchStart 的時(shí)候給 gotoTopNum 一個(gè)無效的值,再次點(diǎn)擊回到頂部時(shí),視圖層也就更新了。

原生滾動(dòng) OR scroll-view

END…了嗎…
并沒有。

真機(jī)測試
實(shí)現(xiàn)的上拉加載在模擬器上跑的很流暢,不存在問題。可是。
如果是蘋果機(jī)的話(暫時(shí)測試iphone5 和 iPhone7),存在這樣一個(gè)問題,上拉或下拉回彈效果,這個(gè)效果會(huì)影響上拉的距離。
這個(gè)問題想了很久,目前不能優(yōu)雅的解決。
所以就找產(chǎn)品經(jīng)理修改了需求,去掉了上拉動(dòng)畫效果 所以最終的效果就變成:

總結(jié)
1.在微信小程序里操作節(jié)點(diǎn)是昂貴的,比在瀏覽器里操作還昂貴(這是通過比較上拉加載功能在3g端和微信小程序的流暢度得來的),在 1.4.0 版本發(fā)布之后,雖然給出了很多操作節(jié)點(diǎn)的方法,比如得到一個(gè)節(jié)點(diǎn)的寬高、或者通過 id 選擇器得到一個(gè)節(jié)點(diǎn)。請盡量減少這些方法的調(diào)用頻率( 函數(shù)節(jié)流 )或 緩存結(jié)果
2.動(dòng)手之前先動(dòng)腦!!!不然會(huì)走很多彎路…

13. bindtap和catchtap的區(qū)別是什么

相同點(diǎn):首先他們都是作為點(diǎn)擊事件函數(shù),就是點(diǎn)擊時(shí)觸發(fā)。在這個(gè)作用上他們是一樣的,可以不做區(qū)分

不同點(diǎn):他們的不同點(diǎn)主要是bindtap是不會(huì)阻止冒泡事件的,catchtap是阻值冒泡的

14. 簡述下 wx.navigateTo(), wx.redirectTo(), wx.switchTab(), wx.navigateBack(), wx.reLaunch()的區(qū)別

  • wx.navigateTo():保留當(dāng)前頁面,跳轉(zhuǎn)到應(yīng)用內(nèi)的某個(gè)頁面。但是不能跳到 tabbar 頁面
  • wx.redirectTo():關(guān)閉當(dāng)前頁面,跳轉(zhuǎn)到應(yīng)用內(nèi)的某個(gè)頁面。但是不允許跳轉(zhuǎn)到 tabbar 頁面
  • wx.switchTab():跳轉(zhuǎn)到 abBar 頁面,并關(guān)閉其他所有非 tabBar 頁面
  • wx.navigateBack()關(guān)閉當(dāng)前頁面,返回上一頁面或多級頁面。可通過 getCurrentPages()
    獲取當(dāng)前的頁面棧,決定需要返回幾層
  • wx.reLaunch():關(guān)閉所有頁面,打開到應(yīng)用內(nèi)的某個(gè)頁面

總結(jié)

以上是生活随笔為你收集整理的小程序----面试题总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 亚洲激情网 | 97精品人妻一区二区三区蜜桃 | 性色视频| 8x8ⅹ成人永久免费视频 | 国产一区视频在线播放 | 中国a级大片 | 自拍超碰| 婷婷四房综合激情五月 | 欧美日韩激情在线观看 | 久久久999国产精品 天堂av中文在线 | 亚洲欧美日韩精品在线 | 播五月婷婷 | 欧美日韩操 | 欧美成人二区 | 青青青青青草 | 欧美特级一级片 | 久久久18| 色小姐综合| 国产91影院 | 亚洲黄色中文字幕 | 杨贵妃颤抖双乳呻吟求欢小说 | 欧美五月婷婷 | 超碰66| 亚洲视频网址 | 欧美色一区二区三区在线观看 | 国产主播中文字幕 | 国产乱妇无码大片在线观看 | 国模杨依粉嫩蝴蝶150p | 国产精品破处 | 国产精品99久久久久 | 老鸭窝视频在线观看 | 一区二区av在线 | 成人玩具h视频 | 久久人人爽天天玩人人妻精品 | 国产亚洲欧美视频 | 1024金沙人妻一区二区三区 | 草草地址线路①屁屁影院成人 | 成人在线视频在线观看 | 国产又黄又猛的视频 | 国产精品嫩草影院桃色 | 性综合网 | 亚洲视频高清 | 在线观看视频99 | 97视频在线免费观看 | h亚洲| 亚洲自拍偷拍网站 | av制服丝袜在线 | 99热黄色 | 男女性高潮免费网站 | 91精品国产乱码久久久久久久久 | 日本啪啪片| 欧美婷婷六月丁香综合色 | av在线浏览| 好吊视频一区二区三区四区 | 蜜桃臀一区二区三区 | 精品国产三级 | www日韩av | 亚洲免费黄网 | jizz日本在线播放 | www.国产麻豆 | 日韩成人福利视频 | 天堂√在线 | 国产一区二区视频免费 | 欧美色图在线播放 | 国产成人在线播放视频 | 亚洲搞av| av网站在线免费 | 在线观看亚洲精品视频 | 亚洲 欧美 日韩 国产综合 在线 | 中文字幕精品一区二区精品 | 制服丝袜先锋影音 | 伊人久久影院 | 亚洲国产精品毛片av不卡在线 | 夜夜爽天天干 | 熟女肥臀白浆大屁股一区二区 | 美女国产毛片a区内射 | 樱井莉亚av | 欧美偷拍另类 | 国产日韩欧美视频 | 一卡二卡三卡视频 | 中文字幕22页| 秋霞一区二区 | 国产午夜福利一区 | 亚洲第一页中文字幕 | 日本中文字幕在线视频 | www.色哟哟 | 女女同性女同一区二区三区九色 | 亚洲涩色 | 可以免费观看的毛片 | 国精产品一区一区三区在线 | 中文在线播放 | 午夜色网站 | 扩阴视频 | 中文字幕一区二区不卡 | 理论片91 | 深夜的私人秘书 | 色屋在线 | 91精品国产综合久久福利 | 免费看aaaaa级少淫片 |