项目使用uniapp的cli模式,使用vue3+ts语法,vue依赖版本是3.3.4,vite依赖版本是4.0.3,安装 @uni-helper/uni-app-types 有类型uniapp的ts类型提示
vscode开启Volar Takeover 模式
vue3相关
1、报错:vue Extraneous non-props attributes (redirect) were passed to component but
原因:组件缺乏根节点,参考vue控制台报错Extraneous non-props
2、使用@import url()引入scss文件报错:[vite] [plugin:vite:css] [postcss] postcss-import: /Users/chinaso/work/code/fe-auth-miniprogram/src/pages/assets/AssetDetail.scss:147:14: Unknown word
原因:scss文件中使用了js双斜杠注释 //
3、钉钉浏览器访问报错,unexpected token ?
vite-github [blog.csdn.net/weixin_4323...] 开发环境兼容钉钉浏览器 版本: "@dcloudio/uni-app": "3.0.0-alpha-3090020230909001", "vite": "4.0.3", 经查询可能是控制合并运算符??不兼容旧版本浏览器导致的兼容问题 github上vite的issue 没看懂 dcloud社区也没找到 掘金帖子评论区 也没解决
最后找到了解决办法,改变vite配置
js
import legacy from "@vitejs/plugin-legacy"
plugins: [
process.env.UNI_PLATFORM === "h5"
? legacy({
modernPolyfills: true,
// 为打包后的文件提供传统浏览器兼容性支持
renderLegacyChunks: true,
targets: ["chrome 52"], // 需要兼容的目标列表,可以设置多个
additionalLegacyPolyfills: ["regenerator-runtime/runtime"] // 面向IE11时需要此插件
})
: ""
]
4、定义props默认值
java
interface Props {
modelValue: boolean
}
const props = withDefaults(defineProps<Props>(), {
modelValue: false
})
5、在setup中直接从props中取值会导致失去响应式,可以使用toRef
ini
const modelValue = toRef(props, "modelValue")
或者props.modelValue
6、template中报错Parsing error: missing-whitespace-between-attributes
7、vue控制台报错Extraneous non-props attributes (class) were passed to component but could not be automatica
是因为组件内部template下有多个根结点,然后引入组件后直接在标签上写class类名导致的
8、通过ref调用组件方法必须增加是否为空的判断, InstanceType获得构造函数返回值的类型
vue
import CommonDialog from "@/components/CommonDialog.vue"
const alertRef = ref<InstanceType<typeof CommonDialog> | null>(null)
//1、使用可选链
alertRef.value?.show({
title: "标题",
desc: '描述',
cancelText: "返回",
okText: "确定",
onOk() {}
})
//2、使用非空断言
alertRef.value!.show({
title: "标题",
desc: '描述',
cancelText: "返回",
okText: "确定",
onOk() {}
})
//3、使用短路运算符
alertRef.value && alertRef.value.show({
title: "标题",
desc: '描述',
cancelText: "返回",
okText: "确定",
onOk() {}
})
9、vite使用mock
typescript
// 安装
"mockjs": "^1.1.0",
"vite-plugin-mock": "^2.9.8",
"@types/mockjs": "^1.0.7",
// vite.config.ts
import { viteMockServe } from "vite-plugin-mock"
export default ({ mode, command }: ConfigEnv): UserConfig => {
return {
plugins: [
viteMockServe({
mockPath: "src/mock",
// localEnabled: process.env.NODE_ENV !== "production", // true的时候会请求本地
localEnabled: command === "serve", // 开发时应用, // true的时候会请求mock
logger: true
})
]
}
})
// src/mock/test.ts
import type { MockMethod } from "vite-plugin-mock"
export default [
{
url: "/banner/select1", // 请求/banner/select1即刻获取mock数据
method: "post",
response: ({ body, query }) => {
// console.log("body>>>>>>>>", body)
// console.log("query>>>>>>>>", query)
return {
success: true,
status: -1,
msg: "mock成功",
data: []
}
}
}
] as MockMethod[]
10、使用原子化css,unocss
11、使用unocss报错selector.replaceAll is not a function
node版本必须是15以上才不报错,可以使用node16.19.1
12、defineProps类型声明不支持从外部倒入类型,也不支持联合类型
type argument passed to defineProps() must be a literal type, or a reference to an interface or literal type. 传递给defineProps()的类型参数必须是文字类型,或者是对接口或文字类型的引用。
类型声明方式定义defineProps目前仅支持将props类型定义到组件所在文件中
运行时声明方式定义defineProps体验较好些,但需要配合PropType和ExtractPropTypes使用' 如果不需要将props类型抽取出来,则两种方式都可以。
Vue3解决definedProps无法引入外部Typescript类型定义
- 在 3.2 及以下版本中,
defineProps()
的泛型类型参数只能使用类型字面量或者本地接口的引用。 - 这个限制已经在 3.3 版本中解决。最新版本的 Vue 支持在类型参数的位置引用导入的和有限的复杂类型。然而,由于类型到运行时的转换仍然基于 AST,因此并不支持使用需要实际类型分析的复杂类型,例如条件类型等。你可以在单个 prop 的类型上使用条件类型,但不能对整个 props 对象使用。
13、报错:[Vue warn]: Extraneous non-props attributes (class) were passed to component but could not be automatically inherited because component renders fragment or text root nodes.
外部非props属性(类)传递给组件,但无法自动继承,因为组件呈现片段或文本根节点。 报错原因:子组件没有统一的根结点
tmui相关
1、tm-keyborad success回调会在输入达到maxlength的时候触发,
2、picker 弹窗组件出现位置错乱问题
页面需要套在tmapp下.如果不用弹层类,可以不套这个组件
3、执行 npx @dcloudio/uvm alpha
更新依赖后,tmui使用uniapp规则自动导入失效
解决办法:删除package-lock.json,重新install
4、tmui的样式类都在tmui/scss/noNvue.css文件里面,1万多行
arduino
app.vue里面引入
@import url("./tmui/scss/noNvue.css");
小程序相关
1、微信小程序中怎么获取头像和昵称
2、微信基础库版本兼容
3、webview跳转到小程序页面有哪些方法?
webview微信官方文档 安装"weixin-js-sdk": "^1.6.0"
typescript
import wx from "weixin-js-sdk"
export const goToMpPage = (url: string, params?: object) => {
if (wx && wx.miniProgram) {
wx.miniProgram.navigateTo({
// url: `${url}?redirectURL=${encodeURIComponent(h5Url)}&parmes=${encodeURIComponent(stringParmes)}`
url: params ? `${url}?${qs.stringify(params)}` : url,
success() {
console.log("跳转成功")
},
fail() {
console.log("跳转失败")
}
})
}
}
goToMpPage("pages/index/index")提示invokeMiniProgramAPI:ok但是跳转失败 goToMpPage("/pages/index/index")可以跳转成功
typescript
// H5跳转小程序页面, redirect重定向
export const redirectToMpPage = (url: string, params?: object) => {
if (wx && wx.miniProgram) {
// const stringParmes = JSON.stringify(parmes) // h5活动需回传的参数
wx.miniProgram.redirectTo({
// url: `${url}?redirectURL=${encodeURIComponent(h5Url)}&parmes=${encodeURIComponent(stringParmes)}`
url: params ? `${url}?${qs.stringify(params)}` : url,
success() {
console.log("跳转成功")
},
fail() {
console.log("跳转失败")
}
})
}
}
// webview返回上一页面,返回小程序
export const goToMpBack = () => {
if (wx && wx.miniProgram) {
// const stringParmes = JSON.stringify(parmes) // h5活动需回传的参数
// const h5Url = "https://xxxx.com.cn/wxapp/nev-prod/3d/" // h5活动需回传的h5活动地址
wx.miniProgram.navigateBack()
}
}
4、如果类名直接写到引用的子组件标签上面,margin样式在小程序中样式不生效,怎么解决?
微信小程序如果类名写到引用的子组件上面,在编译生成小程序后会在外层增加一个以"组件名"命名的标签, 例如代码为
ini
父组件
<A-B class="test"></A-B>
子组件
<view class="inner-box">
<view class="inner1"></view>
</view>
编译成小程序后子组件外层会多出一层
ini
<A-B bind:__l="__l" class="test" is="components/test/AB">
<view class="inner-box">
<view class="inner1"></view>
</view>
</A-B>
解决办法在父组件中通过:deep(.inner-box)改变子组件样式
5、小程序内嵌h5怎么修改导航栏标题
在app.vue中使用document.title进行修改
6、微信小程序去除buttom默认样式
css
button{
background: transparent !important;
margin: 0;
padding: 0;
}
去除边框
css
button::after {
border: none;
}
7、小程序手机快速验证组件授权回调中没有code,怎么回事?
2.21.2以下的版本都不支持获取手机号code功能, developers.weixin.qq.com/community/d...
8、微信小程序input输入框锁定焦点placeholder会抖动,怎么解决?
暂时没有好的解决办法,京东和小米小程序都有这个问题,微信开发社区也有人提问,微信开放社区
9、小程序的调试模式vConsole没有network选项卡?
developers.weixin.qq.com/community/d...
10、微信H5分享
H5:如果是普通浏览器,浏览器自带分享按钮;如果是在微信内嵌浏览器中,可调用js-sdk进行分享,参考
11、微信小程序分享
用户分享给朋友onShareAppMessage
小程序:不支持API调用,只能用户主动点击触发分享。可使用自定义按钮方式 或监听系统右上角的分享按钮 onShareAppMessage 进行自定义分享给朋友的内容,只有定义了此事件处理函数,右上角菜单才会显示"转发给朋友"按钮
用户分享到朋友圈,不支持自定义页面路径 onShareTimeline
只有定义了此事件处理函数,右上角菜单才会显示"分享到朋友圈"按钮
12、微信小程序中怎么下载文件,文件保存到手机。
微信小程序 - 下载文件到本地、打开文档(必看1)
微信小程序之保存图片之相册授权问题(必看2)
微信小程序下载图片或视频保存到手机系统相册,判断权限
微信小程序下载文件,保存文档表现(含图)
wx.saveFile这个api官方已经停止维护
wx.downloadFile下载文件资源到本地。客户端直接发起一个 HTTPS GET 请求,返回文件的本地临时路径 (本地路径)。
注意:单次下载允许的最大文件为 200MB
wx.getFileSystemManager().saveFile()微信[文件管理]对象,保存临时文件到本地。
注意:1.FileSystemManager是微信小程序文件管理器,通过 wx.getFileSystemManager
获取,saveFile()
是它提供的一个方法
以上三个api都不能实现真正意义的下载保存,因为微信小程序提供的存储服务是以小程序和用户维度隔离的存储服务,所以下载下来之后用户并不能访问到自己下载的文件。做不到用户下载文件之后可以快捷的找到下载的文件。只是下载到微信app的缓存里面。且微信也不建议开发人员或用户去查询本地文件存储的路径。该结论官方文档也有具体说明微信文件系统文档,本地临时文件只保证在小程序当前生命周期内,一旦小程序被关闭就可能被清理,即下次冷启动不保证可用。 本地缓存文件和本地用户文件的清理时机跟代码包一样,只有在代码包被清理的时会被清理。
13、小程序如何分包
独立分包:独立分包
独立分包中不能依赖主包和其他分包中的内容 目前小程序分包大小有以下限制:
- 整个小程序所有分包大小不超过 20M(开通虚拟支付后的小游戏不超过30M)
- 单个分包/主包大小不能超过 2M
14、小程序中行内样式backgroundImage样式未生效,无法覆盖css文件里写的background-image
解决办法必须写成background-image才可以
ini
:style="item.icon ? 'backgroundImage:url(' + item.icon + ')' : ''"
// 改写成
:style="item.icon ? 'background-image:url(' + item.icon + ')' : ''"
15、关于小程序隐私保护指引设置
在微信公众平台填写"用户隐私保护指引"后,在页面调用相关功能的时候会在页面下方弹出如下弹窗
16、微信开发者工具中怎么调试源码?
App,小程序端源码调试,需要在 vite.config.js 中主动开启sourcemap vite中增加如下配置
yaml
build: {
sourcemap: true
}
17、小程序原生页面和webview页面的区别
原生页面标题显示在中间,webview页面标题显示在左边。
18、手机体验版小程序怎么请求内网后端接口?
打开体验版小程序,点击右上角"三个点",然后在弹窗中点击"开发调试",小程序重启后会出现"vconsole"按钮, 小程序与原生页面打开vconsole如图,没有network;
小程序与webview页面打开vconsole如图,有network
19、小程序怎么冷启动更新版本?
小程序版本更新只需在app.vue中增加如下代码
javascript
onLaunch(() => {
// #ifdef MP-WEIXIN
// 冷启动更新小程序 begin
if (uni.canIUse("getUpdateManager")) {
const updateManager = uni.getUpdateManager()
updateManager.onCheckForUpdate(function (res) {
console.log("onCheckForUpdate:", res)
if (res.hasUpdate) {
updateManager.onUpdateReady(function () {
uni.showModal({
title: "更新提示",
content: "新版本已经准备好,是否重启应用?",
showCancel: false,
success: function (res) {
if (res.confirm) {
updateManager.applyUpdate()
}
}
})
})
updateManager.onUpdateFailed(function () {
uni.showModal({
title: "已经有新版本了哟~",
content: "新版本已经上线啦~,请您删除当前小程序,重新搜索打开哟~"
})
})
}
})
} else {
//如果小程序需要在最新的微信版本体验,如下提示
uni.showModal({
title: "更新提示",
content: "当前微信版本过低,无法使用该功能,请升级到最新微信版本后重试。"
})
}
// #endif
})
提示: 微信开发者工具上可以通过「编译模式」下的「下次编译模拟更新」开关来调试
小程序开发版/体验版没有「版本」概念,所以无法在开发版/体验版上测试更版本更新情况 参考地址
20、微信小程序报错,不支持标签选择器
vue3 出于性能考虑,style 中暂不支持 div、p 等 HTML 标签选择器,推荐使用 class 选择器,template 中的 HTML 标签仍会进行转换。
Some selectors are not allowed in component wxss, including tag name selectors, ID selectors, and attribute selectors 组件wxss中不允许使用某些选择器,包括标签选择器、ID选择器和属性选择器,改为class选择器 参考: uniapp的微信小程序错误警告
不支持通配符*号选择器 参考博客
21、uni自带导航栏字体大小不随着页面宽度变化怎么解决?
使用自定义navbar, 通过navigationStyle:false,隐藏系统自带导航栏
json
{
"path": "pages/test/test",
"name": "test",
"meta": {
"needAuth": true
},
"style": {
"navigationBarTitleText": "测试",
"navigationStyle": "custom", // 隐藏系统导航栏
"enablePullDownRefresh": false
// "navigationBarTextStyle": "white"
}
}
22、微信小程序按需注入和用时注入
修改manifest.json中的配置微信小程序官方文档
json
/* 小程序特有相关 */
"mp-weixin": {
"appid": "wx3197b9669531fd3e",
"setting": {
"urlCheck": false,
"es6": true,
"postcss": true,
"minified": true
},
"usingComponents": true,
"lazyCodeLoading": "requiredComponents"
}
23、v-html在微信小程序中会被编译成rich-text组件
24、新建vue文件,从其他文件复制过来代码后提示找不到模块"@/utils"或其相应的类型声明
typescript版本为4.9.5 点击底部提示 TS 4.9有一个bug,会导致自动导入失败。请降级至TS 4.8或升级至TS 5.0+。 官方issue typescript版本升级为5.0.2
25、发布订阅插件mitt
26、报错:Failed to resolve component: DiyTip,If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement
报错原因:DiyTip组件没有引入
27、微信小程序中无法从文件管理器中上传文件,只能使用web-view
嵌套h5页面来访问文件管理器上传
web-view
是一个 web 浏览器组件,可以用来承载网页的容器,会自动铺满整个页面 h5上传文件使用uni.chooseFile, 微信小程序是上传文件使用uni.chooseMessageFile
28、微信开发者工具提示用户绑定的手机号需要进行验证
手机预览小程序然后点击获取手机号按钮,短信验证后可以在开发者工具获取手机号
28、小程序中页面栈最多十层
wx.navigateTo(Object object),保留当前页面,跳转到应用内的某个页面。但是不能跳到 tabbar 页面。使用 wx.navigateBack 可以返回到原页面。小程序中页面栈最多十层。
29、微信开发者工具评测代码质量
30、webview中H5怎么给小程序发送消息?
typescript
export const postMessageToMP = (parmes) => {
if (wx && wx.miniProgram) {
wx.miniProgram.postMessage({
//这里一定要将数据放在dada中
data: {
message: parmes
}
})
}
}
h5相关
1、当_pages为1显示返回首页图标,当_pages > 1显示返回上一页图标
scss
const _pages = ref(0)
onMounted(() => {
_pages.value = getCurrentPages().length
// #ifdef H5
_pages.value = history.state.back === null ? 1 : window.history.length
// #endif
console.log("getCurrentPages:", toRaw(getCurrentPages()))
})
2、自定义字体可以生效,在小程序中字体ttf不支持上传到微信平台
css
@font-face {
font-family: SourceHanSansCN-Regular;
src: url("SourceHanSansCN-Regular.ttf") format("truetype"); /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
font-style: normal;
font-weight: normal;
}
// 使用
.test {
font-family: SourceHanSansCN-Regular;
}
3、h5非微信浏览器微信支付
前端把支付取消或支付成功地址url以参数的形式传给后端, 后端可以控制微信支付取消或微信支付成功后跳转到指定的url地址并带上订单号等参数,然后在页面判断如果有订单号就弹出支付弹窗包含重新支付和支付完成按钮让用户自己确认
4、判断是否在微信内打开H5
前端把支付取消或支付成功地址url以参数的形式传给后端, 后端可以控制微信支付取消或微信支付成功后跳转到指定的url地址并带上订单号等参数,然后在页面判断如果有订单号就弹出支付弹窗包含重新支付和支付完成按钮让用户自己确认
js
export const isWechat = () => {
const ua = window.navigator.userAgent.toLowerCase()
const temp = ua.match(/micromessenger/i)
if ((Array.isArray(temp) && temp[0]) === "micromessenger") {
// console.log('是微信客户端')
return true
} else {
// console.log('不是微信客户端')
return false
}
}
5、判断h5是否在小程序环境内?
typescript
export const isMiniProgram = (): Promise<boolean> => {
return new Promise((resolve) => {
if (!isWechat()) {
resolve(false)
return
}
if (wx && wx.miniProgram) {
//ios的ua中无miniProgram,但都有MicroMessenger(表示是微信浏览器)
wx.miniProgram.getEnv(function (res) {
console.log("wx.miniProgram:", res)
if (res.miniprogram) {
//小程序环境 ,在此进行相关逻辑处理
resolve(true)
} else {
//非小程序环境下逻辑
console.log("不在小程序中")
resolve(false)
}
})
} else {
resolve(false)
}
})
}
6、使用uni.setClipboardData实现复制功能时,安卓没问题,ios会闪一下
解决方法:安装 "clipboard": "^2.0.11"
创建公共方法
js
import Clipboard from 'clipboard'
export function handleClipboard (text, event, onSuccess, onError) {
event = event || {}
const clipboard = new Clipboard(event.target, {
text: () => text
})
clipboard.on('success', () => {
onSuccess()
clipboard.off('error')
clipboard.off('success')
clipboard.destroy()
})
clipboard.on('error', () => {
onError()
clipboard.off('error')
clipboard.off('success')
clipboard.destroy()
})
clipboard.onClick(event)
}
引用
javascript
import { handleClipboard } from '@/xx/clipboard.js'
copy(text) {
handleClipboard(text, event, () => {
uni.showToast({
title: "复制成功"
})
}, () => {
uni.showToast({
title: "复制失败"
})
})
},
uniapp相关
1、从手机里选择图片功能,怎么限选择图片的数量
javascript
uni.chooseImage({
// count 值在 H5 平台的表现,基于浏览器本身的规范。目前测试的结果来看,只能限制单选/多选,设置为1时单选,大于1时是多选,并不能限制数量;在小程序平台中可以一次选择图片的数量。
count: count, // 默认9
sizeType: ["original", "compressed"], //可以指定是原图还是压缩图,默认二者都有
sourceType: ["album", "camera"], //从相册选择或拍照
success: function (chooseImageRes: UniApp.ChooseImageSuccessCallbackResult) {
resolve(chooseImageRes)
}
})
2、怎么判断api能否使用
shell
###
uni.canIUse(String)
判断应用的 API,回调,参数,组件等是否在当前版本可用。
3、uniapp获取设备类型
typescript
const type = uni.getSystemInfoSync().uniPlatform
console.log(type) // app
4、每次更新pages.json都要重新启动服务
5、报错 Do not nest other components in the text component, as there may be display differences on different platforms.
text组件中不能嵌套其他组件
6、使用axios上传文件,定义content-type为"multipart/form-data"上传失败,怎么解决
不使用axios上传,改为使用uniapp提供的专门的上传方法:uni.uploadFile,在header中不能手动定义content-type参数接口会报错302,使用uni.uploadFile方法会自动增加content-type
7、uniapp从本地选择文件的方法
微信方法
:wx.chooseMessageFile, success回调返回参数有
arduino
// errMsg: "chooseMessageFile:ok"
// tempFiles
h5方法
:uni.chooseFile,success回调返回参数有
arduino
// errMsg: "chooseFile:ok"
// tempFilePaths: (...)
// tempFiles:
tempFiles的属性有
lua
path
type
name
size
8、刷新后setup中通过uni-mini-router的useRoute方法获取不到url参数?
在onload方法中获取
javascript
onLoad(params){
console.log(params)
}
9、uniapp的cli模式,rpx在style的css宽度变量中被转换成了px,在不同设备中样式不一样,怎么变成rem保证不同设备样式统一?
vue
<view class="com" style="--size: props.size"></view>
.com{
--size-rpx: calc(var(--size, 305) * 1rpx);
width: var(--size-rpx);
height: var(--size-rpx);
}
var第二个参数305是默认值
10、uniapp中rpx怎么转变为px?px怎么转变为rpx?
javascript
// rpx转px
rpxToPx(rpx) {
return uni.upx2px(rpx)
}
// px转rpx
pxToRpx(px) {
//计算比例
let scale = uni.upx2px(100)/100;
return px/scale
}
11、怎么预览文本文件
使用uni.openDocument 新开页面打开文档,支持格式:doc, xls, ppt, pdf, docx, xlsx, pptx,不支持H5环境
javascript
uni.downloadFile({
url: 'https://example.com/somefile.pdf',
success: function (res) {
var filePath = res.tempFilePath;
uni.openDocument({
filePath: filePath,
showMenu: true,
success: function (res) {
console.log('打开文档成功');
}
});
}
});
12、播放音频
uni.createInnerAudioContext()
13、播放视频
uniapp自带video标签 H5环境可以使用西瓜视频插件
npm install xgplayer
14、设置页面标题
uni.setNavigationBarTitle(OBJECT),相当于html中的document.title 动态设置当前页面的标题
15、自定义子组件@click在h5环境中起作用,在小程序环境中不起作用,可能是小程序会在组件外增加一层的原因?
vue.runtime.esm.js:1240 [Vue warn]: Component emitted event "click" but it is neither declared in the emits option nor as an "onClick" prop.
解决方法1:把@click改成@tap即可,@tap是源于触摸touch事件,在移动触摸事件就是在同个点触发,触摸、按住(长按)和轻滑(包括上下左右滑)就使用该事件,当执行完绑定的tap事件之后,如果下面如果绑定了其他事件或者是本身就存在点击事件的话,也会默认触发
解决方法2:在子组件元素上面写@click="$emit('click')"
即可
参考地址1 官网说明
1、在 Vue 2.x,如果想要在一个组件的根元素上直接监听一个原生事件,需要使用v-on
的 .native
修饰符
2、Vue 3.x 取消 .native
修饰符,对于子组件中未 被定义为组件触发的所有事件监听器,Vue 现在将把它们作为原生事件监听器添加到子组件的根元素中 (除非在子组件的选项中设置了 inheritAttrs: false
)。
父组件
perl
<my-component @close="handleComponentEvent" @click="handleNativeClickEvent" />
子组件
xml
<template>
<div>
<button v-on:click="emits('click')">click</button>
<button v-on:click="emits('close')">close</button>
</div>
</template>
<script setup lang="ts">
const emits = defineEmits(["click"])
</script>
16、预览图片方法
17、报错[plugin:uni:pre] Unbalanced delimiter found in string
条件表达式少了结尾// #endif
18、通过script引入jweixin-1.2.0.js报错jWeixin未定义怎么解决?
#ifdef H5 括起来相关语句 微信开放社区问题文档