CSS
点击穿透
应用场景:点赞或送礼等出现的弹窗遮罩,无法再次触发点击事件
pointer-events: none;
磨砂模糊
background:
linear-gradient(to bottom, transparent, #fff 400rpx),
linear-gradient(to right, #beecd8 20%, #F4E2D8);
min-height: 80vh;
底部安全距离
可以放入【common.scss】中,在需要的页面引入
.safe-area-inset-bottom{
height: env(safe-area-inset-bottom);
}
<view class="safe-area-inset-bottom"></view>
宽度根据内容决定
width: fit-content;
媒体查询@media
@media mediatype and|not|only (media feature) {
CSS-Code;
}
- 必须是以 @media 开头
- 使用 mediatype 指定媒体(设备)类型
- 使用 and | not | only 逻辑操作符构建复杂的媒体查询
- 使用 media feature 指定媒体特性
☀️mediatype (媒体类型)取值范围如下:
值 | 描述 |
---|---|
all | 适用于所有设备 |
用于打印机和打印预览 | |
screen | 用于电脑屏幕、平板电脑、智能手机等 |
speech | 用于屏幕阅读器等设备发声设备 |
☀️逻辑操作符取值范围如下:
值 | 描述 |
---|---|
and | 用于将多个媒体查询规则组合成单条媒体查询,当每个查询规则都为真时则该条媒体查询为真 |
not | 用来排除某种设备 |
only | 用于指定某种特定媒体设备 |
☀️media feature (媒体特性)常用取值如下::
值 | 描述 |
---|---|
max-width | 定义输出设备中的页面最大可见区域宽度 |
max-height | 定义输出设备中的页面最大可见区域高度 |
mix-width | 定义输出设备中的页面最小可见区域宽度 |
mix-height | 定义输出设备中的页面最小可见区域高度 |
orientation | 视口旋转方向:portrait(纵向,高度大于宽度)、landscape(横向,宽度大于高度) |
网格布局grid
JavaScript
parseInt小数或字符串取整
将字符串转换为整数的函数。将字符串转换为整数,并返回整数部分,忽略任何小数部分或非数字字符
let num = parseInt("10");
console.log(num); // 输出 10
let num2 = parseInt("10.5");
console.log(num2); // 输出 10,小数部分被忽略
let num3 = parseInt("ABC");
console.log(num3); // 输出 NaN,表示无法转换为数字
{ … }解构
-
通过【( … )】这样就可以解构出【if作用域】里面的属性
let name, age; if(true){ ({name, age} = {name: "小明" ,age: 18}) }
-
深度解构
let {works:{music}} = person
request二次封装
封装【uni.request】
-
@/utils/request.js
const BASE_URL = 'https://xxxxx'; export function request(config={}){ let { url, data={}, method="GET", header={} } = config url = BASE_URL+url // header['access-key'] = "xxxxxx" // header['content-type'] = "xxxxxx" return new Promise((resolve,reject)=>{ uni.request({ url, data, method, header, success:res=>{ if(res.data.errCode===0){ resolve(res.data) }else if(res.data.errCode === 400){ uni.showModal({ title:"错误提示", content:res.data.errMsg, showCancel:false }) reject(res.data) }else{ uni.showToast({ title:res.data.errMsg, icon:"none" }) reject(res.data) } }, fail:err=>{ reject(err) } }) }) }
-
@/api/xxx.js
import {request} from "@/utils/request.js" export function apiGetIndexData(){ return request({ url:"/xxx" }) } export function apiGetUserData(){ return request({ url:"/xxx", method:"POST" }) }
replace置换
"xxx.webp".replace( ".webp" , ".jpg")
findindex返回数组下标
const numbers = [10, 20, 30, 40, 50];
// 查找大于25的元素的索引
const index = numbers.findIndex(item => item > 25);
异步同步化的异常处理
-
异常处理
pro().then({ ... }) .catch({}) uni.request({ ..., success:(){ ... }, fail:(){ ... } })
-
当采用【async+await】做异步同步化时,所产生的异常如何处理
// 解决【异常】以及【状态码!=0】的情况 async fun(){ try{ let res = await pro() if(res.errCode != 0) throw res ... }catch{ console.log(res.msg) }finally{ ... } } // 解决【状态码!=0】的情况 async fun(){ let res = await pro() if(res.errCode !=0 ){ console.log(res.msg) return } ... }
去重数组
newArr = [...new Set([value ,...arr])].slice(0,10);
VUE
自动引入插件,使用【@】插件
生命周期
接收页面参数
import {onLoad, ...} from "@dcloudio/uniapp"
-
setup():是在beforeCreate和created之前运行的,所以可以用setup代替这两个钩子函数。
-
onBeforeMount():已经完成了模板的编译,但是组件还未挂载到DOM上的函数。
-
onMounted():组件挂载到DOM完成后执行的函数。
-
onBeforeUpdate():组件更新之前执行的函数。
-
onUpdated():由于数据更改导致的虚拟DOM重新渲染和打补丁,在这之后会调用该函数。
-
onBeforeUnmount():在组件实例被卸载之前调用。
-
onUnmounted():组件卸载完成后执行的函数
-
onActivated():若组件实例是缓存树的一部分,当组件被插入到DOM中时调用。
-
onDeactivated():若组件实例是缓存树的一部分,当组件从 DOM中被移除时调用。
-
onErrorCaptured(): 在捕获了后代组件传递的错误时调用。
监视属性
计算属性
父子传值
-
vue2
-
vue3
<child :str="str" :data="data"></child> let data = ref({...}) let str = ref("")
<script setup> defineProps({ str:{ type: String, default: '' }, data:{ type: Object, default(){ return{ xxx:xxx ... } } } }) <script>
状态管理
- vuex
- pinia
UniApp
跨域
-
后端配置
Access-Control-Allow-Origin: *
后端考虑安全问题,API接口只允许自己公司项目使用,开启运行跨域可能会被蹭接口,导致没必要的消耗或暴露存在的安全漏洞
-
在HBuilder编辑器中使用内置浏览器运行
-
前端配置代理(推荐)
-
Vue3:vite.config.js
import { defineConfig } from 'vite'; import uni from '@dcloudio/vite-plugin-uni'; export default defineConfig({ plugins: [uni()], server: { host: "localhost", // 指定服务器应该监听哪个IP地址,默认:localhost port: 5173, // 指定开发服务器端口,默认:5173 proxy: { // 为开发服务器配置自定义代理规则 // 带选项写法:http://localhost:5173/api/posts -> http://qt.com/posts "/api": { target: "http://qt.com/posts", // 目标接口 changeOrigin: true, // 是否换源 rewrite: (path) => path.replace(/^\/api/, ""), } } } })
uni.request({ url:"/api/posts" //这里的/api相当于设置的target目标地址 }).then(res=>{ console.log(res); })
-
Vue2:vue.config.js
module.exports = { devServer: { disableHostCheck: true, proxy: { "/devapi": { target: "http://qt.com", changeOrigin: true, secure: false, pathRewrite: { "^/devapi": "/" } } } } }
uni.request({ url:"/devapi/posts" //这里的/devapi相当于设置的target目标地址 }).then(res=>{ console.log(res); })
-
状态栏高度
// 获取状态栏高度px
export const getStatusBarHeight = ()=> uni.getSystemInfoSync().statusBarHeight || 15;
// 获取微信小程序胶囊按钮的 height+padding
export const getTitleBarHeight = ()=>{
if(uni.getMenuButtonBoundingClientRect){
let {top,height} = uni.getMenuButtonBoundingClientRect();
return height + (top - getStatusBarHeight())*2
}else{
return 40;
}
}
css变量小程序变量 --status-bar-height
tabbar高度
// vue中直接在 css 中使用
.fixed1{
position: fixed;
left: 0;
bottom: var(--window-bottom);
}
// nvue 不支持css的写法,请使用 js 方法 获取
uni.getSystemInfoSync().windowBottom
富文本editor
-
内置组件editor
-
富文本组件在自带的删除按钮删除图片的是时候会触发什么事件吗?点击发表的时候再选择上传图片到服务器,而不是从本地选择的时候就上传。在编辑内容的时候,把图片删了,我该怎么获取这张图片的信息(名称之类的),该怎么维护一个图片的数组等到后面上传的时候再把数组中的图片上传上去
-
在输入标题然后换行的时候,第二行还是显示标题按钮还是显示高亮,但是输出的内容就是普通的内容非标题,通过uniapp的editor组件的相关api检测到样式发生改变时触发,然后将标题的高亮状态改正。但是有个小问题:他在换行之后还是显示高亮状态,需要输入文字之后触发api才能调用相关方法来做判断从而改变标题等按钮的高亮
-
<editor
id=“myEditor”
ref=“mineEditor”
placeholder=“请输入内容”
show-img-size
show-img-toolbar
show-img-resize
@ready=“onEditorReady”
@focus=“onFocus”
@blur=“onBlur”
// 富文本容器初始化
onEditorReady(){
uni.createSelectorQuery().select(‘#myEditor’).fields({
size:true,
context:true
},res=>{
this.editorCtx = res.context
}).exec()
},
// 添加分割线
addLine(){
this.editorCtx.insertDivider()
}
- 使用第三方插件
#### uni.showLoding必须和uni.hideLoding配套使用
在已经配套使用的情况下,仍然报这个警告,中间掺杂了uni.showTost
分析:他们的本质可能是一样的,只是展示的样式不一样,所以中间掺杂的uni.showTost在自动关闭的时候会把uni.showLoding也关闭了
## 微信小程序
#### 自动鉴黄
上线微信小程序,涉及到展示图片、发表评论等。需要修改小程序类型还有鉴定内容工作,微信小程序开发文档提供了相关的鉴定接口。
鉴定接口存在v1和v2版本,v2版本更加严格。
#### 跳转其他小程序
#### 保存图片到相册
在微信公众平台:
- 配置download域名白名单:微信公众平台--开发--开发管理--服务器域名
- 配置相册权限:微信公众平台--设置--服务内容声明--用户隐私保护协议--更新(点击最右侧的更新)--【xxx小程序隐私保护指引】--【本程序处理了用户信息】--填写相关信息(http://www.blog.csdn.net/qq_18798149/article/details/135871140)
- 关键代码
```js
// 通过图片网络地址获取图片临时地址,配置download域名白名单
uni.getImageInfo(OBJECT)
// 小程序支持,H5不支持
// 通过临时地址保存图片打本地,配置相册权限
uni.saveImageToPhotosAlbum(OBJECT)
-
详细代码
// 通过图片网络地址获取图片临时地址 uni.getImageInfo({ src: imgUrl, success: (res) => { // 通过临时地址保存图片打本地,第一次系统会自动弹出权限设置框,后续不会 uni.saveImageToPhotosAlbum({ filePath: res.path, success: (res) => { uni.showToast({ title: "保存成功,请到相册查看", icon: "none" }) }, fail: err => { // 有权限的情况下,提示失败 if (err.errMsg == 'saveImageToPhotosAlbum:fail cancel') { uni.showToast({ title: '保存失败,请重新点击下载', icon: "none" }) return; } // 没有权限的情况下,提示需要授权,并打开授权设置 this.authrization() }, complete: () => { uni.hideLoading(); } }) } }) // 没有权限的情况下,提示需要授权,并打开授权设置 authorization (){ uni.showModal({ title: "授权提示", content: "需要授权保存相册", success: res => { if (res.confirm) { // 打开授权设置(根据微信公众平台配置的权限,平台配置多少,小程序就有多少选择) uni.openSetting({ success: (r) => { if (r.authSetting[ 'scope.writePhotosAlbum' ]) { uni.showToast({ title: "获取授权成功", icon: "none" }) } else { uni.showToast({ title: "获取权限失败", icon: "none" }) } } }) } } }) }
-
调试时可以在微信开发者工具上清除已授权的信息
权限授权设置
- 其他权限设置同上:微信公众平台–设置–服务内容声明–用户隐私保护协议–更新(点击最右侧的更新)–【xxx小程序隐私保护指引】–【本程序处理了用户信息】–填写相关信息(http://www.blog.csdn.net/qq_18798149/article/details/135871140)
其他
插件
原生开发存在问题:开发效率、代码bug、兼容性
-
z-paging:上拉加载,下拉刷新
-
使用自定义加载动画的话,配合http://icons8.com,里面有丰富的加载动画
-
在网速慢的情况下,先加载uniapp框架(有提示)——空白——页面信息,【空白期】会影响用户体验,可通过【z-paging】插件的具名插槽(http://z-paging.zxlee.cn/api/slot/main.html#主体布局slot),配置相应的提示信息,优化用户体验
-