一.微信小程序主要目录和文件的作用?
1.project.config.json项目配置文件,做一些个性化配置,例如界面颜色、编译配置等等
2.app.json当前小程序的全局配置,包括了小程序的所有页面路径、界面表现、网络超时时间、底部 tab 等
3.sitemap配置小程序及其页面是否允许被微信索引
4.pages里面包含一个个具体的页面
5.wxss页面样式,app.wxss 作为全局样式,会作用于当前小程序的所有页面,局部页面样式 page.wxss 仅对当前页面生效。
6.app.js小程序的逻辑
7.js页面逻辑
8.json页面配置
9.wxml页面结构
二.wxml与标准的html的异同?
1.都是用来描述页面的结构;
2.都由标签、属性等构成;
3.标签名字不一样,且小程序标签更少,单一标签更多;
4.多了一些 wx:if 这样的属性以及 {{ }} 这样的表达式
5.WXML仅能在微信小程序开发者工具中预览,而HTML可以在浏览器内预览
6.组件封装不同, WXML对组件进行了重新封装,
7.小程序运行在JS Core内,没有DOM树和window对象,小程序中无法使用window对象和document对象。
三.WXSS和CSS的异同?
1.都是用来描述页面的样子;
2.WXSS 具有 CSS 大部分的特性,也做了一些扩充和修改;
3.WXSS新增了尺寸单位,WXSS 在底层支持新的尺寸单位 rpx;
4.WXSS 仅支持部分 CSS 选择器;
5.WXSS 提供全局样式与局部样式
四.你是怎么封装微信小程序的数据请求的?
1.将所有的的接口放在统一的js文件中并导出
2.在app.js中创建封装请求数据的方法,并且添加统一的配置, 使用promise对象来封装请求
3.页面中调用封装的方法请求数据
五.小程序页面之间有哪些(传值)传递数据的方法?
1.设置标签的data-*属性,在方法中通过e.currentTarget.dataset获取到数据
六.小程序的双向绑定和vue的异同?
小程序直接this.data的属性是不可以同步到视图的,必须调用setData
七.小程序的生命周期函数
App:
Onlaunch() 生命周期回调——监听小程序初始化
Onshow() 生命周期回调——监听小程序启动或切前台
Onhide()生命周期回调——监听小程序切后台
页面:
1.onLoad() 页面加载时触发,只会调用一次,可获取当前页面路径中的参数。
2.onShow() 页面显示/切入前台时触发,一般用来发送数据请求;
3.onReady() 页面初次渲染完成时触发, 只会调用一次,代表页面已可和视图层进行交互。
4.onHide() 页面隐藏/切入后台时触发, 如底部 tab 切换到其他页面或小程序切入后台等。
5.onUnload() 页面卸载时触发,如redirectTo或navigateBack到其他页面时。
组件
1.created 组件生命周期函数-在组件实例刚刚被创建时执行, setData
2.attached 组件生命周期函数-在组件实例进入页面节点树时执行
3.ready 组件生命周期函数-在组件布局完成后执行
4.moved 组件生命周期函数-在组件实例被移动到节点树另一个位置时执行
5.detached 组件生命周期函数-在组件实例被从页面节点树移除时执行
6.lifetimes 组件生命周期声明对象
7.pageLifetimes 组件所在页面的生命周期声明对象
八.简述微信小程序原理
小程序的页面主要由四部分组成,分别是wxml、wxss、js、json。wxml用于构建用户界面,wxss用于编写界面的样式,js用于编写界面逻辑,json用于界面的配置。
微信的架构,是数据驱动的架构模式,它的 UI 和数据是分离的,所有的页面更新,都需要通过对数据的更改来实现
程序的渲染层和逻辑层分别由2个线程管理:渲染层的界面使用了WebView 进行渲染;逻辑层采用JsCore线程运行JS脚本。一个小程序存在多个界面,所以渲染层存在多个WebView线程,这两个线程的通信会经由微信客户端做中转,逻辑层发送网络请求也经由Native转发。
九.简单描述下微信小程序的 相关文件类型
WXML (WeiXin Markup Language)是框架设计的一套标签语言,结合基础组件、事件系统,可以构建出页面的结构。内部主要是微信自己定义的一套组件。
WXSS (WeiXin Style Sheets)是一套样式语言,用于描述 WXML 的组件样式,
js 逻辑处理,网络请求
json 小程序设置,如页面注册,页面标题及tabBar。
app.json
必须要有这个文件,如果没有这个文件,项目无法运行,因为微信框架把这个作为配置文件入口,整个小程序的全局配置。包括页面注册,网络设置,以及小程序的window背景色,配置导航条样式,配置默认标题。
app.js
必须要有这个文件,没有也是会报错!但是这个文件创建一下就行 什么都不需要写以后我们可以在这个文件中监听并处理小程序的生命周期函数、声明全局变量。
app.wxss
小程序的公共样式
十.哪些方法来提高微信小程序的应用速度?
1.精简代码,降低WXML结构和JS代码的复杂性;
2.合理使用setData调用,减少setData次数和数据量
3.必要时使用分包优化
十一分析微信小程序的优劣势?
优势.
劣势
1.大小限制为2M,这导致无法开发大型的应用。
2.不能直接分享到朋友圈。
3.需要像app一样审核上架,这点相对于H5的发布要麻烦一些
4.微信对小程序的开发也有限制
十二.小程序和H5的区别?
传统的HTML5的运行环境是浏览器,包括webview,而微信小程序的运行环境并非完整的浏览器,是微信开发团队基于浏览器内核完全重构的一个内置解析器,针对小程序专门做了优化,配合自己定义的开发语言标准,提升了小程序的性能。
只在微信中运行,所以不用再去顾虑浏览器兼容性,不用担心生产环境中出现不可预料的奇妙BUG
3. 获取系统级权限的不同
系统级权限都可以和微信小程序无缝衔接
4.在生产环境的运行流畅度
长久以来,当HTML5应用面对复杂的业务逻辑或者丰富的页面交互时,它的体验总是不尽人意,需要不断的对项目优化来提升用户体验。但是由于微信小程序运行环境独立
十三.解决微信小程序的异步请求问题?
1.精简代码,降低WXML结构和JS代码的复杂性;
2. 合理使用setData调用,减少setData次数和数据量
3.必要时使用分包优化
十四.小程序关联微信公众号如何确定用户的唯一性?
可通过 union_id来区分用户的唯一性,因为只要是同一个微信开放平台帐号下的移动应用、网站应用和公众帐号(包括小程序),用户的 union_id 是唯一的。换句话说,同一用户,对同一个微信开放平台下的不同应用,union_id 是相同的
十五.小程序如何实现下拉刷新?
1.需要在app.json的window选项中或页面配置中开启enablePullDownRefresh。
2.可以通过wx.startPullDownRefresh触发下拉刷新,调用后触发下拉刷新动画,效果与用户手动下拉刷新一致。
3.当处理完数据刷新后,wx.stopPullDownRefresh可以停止当前页面的下拉刷新。
4.用户执行下拉刷新的时候会触发onPullDownRefresh函数
十六.bindtap和catchtap的区别?
1.bind事件绑定不会阻止冒泡事件向上冒泡,catch事件绑定可以阻止冒泡事件向上冒泡
十七.wx.navigateTo(),wx.redirectTo(),wx.switchTab(),wx.navigateBack(),wx.reLaunch()的区别?
wx.navigateTo:
用于保留当前页面、跳转到应用内的某个页面,使用 wx.navigateBack可以返回到原页面。对于页面不是特别多的小程序,通常推荐使用 wx.navigateTo进行跳转, 以便返回原页面,以提高加载速度。当页面特别多时,则不推荐使用。
wx.redirectTo:
当页面过多时,被保留页面会挤占微信分配给小程序的内存,或是达到微信所限制的 5 层页面栈。这时应该考虑选择 wx.redirectTo。wx.redirectTo()用于关闭当前页面,跳转到应用内的某个页面。这样的跳转,可以避免跳转前页面占据运行内存,但返回时页面需要重新加载,增加了返回页面的显示时间。
wx.reLaunch:
wx.reLaunch()与 wx.redirectTo()的用途基本相同, 只是 wx.reLaunch()先关闭了内存中所有保留的页面,再跳转到目标页面。
wx.switchTab:
对于跳转到 tab bar 的页面,最好选择 wx.switchTab(),它会先关闭所有非 tab bar 的页面。其次,也可以选择 wx.reLaunch(),它也能实现从非 tab bar 跳转到 tab bar,或在 tab bar 间跳转,效果等同 wx.switchTab()。使用其他跳转 API 来跳转到 tab bar,则会跳转失败。
wx.navigateBack:
用于关闭当前页面,并返回上一页面或多级页面。开发者可通过 getCurrentPages() 获取当前的页面栈,决定需要返回几层。这个 API 需要填写的参数只有 delta,表示要返回的页面数。若 delta 的取值大于现有可返回页面数时,则返回到用户进入小程序的第一个页面。当不填写 delta 的值时,就默认其为 1(注意,默认并非取 0),即返回上一页面。
十八.小程序和Vue写法的区别?
1.数据请求
在页面加载请求数据时,两者钩子的使用有些类似,vue一般会在created或者mounted中请求数据,而在小程序,会在onLoad或者onShow中请求数据。
2.数据绑定
vue动态绑定一个变量的值为元素的某个属性的时候,会在变量前面加上冒号:
小程序绑定某个变量的值为元素属性时,会用两个大括号括起来,如果不加括号,为被认为是字符串
3.显示隐藏
vue中,使用v-if 和v-show控制元素的显示和隐藏
小程序中,使用wx-if和hidden控制元素的显示和隐藏
4.数据处理
vue:使用v-on:event绑定事件,或者使用@event绑定事件
//阻止事件冒泡
小程序中,全用bindtap(bind+event),或者catchtap(catch+event)绑定事件
//阻止事件冒泡
5.绑定事件传参
在vue中,需要在触发事件的方法中,把需要传递的数据作为形参传入就可以了
new Vue({
el: '#app',
methods:{
say(arg){
consloe.log(arg)
}
}
})
在小程序中,不能直接在绑定事件的方法中传入参数,需要将参数作为属性值,绑定到元素上的data-属性上,然后在方法中,通过e.currentTarget.dataset.*的方式获取
Page({
data:{
reason:''
},
toApprove(e) {
let id = e.currentTarget.dataset.id;
}
})
十九.小程序与原生App那个好?
小程序除了拥有公众号的低开发成本、低获客成本低以及无需下载等优势,在服务请求延时与用户使用体验是都得到了较大幅度 的提升,使得其能够承载跟复杂的服务功能以及使用户获得更好的用户体验。
区别
优点:
缺点
用完即走因为没办法多任务处理,你的产品如果不能在一定时间内完成特定场景的需求并且达成自己的目标,你就比较难做。
二十.小程序的发布流程(开发流程)
1.申请注册微信小程序账号,注意:注册账号之后会有一个AppID,下载微信开发者工具,新建项目的时候需要填上,否则很多功能用不了,比如不能预览、不能上传代码等问题。
2.通过微信开发工具新建项目。
3.根据业务需求配置小程序,并进行业务代码的开发。
4.如果涉及到发送请求,需要在小程序后台管理页面配置服务器合法域名,或者关闭域名校验(部署则必须配置合法域名,域名必须是https协议的,并且已经备案了)(这里有可能问http和https的区别)
5.开发完成之后点击上传代码可以将小程序发不到体验版
6.体验版确定无误后提交审核,审核通过后就可以正式上线了。
Uniapp
优点:
a. 一套代码可以生成多端
b. 学习成本低,语法是vue的,组件是小程序的
c. 拓展能力强
d. 使用HBuilderX开发,支持vue语法
e. 突破了系统对H5调用原生能力的限制
缺点:
a. 问世时间短,很多地方不完善
b. 社区不大
c. 官方对问题的反馈不及时
d. 在Android平台上比微信小程序和iOS差
e. 文件命名受限
pages.json
配置文件,全局页面路径配置,应用的状态栏、导航条、标题、窗口背景色设置等
main.js
入口文件,主要作用是初始化vue实例、定义全局组件、使用需要的插件如 vuex,注意uniapp无法使用vue-router,路由须在pages.json中进行配置。如果开发者坚持使用vue-router,可以在插件市场找到转换插件。
App.vue
是uni-app的主组件,所有页面都是在App.vue下进行切换的,是页面入口文件。但App.vue本身不是页面,这里不能编写视图元素。除此之外,应用生命周期仅可在App.vue中监听,在页面监听无效。
pages
页面管理部分用于存放页面或者组件
manifest.json
文件是应用的配置文件,用于指定应用的名称、图标、权限等。HBuilderX 创建的工程此文件在根目录,CLI 创建的工程此文件在 src 目录。
package.json
配置扩展,详情内容请见官网描述package.json概述
页面生命周期
1. onLoad:首次进入页面加载时触发,可以在 onLoad 的参数中获取打开当前页面路径中的参数。
2. onShow:加载完成后、后台切到前台或重新进入页面时触发
3. onReady:页面首次渲染完成时触发
4. onHide:从前台切到后台或进入其他页面触发
5. onUnload:页面卸载时触发
6. onPullDownRefresh:监听用户下拉动作
7. onReachBottom:页面上拉触底事件的处理函数
8. onShareAppMessage:用户点击右上角转发
组件生命周期:
uni-app 组件支持的生命周期,与vue标准组件的生命周期相同。这里没有页面级的onLoad等生命周期:
函数名 |
说明 |
平台差异说明 |
函数名 |
说明 |
beforeCreate |
在实例初始化之后被调用 |
beforeCreate |
在实例初始化之后被调用 |
|
created |
在实例创建完成后被立即调用 |
created |
在实例创建完成后被立即调用 |
|
beforeMount |
在挂载开始之前被调用 |
beforeMount |
在挂载开始之前被调用 |
|
mounted |
挂载到实例上去之后调用, 注意:此处并不能确定子组件被全部挂载,如果需要子组件完全挂载之后在执行操作可以使用$nextTickVue官方文档 |
mounted |
挂载到实例上去之后调用, 注意:此处并不能确定子组件被全部挂载,如果需要子组件完全挂载之后在执行操作可以使用$nextTickVue官方文档 |
|
beforeUpdate |
数据更新时调用,发生在虚拟 DOM 打补丁之前 |
仅H5平台支持 |
beforeUpdate |
数据更新时调用,发生在虚拟 DOM 打补丁之前 |
updated |
由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子 |
仅H5平台支持 |
updated |
由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子 |
beforeDestroy |
实例销毁之前调用。在这一步,实例仍然完全可用 |
beforeDestroy |
实例销毁之前调用。在这一步,实例仍然完全可用 |
globalDate和微信小程序中一样,是定义在全局上的对象,他类似于vuex,用来共享全局状态,在组件和页面中可以使用getApp().globalData来获取和修改全局变量。
//app.vue
//在其他页面调用/修改全局变量
getApp().globalData.msg= 'hello world'
每个平台有自己的一些特性,因此会存在一些无法跨平台的情况。因此就有了条件编译这个模式,不仅是js逻辑代码,template和css样式都可以设置成在某个环境中生效,在其他环境不生效。
//template
//js
// #ifndef H5
// 表示只有 h5 不使用这个 api
uni.createAnimation(OBJECT)
// #endif
//css
/* #ifdef MP-WEIXIN */
/* 只在小程序中生效 */
.header {
color:red
}
/* #endif */
//选择文件
uni.chooseFile({
count: 6, //默认100
extension:['.zip','.doc'],
success: function (res) {
console.log(JSON.stringify(res.tempFilePaths));
}
});
// 选择图片文件
uni.chooseFile({
count: 10,
type: 'image',
success (res) {
// tempFilePath可以作为img标签的src属性显示图片
const tempFilePaths = res.tempFiles
}
})
const request = (config) => {
// 处理 apiUrl
config.url = '你的链接服务器地址' + config.url;
if(!config.data){
config.data = {};
}
let promise = new Promise(function(resolve, reject) {
uni.request(config).then(responses => {
// 异常
if (responses[0]) {
reject({message : "网络超时"});
} else {
let response = responses[1].data;
resolve(response);
}
}).catch(error => {
reject(error);
})
})
return promise;
};
export default request;
rpx |
相当于把屏幕宽度分为750份,1份就是1rpx |
px |
绝对单位,页面按精确像素展示 |
em |
相对单位,相对于它的父节点字体进行计算 |
rem |
相对单位,相对根节点html的字体大小来计算 |
% |
一般来说就是相对于父元素 |
vh |
视窗高度,1vh等于视窗高度的1% |
vm |
视窗宽度,1vw等于视窗宽度的1% |
存储:uni.setStorage({key:“属性名”,data:“值”}) //异步
uni.setStorageSync(KEY,DATA) //同步
接收:uni.getStorage({key:“属性名”,success(res){res.data}}) //异步
uni.getStorageSync(KEY) //同步
移除:uni.removeStorage(OBJECT) //从本地缓存中异步移除指定 key。
uni.removeStorageSync(KEY) //从本地缓存中同步移除指定 key。
清除:uni.clearStorage() //清理本地数据缓存。
uni.clearStorageSync() //同步清理本地数据缓存。
事件总线可以作为组件沟通的桥梁,就像是所有组件共用相同的事件中心,可以向该中心注册发送事件或接收事件,所以组件都可以上下平行地通知其他组件,但也就是太方便所以若使用不慎,就会造成难以维护的灾难
触发事件
在uni中可以通过uni.$emit(eventName,OBJECT)来触发全局的自定事件。附加参数都会传给监听器回调。
监听事件
uni.$on(eventName,callback)
监听全局的自定义事件。事件可以由 uni.$emit 触发,回调函数会接收所有传入事件触发函数的额外参数。
只监听一次
uni.$once(eventName,callback)
监听全局的自定义事件。事件可以由 uni.$emit 触发,但是只触发一次,在第一次触发之后移除监听器。
移除监听
uni.$off([eventName, callback])
移除全局自定义事件监听器。