1. 什么是flex布局
Flex
是 Flexible Box
的缩写,意为弹性布局
,用来为盒状模型提供最大的灵活性。可以随着页面大小的改变自适应页面布局。 目前被所有浏览器所支持。
2. 如何设置flex布局
块级元素:
.box{
display:flex;
}
行内元素也可以设置成flex布局:
.box{
display:inline-flex;
}
设为Flex
布局以后,子元素的float
、clear
和vertical-align
属性将失效。
3. em、rem、meta标签的基本概念
em
是一个布局的长度单位,当前对象内文本的字体大小的相对单位,也就是说相对于当前元素的font-size
。 rem
是(根)字体大小相对单位,也就是说跟当前元素的font-size
没有关系,而是跟整个body
的font-size
有关系。
物理像素是硬件的一个实际像素;而逻辑像素是我们在网页设计中使用的像素。它跟物理像素的关系是有一个设备像素比的关系,比如说设备像素比是2,那么就说明一个逻辑像素对应着4个物理像素,它们是一个平方的关系。
meta
标签,我们可以指定浏览器的适口,适口就是可以看见的区域。
4. rem 和 em 的区别
4.1 rem的特点:
rem是CSS3中新增的一个相对单位,但相对的只是HTML根元素。它的使用非常简单,通过改变根元素的大小就可以改变它的值
4.2 em的特点:
字体大小是根据父元素字体大小设置的。
5. rem实现适配的原理
rem
方案的原理其实就是,将每一个不同的屏幕划分成相同的份数,让同一个元素在不同的屏幕上占据相同比例的空间。1rem
等于此页面html
的font-size
,rem
可以理解为每份是多少px
,比如说,我们的设计稿宽度为750px
,我们规定将页面划分成10
份,那么rem=75px
,如果有一个div
宽度为75px
,就刚好为1rem
。即,将750px
宽的屏幕划分为10
份,这个div
宽度占一份。那么只需要让此div
在不同宽度的屏幕下宽度都占一份,就行了。那么我们只需要做一件事,就是确定不同的屏幕下一份有多宽,即不同设备下1rem
等于多少px
?这很容易计算,document.body.clientWidth / 10
就能算出来。
6. 如何动态计算rem
核心代码块:
// 动态为根元素设置字体大小
function init () {
// 获取屏幕宽度
var width = document.documentElement.clientWidth
// 设置根元素字体大小。此时为宽的10等分
document.documentElement.style.fontSize = width / 10 + 'px'
}
// 首次加载应用,设置一次
init()
// 监听手机旋转的事件的时机,重新设置
window.addEventListener('orientationchange', init)
// 监听手机窗口变化,重新设置
window.addEventListener('resize', init)
7. rem布局的优点
7.1 优点:
在屏幕分辨率千差万别的时代,只要将 rem
与屏幕分辨率关联起来就可以实现页面的整体
缩放,使得在设备上的展现都统一起来了。
而且现在浏览器基本都已经支持rem
了,兼容性也非常的好。
7.2. rem 布局的缺点
(1)在奇葩的 dpr
设备上表现效果不太好,比如一些华为的高端机型用 rem 布局会出现错
乱。
(2)使用iframe
引用也会出现问题。
(3)rem
在多屏幕尺寸适配上与当前两大平台的设计哲学不一致。即大屏的出现到底是为
了看得又大又清楚,还是为了看的更多的问
8. 什么是媒体查询
媒体指的就是各种设备 (移动设备, PC设备)
查询指的是要检测属于哪种设备
媒体查询: 通过查询当前属于哪种设备, 让网页能够在不同的设备下正常的预览
9. 媒体查询分哪几个?具体宽度是多少?
/* 超小屏幕(手机,小于 768px) */
/* 没有任何媒体查询相关的代码,因为这在 Bootstrap 中是默认的(还记得 Bootstrap 是移动设备优先的吗?) */
/* 小屏幕(平板,大于等于 768px) */
@media (min-width: @screen-sm-min) { ... }
/* 中等屏幕(桌面显示器,大于等于 992px) */
@media (min-width: @screen-md-min) { ... }
/* 大屏幕(大桌面显示器,大于等于 1200px) */
@media (min-width: @screen-lg-min) { ... }
9. 说一下你所了解的移动端Web页面适配方案有哪些
- 百分比方案
- rem
- vh/vw
- rem+vw/vh
- 基于媒体查询的响应式设计
10. 有用过vw/vh吗,简单描述下吧
vw和vh他们是一个相对单位(类似em和rem)
vw
是:viewport width
视口宽度单位vh
是: viewport height
视口高度单位
相对视口的尺寸计算
1vw=1/100视口宽度
1vh=1/100视口高度
eg
:当前屏幕视口是375
像素,1vw
就是3.75
像素
10.1 vw和百分比的区别是什么?
百分比是相对父元素来说的vw
和vh
是相对于当前视口来说的
10.2 有在项目中使用过vw吗?
以vue_cli
举例:
在开发中使用Webpack编译打包,通过postcss-px-to-viewport插件。配置好这个插件,在写CSS的时候可以严格按照设计稿上的像素值去写,这个插件负责将你写的 px 转换为 vw 。
10.2.1 PostCss配置文件
在postcss.config.js添加如下配置
module.exports = {
plugins: {
// ...
'postcss-px-to-viewport': {
// options
}
}
}
10.2.2 配置参数
默认参数:
{
unitToConvert: 'px',
viewportWidth: 320,
unitPrecision: 5,
propList: ['*'],
viewportUnit: 'vw',
fontViewportUnit: 'vw',
selectorBlackList: [],
minPixelValue: 1,
mediaQuery: false,
replace: true,
exclude: undefined,
include: undefined,
landscape: false,
landscapeUnit: 'vw',
landscapeWidth: 568
}
unitToConvert
(String) 需要转换的单位,默认为”px”viewportWidth
(Number) 设计稿的视口宽度unitPrecision
(Number) 单位转换后保留的精度propList
(Array) 能转化为vw的属性列表
- 传入特定的CSS属性;
- 可以传入通配符”*”去匹配所有属性,例如:[‘*’];
- 在属性的前或后添加”*”,可以匹配特定的属性. (例如[‘position‘] 会匹配 background-position-y)
- 在特定属性前加 “!”,将不转换该属性的单位 . 例如: [‘*’, ‘!letter-spacing’],将不转换letter-spacing
- “!” 和 “*”可以组合使用, 例如: [‘‘, ‘!font‘],将不转换font-size以及font-weight等属性
viewportUnit
(String) 希望使用的视口单位fontViewportUnit
(String) 字体使用的视口单位selectorBlackList
(Array) 需要忽略的CSS选择器,不会转为视口单位,使用原有的px等单位。
- 如果传入的值为字符串的话,只要选择器中含有传入值就会被匹配
- 例如
selectorBlackList
为['body']
的话, 那么.body-class
就会被忽略
- 如果传入的值为正则表达式的话,那么就会依据CSS选择器是否匹配该正则
- 例如
selectorBlackList
为[/^body$/]
, 那么body
会被忽略,而.body
不会
minPixelValue
(Number) 设置最小的转换数值,如果为1的话,只有大于1的值会被转换mediaQuery
(Boolean) 媒体查询里的单位是否需要转换单位replace
(Boolean) 是否直接更换属性值,而不添加备用属性exclude
(Array or Regexp) 忽略某些文件夹下的文件或特定文件,例如 ‘node_modules’ 下的文件
- 如果值是一个正则表达式,那么匹配这个正则的文件会被忽略
- 如果传入的值是一个数组,那么数组里的值必须为正则
include
(Array or Regexp) 如果设置了include
,那将只有匹配到的文件才会被转换,例如只转换 ‘src/mobile’ 下的文件
(include: /\/src\/mobile\//
)
- 如果值是一个正则表达式,将包含匹配的文件,否则将排除该文件
- 如果传入的值是一个数组,那么数组里的值必须为正则
landscape
(Boolean) 是否添加根据landscapeWidth
生成的媒体查询条件@media (orientation: landscape)
landscapeUnit
(String) 横屏时使用的单位landscapeWidth
(Number) 横屏时使用的视口宽度
exclude
和include
是可以一起设置的,将取两者规则的交集。
微信小程序
- 1、小程序的原生组件有哪些?
- 2、小程序的安卓版和ios版是怎么开发出来?
- 3、小程序生命周期
- 4、小程序路由跳转
- 4、小程序的兼容问题有哪些?
- 5、小程序框架都掌握哪一些?uniapp都会哪一些?平时开发遇到的困难?
- 6、小程序怎么获取手机号?
- 7、小程序的登录流程
- 7.1 首次登录
- 7.2 第二次及以后
- 8、小程序如果版本更新了怎么通知用户?
- 9、小程序嵌入H5页面怎么做?
- 10、小程序的生命周期函数有哪些?分别有什么作用?
- 10.1 小程序应用的生命周期
- 10.2 小程序页面的生命周期
- 10.3 小程序组件的生命周期
1、小程序的原生组件有哪些?
以微信小程序为例,可以分成容器组件、基础组件、表单组件、媒体组件、开放能力组件等。
2、小程序的安卓版和ios版是怎么开发出来?
小程序开发基于html、css、javascript
,与web
开发一样具有跨平台特性,一次开发即可在安卓和iOS等平台访问。但与普通web开发不同,小程序运行环境并不是浏览器,而是依附于各自的软件App。如微信小程序必须在微信中访问,支付宝小程序必须在支付宝中访问等,小程序的开发流程也有所不同,需要经过申请小程序帐号、安装小程序开发者工具、配置项目、开发、调试、上线发布等过程方可完成。
3、小程序生命周期
onReady
生命周期函数–监听页面初次渲染完成
onShow
生命周期函数–监听页面显示
onHide
生命周期函数–监听页面隐藏
onUnload
生命周期函数–监听页面卸载
onPullDownRefresh
页面相关事件处理函数–监听用户下拉动作
onReachBottom
页面上拉触底事件的处理函数
onShareAppMessage
用户点击右上角转发
onPageScroll
页面滚动触发事件的处理函数
onTabItemTap
当前是 tab 页时,点击 tab 时触发
4、小程序路由跳转
(1)通过组件navigator
跳转,设置url
属性指定跳转的路径,设置open-type
属性指定跳转的类型(可选),open-type
的属性有 redirect
, switchTab
, navigateBack
等
(2)通过api跳转,wx.navigateTo()
,wx.navigateBack()
,wx.redirectTo()
, wx.switchTab()
,wx.reLanch()
4、小程序的兼容问题有哪些?
遇到的如下:
1,ios
下的zIndex
层级问题,主要发生在iphone7
和iphoneX
下 绝对定位必须有一个共同的父元素。
2,左右边框不生效 当边框的宽度设置为奇数的时候,可能会不生效 解决方法:将宽度设置为偶数的时候,在ios
下就可以解决
3,还有尽量不要用margin-bottom
,当元素是在整个页面的最底部的时候,在ios下可能margin-bottom
会失效,所以建议,都使用padding-bottom
new Date
跨平台兼容性问题
在Andriod
使用new Date(“2018-05-30 00:00:00”)
木有问题,但是在ios
下面识别不出来。
因为IOS下面不能识别这种格式,需要用2018/05/30 00:00:00
格式。可以使用正则表达式对做字符串替换,将短横替换为斜杠。var iosDate= date.replace(/-/g, '/');
。
5、小程序框架都掌握哪一些?uniapp都会哪一些?平时开发遇到的困难?
Taro
uni-app
WeUI
mpvue
iView Weapp
开发uni-app
遇到的坑
uni-app h5
端的ios图片不能加载问题
uni-app h5
端 ios只能加载https的图片
需要在methods同级下加一个 :
uni-app post请求如何传递数组 参数
在开发中我们接口上传图片是post请求 无法传递一个数组 解决方法如下
我们可以把数据转换成字符串 然后拼接到请求地址后后面
拼接字符串格式:image[]=arr[0]&image[]=arr[1]
imgURlClick(imgArr){
return '?images[]='+imgArr.join('&images[]=')
}
6、小程序怎么获取手机号?
准备一个button
组件, 将 button
组件 open-type
的值设置为 getPhoneNumber
,当用户点击并同意之后,可以通过 bindgetphonenumber
事件回调获取到动态令牌code
;
<button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber"></button>
Page({
getPhoneNumber (e) {
console.log(e.detail.code)
}
})
接着把code
传到开发者后台,并在开发者后台调用微信后台提供的
getPhoneNumber
接口,消费code
来换取用户手机号。每个code
有效期为5分钟,且只能消费一次。
getPhoneNumber: function (e) {
var that = this;
console.log(e.detail.errMsg == "getPhoneNumber:ok");
if (e.detail.errMsg == "getPhoneNumber:ok") {
wx.request({
url: 'http://localhost/index/users/decodePhone',
data: {
encryptedData: e.detail.encryptedData,
iv: e.detail.iv,
sessionKey: that.data.session_key,
uid: "",
},
method: "post",
success: function (res) {
console.log(res);
}
})
}
}
注:getPhoneNumber
返回的 code
与 wx.login
返回的 code
作用是不一样的,不能混用.
注:从基础库 2.21.2 开始,对获取手机号的接口进行了安全升级, 需要用户主动触发才能发起获取手机号接口,所以该功能不由 API 来调用,需用 button 组件的点击来触发。另外,新版本接口不再需要提前调用wx.login进行登录。
7、小程序的登录流程
7.1 首次登录
调用小程序api
接口 wx.login()
获取 临时登录凭证code
,这个code
是有过期时间的.
将这个code
回传到开发者服务器(就是请求开发者服务器的登录接口,通过凭证进而换取用户登录态信息,包括用户的唯一标识(openid
)及本次登录的会话密钥(session_key
)等)
拿到开发者服务器传回来的会话密钥(session_key
)之后,前端需要保存起来.wx.setStorageSync('sessionKey', 'value')
7.2 第二次及以后
再次登录的时候,就要判断存储的session_key
是否过期了
获取缓存中的session_key,wx.getStorageSync('sessionKey')
如果缓存中存在session_key
,那么调用小程序api
接口wx.checkSession()
来判断登录态是否过期,回调成功说明当前 session_key
未过期,回调失败说明 session_key
已过期。登录态过期后前端需要再调用 wx.login()
获取新的用户的code,然后再向开发者服务器发起登录请求.
一般在项目开发,开发者服务器也会对用户的登录态做过期限制,所以这时在判断完微信服务器中登录态如果没有过期之后还要判断开发者服务器的登录态是否过期。(请求开发者服务器给定的接口进行请求判断就好)
参考官网: 小程序登陆流程 登陆态过期检测
8、小程序如果版本更新了怎么通知用户?
当小程序发布新的版本后,用户如果之前访问过该小程序,通过已打开的小程序进入(未手动删除),则会弹出提示,提醒用户更新新的版本。用户点击确定就可以自动重启更新,点击取消则关闭弹窗,不再更新.
核心步骤:
打开小程序, 检查小程序是否有新版本发布updateManager.onCheckForUpdate(function (res) {})
小程序有新版本,则静默下载新版本,做好更新准备
updateManager.onUpdateReady(function () {})
新的版本已经下载好,调用 applyUpdate
应用新版本并重启小程序
updateManager.applyUpdate()
更新版本的模拟测试
微信开发者工具上可以通过「编译模式」下的「下次编译模拟更新」开关来调试.
点击编译模式设置下拉列表,然后点击“添加编译模式”,在自定义编译条件弹窗界面,点击下次编译时模拟更新,然后点击确定,重新编译就可以了.
注: 需要注意的是,这种方式模拟更新一次之后就失效了,后边再测试仍需要对这种编译模式进行重新设置才可以.
核心代码如下:
App({
onLaunch: function(options) {
this.autoUpdate()
},
autoUpdate:function(){
var self=this
// 获取小程序更新机制兼容
if (wx.canIUse('getUpdateManager')) {
const updateManager = wx.getUpdateManager()
//1. 检查小程序是否有新版本发布
updateManager.onCheckForUpdate(function (res) {
// 请求完新版本信息的回调
if (res.hasUpdate) {
//2. 小程序有新版本,则静默下载新版本,做好更新准备
updateManager.onUpdateReady(function () {
wx.showModal({
title: '更新提示',
content: '新版本已经准备好,是否重启应用?',
success: function (res) {
if (res.confirm) {
//3. 新的版本已经下载好,调用 applyUpdate 应用新版本并重启
updateManager.applyUpdate()
} else if (res.cancel) {
//不应用
}
}
})
})
updateManager.onUpdateFailed(function () {
// 新的版本下载失败
wx.showModal({
title: '已经有新版本了哟~',
content: '新版本已经上线啦~,请您删除当前小程序,重新搜索打开哟~',
})
})
}
})
} else {
// 如果希望用户在最新版本的客户端上体验您的小程序,可以这样子提示
wx.showModal({
title: '提示',
content: '当前微信版本过低,无法使用该功能,请升级到最新微信版本后重试。'
})
}
}
})
9、小程序嵌入H5页面怎么做?
解决方式 :web-view
webview
指向网页的链接。可打开关联的公众号的文章,其它网页需登录小程序管理后台配置业务域名。
具体实现步骤:
登陆小程序管理后台, 配置服务器域名( h5页面所在的域名 )
在小程序里面嵌入h5
在小程序里面定义一个你想要的H5入口
<navigator url="/page/navigate/navigate" hover-class="navigator-hover">跳转到新页面</navigator>
新建一个页面,放置 webview
, src
指向h5
网页的链接.
<web-view src="{{url}}" bindmessage="getMessage"></web-view> </block>
注: 实际开发中在h5页面中有可能需要向小程序发送消息, 实现h5页面和小程序页面的通信
需要使用postMessage
向小程序发送消息, 在h5中postMessage
注意,key必须叫做data
,否则取不到。
10、小程序的生命周期函数有哪些?分别有什么作用?
小程序的生命周期函数大体分为三类:
10.1 小程序应用的生命周期
属性 说明
onLaunch 监听小程序初始化, 全局只触发一次
onShow 监听小程序启动或切前台。
onHide 监听小程序切后台。
参考官网: 应用的生命周期
10.2 小程序页面的生命周期
属性 说明
onLoad 监听页面加载, 获取其他页面传过来的参数, 发起网络请求
onShow 监听页面显示
onReady 监听页面初次渲染完成
onHide 监听页面隐藏
onUnload 监听页面卸载
参考官网: 页面的生命周期
10.3 小程序组件的生命周期
定义段 描述
created 在组件实例刚刚被创建时执行,注意此时不能调用 setData )
attached 在组件实例进入页面节点树时执行)
ready 在组件布局完成后执行)
moved 在组件实例被移动到节点树另一个位置时执行)
detached 在组件实例被从页面节点树移除时执行)