/**
* 1、小程序开发流程
*a、申请账号
*b、安装开发者工具
*c、编译预览
*d、打包提测发布上线
* ****/

/**
* 2、小程序代码构成
*a、wxml //模板
* wxml的标签有view, button, text等,wx:if、wx:for以及{{}},
* eg:
* <view wx:for="{{array}}"> {{item}} </view>
* <view> {{message}} </view>
* <view wx:if="{{view == 'WEBVIEW'}}"> WEBVIEW </view>
<view wx:elif="{{view == 'APP'}}"> APP </view>
<view wx:else="{{view == 'MINA'}}"> MINA </view>
*
* <--block wx:if--->
因为 wx:if 是一个控制属性,需要将它添加到一个标签上。如果要一次性判断多个组件标签,
可以使用一个 <block/> 标签将多个组件包装起来,并在上边使用 wx:if 控制属性。

<block wx:if="{{true}}">
<view> view1 </view>
<view> view2 </view>
</block>
注意: <block/> 并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性。

<--wx:if vs hidden--->
因为 wx:if 之中的模板也可能包含数据绑定,所以当 wx:if 的条件值切换时,框架有一个局部渲染的过程,
因为它会确保条件块在切换时销毁或重新渲染。

同时 wx:if 也是惰性的,如果在初始渲染条件为 false,框架什么也不做,
在条件第一次变成真的时候才开始局部渲染。

相比之下,hidden 就简单的多,组件始终会被渲染,只是简单的控制显示与隐藏。

一般来说,wx:if 有更高的切换消耗而 hidden 有更高的初始渲染消耗。因此,
如果需要频繁切换的情景下,用 hidden 更好,如果在运行时条件不大可能改变则 wx:if 较好。
*
*
*b、wxss //css样式
*
* 1、rpx(responsive pixel): 可以根据屏幕宽度进行自适应。规定屏幕宽为750rpx。如在 iPhone6 上,
* 屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素。
*
* 2、使用@import语句可以导入外联样式表;
*
* 3、行内样式: <view style="color:{{color}};" />
*
*
*
*c、json //json格式文件
*
* 在跟目录结构里,有一个app.json和project.config.json,pages/logs下有个logs.json
*
* <---app.json--->
* app.json此文件为当前小程序的全局配置,包含了所有页面路径、网络超时时间。底部tab等
* eg:
* {
"pages":[ //此字段为页面路径集合
"pages/index/index",
"pages/logs/logs"
],
"window":{ //此字段定义所有页面的顶部背景颜色,文字颜色,
"backgroundTextStyle":"light", //窗口的背景色
"navigationBarBackgroundColor": "#fff", //导航栏背景颜色
"navigationBarTitleText": "WeChat", //导航栏标题文字内容
"navigationBarTextStyle":"black" , //导航栏标题颜色
"backgroundTextStyle": "dark/light", //下拉 loading 的样式
"navigationStyle" : "default/custom" , //导航栏样式,一个是默认,一个是自定义
},
"tabBar": {
"list": [{
"pagePath": "pages/index/index",
"text": "首页"
}, {
"pagePath": "pages/logs/index",
"text": "日志"
}]
},
"networkTimeout": { //网络超时时间
"request": 10000,
"downloadFile": 10000
},
"debug": true, //是否开启 debug 模式,默认关闭
"navigateToMiniProgramAppIdList": [ //需要跳转的小程序列表,详见
"wxe5f52902cf4de896"
]
}
}

<---project.config.json--->
project.config.json是工具配置,每个项目的根目录都会生成,类似于package.json

<---page.json--->
page.json用来表示每个pages下的json文件,page.json下的配置项如果和app.json重复,则会覆盖掉公共的;
*
*d、js //js脚本逻辑
* 点击事件为 bindtap
* <button bindtap="clickMe">点击我</button>
* eg:
* Page({
clickMe: function() {
this.setData({ msg: "Hello World" })
}
})


事件列表:
touchstart 手指触摸动作开始
touchmove 手指触摸后移动
touchcancel 手指触摸动作被打断,如来电提醒,弹窗
touchend 手指触摸动作结束
tap 手指触摸后马上离开
longpress 手指触摸后,超过350ms再离开,如果指定了事件回调函数并触发了这个事件,tap事件将不被触发
longtap 手指触摸后,超过350ms再离开(推荐使用longpress事件代替)
transitionend 会在 WXSS transition 或 wx.createAnimation 动画结束后触发
animationstart 会在一个 WXSS animation 动画开始时触发
animationiteration 会在一个 WXSS animation 一次迭代结束时触发
animationend 会在一个 WXSS animation 动画完成时触发
touchforcechange 在支持 3D Touch 的 iPhone 设备,重按时会触发

* ****/

/***
3、小程序的双向绑定和vue哪里不一样?
小程序直接 this.data 的属性是不可以同步到视图的,必须调用:

this.setData({
// 这里设置
})
***/

/***
4、小程序页面间有哪些传递数据的方法?
app.js中定义全局变量globalData,将需要存储的信息放在里面,
// app.js

App({
// 全局变量
globalData: {
userInfo: null
}
})
使用的时候,直接使用 getApp() 拿到存储的信息

wx.navigateTo 和 wx.redirectTo 不允许跳转到 tab 所包含的页面

onLoad 只执行一次

使用本地缓存 Storage: wx.getStorageSync('logs')
wx.setStorageSync('logs', logs)

***/

/***
5、小程序的生命周期
onLoad()页面加载时触发,一个页面只调用一次,可以在onLoad的参数中获取打开当前页面路径中的参数;
onShow()页面显示/切入前台时触发;
onReady()页面初次渲染完成时触发,一页页面只调用一次,代表页面已经准备妥当,可以和视图层进行交互;
onHide()页面隐藏/切入后台时触发,如navigateTo或底部tab切换到其他页面,小程序切入后台等;
onUnload()页面卸载、销毁时触发,如redirectTo或navigateBack到其他页面时;
onResize()页面尺寸变化时执行;
onPageScroll()页面滚动时执行;
onPullDownRefresh()触发下拉刷新时执行;
onTabItemTap(item) tab 点击时执行;
onReachBottom()页面触底时执行;
onShareAppMessage()页面被用户分享时执行;
***/

/**
6、小程序性能提升
1、提高页面加载速度
2、用户行为预测
3、减少默认data的大小
4、组件化方案
* **/

/**
7、小程序优劣势
优势: 即用即走,不用安装,省流量,省安装时间,不占用桌面,
开发成本相对于app来说较低,推广交由优势;
缺点: 用户留存性不大,限制较多,页面大小不能超过2M,不能打开超过10个成绩的页面
* **/

/**
8、小程序异步请求问题
已支持es6语法,可以使用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' // 默认值 ,另一种是 "content-type": "application/x-www-form-urlencoded"
},
...other,
complete: (res) => {
wx.hideLoading();
console.log(`耗时${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
}
* **/

/**
9、如何实现下拉刷新

首先在全局 config 中的 window 配置 enablePullDownRefresh
在 Page 中定义 onPullDownRefresh 钩子函数,到达下拉刷新条件后,该钩子函数执行,发起请求方法
请求返回后,调用 wx.stopPullDownRefresh 停止下拉刷新

***/

/**
10、 bindtap和catchtap的区别是什么?

相同点:首先他们都是作为点击事件函数,就是点击时触发。在这个作用上他们是一样的,可以不做区分;

不同点:他们的不同点主要是bindtap是不会阻止冒泡事件的,catchtap是阻止冒泡的;

***/

/**
11、简述下 wx.navigateTo(), wx.redirectTo(), wx.switchTab(), wx.navigateBack(), wx.reLaunch()的区别

wx.navigateTo():保留当前页面,跳转到应用内的某个页面。但是不能跳到 tabbar 页面
wx.redirectTo():关闭当前页面,跳转到应用内的某个页面。但是不允许跳转到 tabbar 页面
wx.switchTab():跳转到 abBar 页面,并关闭其他所有非 tabBar 页面
wx.navigateBack()关闭当前页面,返回上一页面或多级页面。可通过 getCurrentPages() 获取当前的页面栈,决定需要返回几层
wx.reLaunch():关闭所有页面,打开到应用内的某个页面

***/