小程序
1. wxss和css的区别?
- wxss是小程序配合wxml渲染结构样式
- css是网页结合html渲染结构样式
- wxss新增了rpx,适配单位, 750rpx等于整屏的宽度
- wxss区分全局样式和局部样式,全局样式app.wxss,局部样式,每个页面内部的wxss文件,权重,先看权重,谁的权重高就会把另一个覆盖,同等权重,局部的覆盖全局的
2. 原生小程序组件使用过哪些?
- view: 盒子
- text: 文本
- richtext: 富文本,可以通过nodes节点解析html标签
- scroll-view: 滚动区域
- swiper: 轮播图
- button: 按钮组件
3. 原生小程序中如何绑定事件?
- 通过bind: 或者bind
4. 原生小程序中如何修改数据并同步视图?
- this.setData(), 既可以更改数据,也可以同步视图
- 不可以直接修改数据, 直接this.data.数据名, 之更改数据,视图不变
5. 事件传参?
- 通过data-属性名, 核心通过自定义属性进行传参
- 通过事件对象的currentTarget里面的dataset获取到数据
6. 小程序中发起网络请求
- 通过WX.request,而且这个方法不支持promise,所使用原生小程序开发,需要对wx.request进行二次封装
- 小程序中不存在跨域的问题
7. 导航跳转方式?
- 声明式导航(navigator标签进行跳转),跳转到tabbar页面,需要配合open-type="switchTab",open-type="navigateBack" delta="层级"
- 编程式导航: wx.navigatorTo() 普通页面的跳转, wx.switchTab跳转到tabbar页面,wx.navigateBack
- 导航传参: 通过query(?根参数 key=value&key=value), 接收参数,通过onLoad的形参去接收
8. 监听上拉触底
- onReachBottom监听到触底
9. 小程序的生命周期函数?
- 应用的生命周期
// 触发一次 onLaunch() { console.log('小程序开启启动,初始化完成') }, // 小程序显示,多次触发 onShow() { console.lg('小程序显示了') }, onHide() { console.log('小程序隐藏了') }, onError() { console.log('小程序出现异常') },
- 页面的生命周期
// 1. onLoad 页面开始加载 发送请求获取数据,获取到导航参数 // 2. onShow 页面显示 (多次触发) 提示信息 // 3. onReady 页面初次渲染完成 // 4. onHide 页面隐藏 tabbar页面切换只是隐藏 // 5. onUnload 页面销毁 不是tabbar页面 b页面 返回 A页面对应的页面销毁 // 清理操作
- 组件的生命周期函数
生命周期 | 参数 | 描述 | 最低版本 |
created | 无 | 在组件实例刚刚被创建时执行(拿到数据) | |
attached | 无 | 在组件实例进入页面节点树时执行 | |
ready | 无 | 在组件在视图层布局完成后执行 | |
moved | 无 | 在组件实例被移动到节点树另一个位置时执行 | |
detached | 无 | 在组件实例被从页面节点树移除时执行 | |
error | Object Error | 每当组件方法抛出错误时执行 |
10. 定义全局组件和局部组件
全局组件
- 创建一个组件
- 通过app.json中的useingComponets进行组件注册,注册为全局组件
局部组件
- 创建一个组件
- 通过页面的json中的useingComponets进行组件注册,注册为局部组件
11. 组件通信
父向子传值
- 父组件通过属性绑定传递
<local-swiper list="{{swipers}}"></local-swiper>
- 子组件通过properties进行接收
properties: { list: { type: Array, required: true } },
子向父传值
- 子组件传值
this.triggerEvent('自定义事件名', 传递的数据)
- 父组件接收, 通过bind:绑定自定义的事件名, 通过事件函数的e.detail获取到子组件传递的数据
<local-swiper bind:onImage="getImage" list="{{swipers}}"></local-swiper>
- 通过事件函数的e.detail接收数据
getImage(e) { console.log(e.detail) },
获取子组件的方式
- 通过selectComponents获取子组件
this.selectComponent('组件对应的选择器')
12. wxs是什么?
wxs weixin script: 在模板中无法调用js中定义的函数,可以调用wxs定义的函数,一般用wxs进行数据处理
缺点:
- 不支持es6
- 不支持小程序的api
- 隔离性, wxs和js不能互相调用
优点:
- 没有兼容性(小程序的版本库)
- 在ios设备上比js快2-20倍
13. 原生小程序上线流程
- 代码进行上传
- 将版本设置为体验版本(产品和ui进行体验)(测试)
- 改bug,重复1\2步骤
- 提交审核
- 审核通过点击发布
14. uni-app小程序的上线流程
- 在hbuilderX中发行-小程序,就会打包
- 在微信开发者工具中点击上传,弹出填写上传信息,填写完毕进行上传
- 登录小程序管理系统(开发人员不会参与)
- 将版本设置为体验版本(产品和ui进行体验)(测试人员进行测试)
- 改bug,重复1\2步骤
- 提交审核
- 审核通过点击发布
15. 登录流程
- 微信授权登录
1.1 获取用户信息(iv, rawData, encrytedData,signature)
const userInfo = await uni.getUserProfile({ desc: '黑马优购获取您的用户信息' }) const { iv, rawData, encrytedData, signature } = userInfo[1]
1.2 调用uni-app的login方法获取code(用户唯一标识)
const { code } = await uni.login()
- 根据微信授权的信息进行接口登录
const res = await login({ iv, rawData, encryptedData, signature, code })
- 登录成功后
- 将token存到vuex
- 判断是否有回跳地址,如果有,从哪来回哪去
16. 支付流程
- 根据购买的商品信息生成订单,从而得到订单号
async createOrder() { // 要购买的商品 const payGoods = this.$store.state.cart.list.filter(item => item.goods_state) // 通过map进行格式化 const goods = payGoods.map(item => { return { goods_id: item.goods_id, goods_number: item.goods_count, goods_price: item.goods_price } }) // 调起创建订单的接口 const { message: { order_number } } = await createOrder({ order_price: this.totalPrice, consignee_addr: this.$store.getters['user/addressStr'], goods: goods }) // 获取到订单id this.payGoods(order_number) },
- 预支付: 根据订单号得到支付的参数
async payGoods(order_number) { // 获取支付参数 const { message: { pay } } = await getPayParams({ order_number }) // },
- uni.requestPayMent: 支付,需要很多参数
// 发起微信支付 const [err, res] = await uni.requestPayment(pay) if (err) { uni.showToast('取消支付,跳转订单页面') } else { uni.showToast('支付成功,跳转订单页面') }
17. tabbar页面切换如何传递参数
- 利用reLaunch
uni.reLaunch({ url: '/pages/my/my?url=123' })
- vuex
- 本地
18. uni-app从头开始写项目
18. 1介绍
- 原生小程序和vue的结合
原生(写法相同): 组件\生命周期\api
vue: 数据绑定\数据渲染\事件绑定\逻辑的定义\计算属性\watch\过滤器\自定义指令\vuex 等等逻辑的处理
独立:
- App.vue (app.js和app.wxss)
- pages.json(app.json): 配置页面的路径和窗口的外观,全局组件也在这里进行注册,tabbar也是在该位置进行配置
- manifest.json打包配置: 不同的平台配置不同
18. 2创建项目
18.3 运行项目
点击运行
配置微信开发者工具的路径
微信开发者工具开启服务端口
18.4 外观配置
在pages.json中通过globalstyle进行配置
"globalStyle": { "navigationBarTextStyle": "black", "navigationBarTitleText": "uni-app", "navigationBarBackgroundColor": "#F8F8F8", "backgroundColor": "#F8F8F8" },
18.5 tabbar的配置
在pages.json中通过tabbar进行配置
"tabBar": { "list": [ { "pagePath": "页面路径", "iconPath": "图标路径", "selectedIconPath": "选中的图标路径", "text": "文本" } ], },
18.6 创建全局组件
- 在项目根目录创建components目录
- 右键创建组件
- 直接使用
<view> <uni-demo></uni-demo> </view>
18.7 新建页面
在pages上右键进行新建页面
填写创建页面的信息
设为首页,可以在pages.json中进行配置
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages { "path": "pages/index/index", "style": { "navigationBarTitleText": "uni-app" } } ,{ "path" : "pages/home/home", "style" : { "navigationBarTitleText": "", "enablePullDownRefresh": false } } ],
18.8 组件库(vant-weapp)
1、npm init -y
2、下包
npm i @vant/weapp -S --production
3、在项目的根目录创建一个wxcomponents目录
4、修改名字
5、定义全局组件
"usingComponents": { "van-button": "/wxcomponents/weapp/button/index" }
6、使用
18.9 封装request
1、使用flyio
npm i flyio
2、在utils目录下新建request.js
import Fly from 'flyio/dist/npm/wx' import store from '@/store' const fly = new Fly() // 配置请求的基准地址, 将请求地址添加到服务器合法域名 fly.config.baseURL = '' // 请求拦截器(拦截所有基于fly实例发出的请求, 统一携带token,配置请求头等) //添加请求拦截器 fly.interceptors.request.use((request) => { uni.showLoading({ title: '...加载中' }) // 满足该条件的携带token return request; }) //添加响应拦截器,响应拦截器会在then/catch处理之前执行(对数据进行剥离,以及进行统一的错误处理) fly.interceptors.response.use( (response) => { uni.hideLoading() //只将请求结果的data字段返回 if (response.data.meta.status !== 200) { uni.showToast({ title: '获取数据失败', icon: 'error' }) return Promise.reject(new Error('请求失败')) } return response.data }, (err) => { //发生网络错误后会走到这里 //return Promise.resolve("ssss") } ) export default fly
3、接口还需要在小程序管理后台中配置服务合法域名,如果目前还没有合法域名,
4、新建api目录,进行api的封装
18.10 vuex状态管理
1、无需下载,直接新建store目录,新建index.js, 借助createLogger进行vuex的数据调试
import Vue from 'vue' // 默认导入和按需导入和合并语法 import Vuex, { createLogger } from 'vuex' import cart from './modules/cart.js' Vue.use(Vuex) const store = new Vuex.Store({ state: {}, mutations: {}, actions: {}, getters: {}, modules: { // 购物车模块 cart }, plugins: process.env.NODE_ENV !== 'production' ? [createLogger()] : [] }) export default store
2、在main.js中引入,挂载
import store from './store' const app = new Vue({ store, ...App })
19. 原生小程序开发项目
19.1 创建项目
1、利用微信开发者工具进行创建
2、填写项目基本信息
19.2 项目清理
1、创建新的首页,app.json中pages选项下新增路径,页面自动生成
2、pages下新建目录,在目录下在新建page也会自动生成,同时路径也会自动生成
- 删除index和log
- 配置小程序的外观,app.json中进行window和tabbar的配置
19.3 封装request
1、对wx.request进行二次封装
const baseURL = '' export function request({ url, method = "GET", data }) { return new Promise((resolve, reject) => { wx.request({ url: baseURL + url, method, data, success(res) { resolve(res) }, fail(err) { reject(err) } }) }) }
19.4 定义数据和渲染数据
- 定义到data,
- 数据渲染
- {{}},所有的数据均通过{{}},
- 列表渲染wx:for,
- 条件渲染wx:if wx:elif wx:else hidden
19.5 数据修改和事件绑定
1、数据修改
- this.setData({要修改的数据}), 既可以更新数据也可以更新视图
2、事件绑定
- 通过bind: 或bindtap
- 事件函数定义在和data平级
- 事件传参: 通过data-自定义属性传,接收通过e.currentTarget.detail.dataSet
19.6 组件注册
- 全局组件
-
-
- 注册组件: 在app.json中的
"usingComponents": { "my-aaa": "/components/my-aaa/my-aaa" },
- 局部组件,在页面内部的json文件中进行配置
{ "usingComponents": {} }
19.7 页面导航
1、声明式导航
- 普通页面: <navigator url="地址"></navigator>
- tabbar页面: <navigator url="地址" open-type="switchTab"></navigator>
- 后退: <navigator open-type="navigatorBack" delta="1"></navigator>
2、编程式导航
- 普通页面: wx.navigatorTo({url: ''})
- tabbar页面: wx.switchTab({url: ''})
- 后退: wx.navigatorBack({delta: 1})
3、tabbar页面跳转传参
- wx.reLaunch
19.8 生命周期
1、应用的生命周期
- onLaunch: 小程序初始化(加载一次)
- onShow: 每次看见小程序
- onHide: 小程序隐藏
- onError: 小程序出错
2、页面的生命周期
- onLoad: 页面加载(加载一次) 获取到导航参数,数据请求
- onShow: 页面显示,
- onReady: 页面加载完成(加载一次)
- onHide: 页面隐藏
- onUnload: 页面销毁
3、组件的生命周期
生命周期 | 参数 | 描述 | 最低版本 |
created | 无 | 在组件实例刚刚被创建时执行 | |
attached | 无 | 在组件实例进入页面节点树时执行 | |
ready | 无 | 在组件在视图层布局完成后执行 | |
moved | 无 | 在组件实例被移动到节点树另一个位置时执行 | |
detached | 无 | 在组件实例被从页面节点树移除时执行 | |
error | Object Error | 每当组件方法抛出错误时执行 |
20. 小程序如何跳转另外一个小程序?
21. 小程序最近更新了什么?
22. 小程序地图
23. 小程序嵌套过深,导致跳转失效?
1、出现问题的原因:
小程序的页面栈最多10层,之前是5层,所以一旦超过10层,跳转则无反应
2、解决思路
合理使用navigateTo、navigateBack、redirectTo、reLaunch
方式一:可以通过获取页面栈信息getCurrentPages,以及即将跳转的页面是否在页面栈中,如果有直接利用navigatorBack进行返回
方式二:可以通过获取页面栈信息getCurrentPages,是否超出限制,如果超出限制利用redirectTo进行跳转或者wx.reLaunch进行跳转
方式三:因为redirectTo/reLaunch跳转,会销毁当前页面栈进入另一个页面,a、b、c,b通过redirectTo到c,再返回会进入a,这个问题解决,可以维护自己的页面栈列表,进行进栈,弹栈维护,从自己维护的列表中取对应的页面,对应的往后退。
24. 小程序打包文件太大如何处理?
- 删除无用代码、组件
- 图片压缩链接
- 分包处理
25. 小程序如何下载文件?
小程序有内置的下载文件api, wx.downloadFile进行文件下载,单次下载允许的最大文件为 200MB
26. 小程序项目选择uni-app的原因?
- 跨终端(但是你的项目没有多终端,只有小程序,说这个就不合适了)
- 开发风格贴近vue, 开发舒服
- 开发效率比原生效率快
- 微信小程序具备的uni-app均具备
- 微信开发者工具没有vscode和hbuilderx好用
27. 小程序内嵌h5页面?
- 可以通过web-view组件嵌入h5页面
- 可参考