易遗漏事件总结
关闭/保存后
-
重置
- 一些变量、表单
-
考虑业务流程
-
加载数据提示
移动端技巧总结
阿里图库
在原有的基础上加新图标
该代码替换掉原有的 iconfont.css
❗src
请求头要加https,要不然移动端会不显示阿里图标
onBackPress
返回上一级
onBackPress() {
// ...自定义操作---提示(是否确认退出)
if (this.ruleForm.Id) {
uni.navigateTo({
// 跳转到平常页面
url: '/pages/business/B_WayBill/B_WayBill'
})
} else {
// 跳转到 tabbar 页面
uni.switchTab({
url: '/pages/work/work'
})
}
return true
}
实现这种提示:
<!--关闭按钮显示与否-->
<u-modal :closeOnClickOverlay="true" @close="show = false" @cancel="show = false" cancelText="继续编辑"
confirmText="下次再编辑" :show="show" @confirm="close" :showCancelButton="true" title="还差一点就添加成功了">
</u-modal>
// 点击左上角返回按钮触发
onBackPress() {
this.show = true
return true
}
close(){
uni.navigateTo(...)
}
❗close事件不要用 navigateBack
会进入死循环
✨路径传参
uni.navigateTo({
url: `/pages/business/B_WayBill_Add/components/cargoMessage?rowData=${JSON.stringify(this.rowData)}&cargoData=${JSON.stringify(row)}`
});
❗如果传递的参数是对象,需要用 JSON.stringify
转成字符串,后面接受数据再用 JSON.parse
转成 object
条件编辑
-
// #ifdef H5 // #endif // #ifdef APP-PLUS <!-- #ifndef MP-WEIXIN --> ✨除了这种之外 <!-- #ifdef MP-WEIXIN -->
页面下拉刷新事件
async onPullDownRefresh() {
this.getData()
// 停止刷新
uni.stopPullDownRefresh()
}
// 同时要在 pages 里面设置
返回顶部
<!-- 返回顶部的按钮组件 -->
<u-back-top class="u-back-top" :iconStyle="{color:'#fff'}" icon="arrow-up" :scroll-top="scrollTop"></u-back-top>
// 监听返回顶部按钮的距离
onPageScroll(e) {
this.scrollTop = e.scrollTop;
}
页面重置到顶部
uni.pageScrollTo({
scrollTop: 0,
duration: 0
});
搜索定位
uni.pageScrollTo({
scrollTop:dom元素(vue里面的ref).offsetTop,
})
图片预览
uni.previewImage({
current: "",
urls: [e],
})
页面跳转
// 页面会刷新触发onLoad(有表单组件的话需要存起来
uni.navigateTo()
❗url要带'/',eg:'/pages/...'
// 页面不会刷新(有表单组件
uni.navigateBack()
PC端技巧总结
element 多试试插槽,实现个性化样式
<template #title>
<el-tag effect="dark" size="large" style="margin-right: 10px;">主单号</el-tag>
</template>
分割组件 splitpanes
import { Splitpanes, Pane } from 'splitpanes';
import 'splitpanes/dist/splitpanes.css';
<splitpanes style="height: 100%">
<pane :size="40" v-if="!rowData"></pane>
</splitpanes>
vuex
的使用
const state = {
lang:getLang(),
}
const mutations = {
SET_LANG(state, lang){
state.lang = lang
setLang(lang)
}
}
const actions = {
changeLang({commit}, lang){
commit('SET_LANG', lang)
}
}
export default {
namespaced: true,
state,
mutations,
actions,
}
import { mapState } from 'vuex'
import store from '@/store/index.js'
computed: {
...mapState("addOrderCargo", ["sendMessage", "recieveMessage", "productOptions", "inventoryData", "ruleForm"])
}
store.getters.inventoryData
store.commit('addOrderCargo/setproductOptions', res.data)
vue2 引入组件
import yhCascader from '@/components/YhCascader'
components:{}
// 全局 main.js
import yhUpload from '@/components/yh-upload/yh-upload'
watch
"sendMessage.MailingType": {
handler(oldVal, newVal) {
this.getSendAddress()
},
deep: true, // 深度监听
immediate: true // 第一次改变就执行
}
computed
计算后属性必须渲染后,绑定的方法才会生效这里指就是定义后的变量名在上面html中显示
vue3
引入组件
import yhCascader from '@/components/YhCascader'
判断数据类型
const keyType = data => {
let type = Object.prototype.toString.call(data);
if (type === '[object String]') {
type = 'String';
} else if (type === '[object Number]') {
type = 'Number';
} else if (type === '[object Null]') {
type = 'Null';
} else if (type === '[object Boolean]') {
type = 'Boolean';
} else if (type === '[object Array]') {
type = 'Array';
} else if (type === '[object Object]') {
type = 'Object';
} else {
type = '未进行判断的类型:' + type;
}
return type;
};
对象包裹对象转换为数组
for in + push
filter
赋值数据
const data = res.data || []
总–总结
对象
深拷贝
JSON.parse(JOSN.Stringfy())
有key字段,但还需要value字段
- 直接使用
.
加一个名称属性给Object
不同属性类型共享同一个 object
对象赋值
for (let key in ruleForm) {
ruleForm[key] = value[key]
}
callBack
合理使用
封装组件需要注意的点
-
显示与否
-
传递数据另给一个
js
文件存放-
import propsData from './props'
-
// props.js export default { leftColumns: { type: Array, default: () => [] }, }
-
-
个性化–合理利用插槽
<slot name="rightTop"></slot>
-
组件间传递数据
props emits
-
数据更新问题
-
$nextTick
-
定时器
-
setTimeout(()=> { emits('changeAfter') },200)
-
-
-
vue3 在 data 中 使用 compute
-
list:computed(()=>{...})
-
-
使用三段式
-
let activeData = isAll ? getLeftData() : leftTableRef.value.getSelected() :type="isShowLeftList ? 'info' : 'success'"
-
-
巧用
v-model
❗v-if 会影响到 ref 的获取
请求接口参数
❗async
返回值都是 promise
对象
解决:
✨善于利用 uniapp 的 API + Promise
async removeBeforeAsync(id) {
this.show = true
let returnBool = false
await new Promise((resolve, reject) => {
uni.showModal({
title: '删除文件', //提示标题
content: '是否删除该文件', //提示内容
showCancel: true, //是否显示取消按钮
success: async (res) => {
if (res.confirm) { //confirm为ture,代表用户点击确定
let res2 = await this.http.post('/api/B_WayBill_Files/DelWayBillFile?Id=' + id, {}, true)
if (res2.Status) {
this.$toast('删除成功!')
} else {
this.$toast('删除失败!', 'error')
}
returnBool = res2.Status
} else if (res.cancel) { //cancel为ture,代表用户点击取消
returnBool = false
}
resolve()
}
})
})
return returnBool
},
请求接口的是否加载可以加在config
里面
-
用 axios 的请求拦截器接收
-
请求拦截器接收之后可以再响应拦截器中拿到并判断关闭
实现左右滑动
.insure {
display: flex;
height: 520px;
.left {
width: 40%;
// overflow: auto;
.header {
}
}
.right {
flex: 1;
// overflow: auto;
}
}
循环一般用来读取数据,而不要改变响应式数据
根据这个思路,可以把methods或者computed计算完的数据放置于数组中,再在响应式内直接读取数组元素
APP热更新
代码:https://blog.csdn.net/itopit/article/details/124620871
借鉴:https://blog.csdn.net/m_xiaozhilei/article/details/126485684
打包的wgt版本要与后端记录的一样,线下打包的可以搞成第一点版本的去测试
高亮与不高亮基本大小要一样才不会变来边去
请求参数如果没有就不添加:
let params = {}
if (this.keyword2) {
params["billNo"]=this.keyword2
}
if (this.startTime2 && this.endTime2) {
params["beginTime"]=this.startTime2
params["endTime"]=this.endTime2
}
uniapp select被table遮挡
.uni-table-scroll{
overflow-x: unset;
}
this.$set
解决新增的对象属性没有响应式(computed无效)
this.$set(this.rowData,'coupon',newVal * num || 0)// 优惠金额
图片
uniapp展示本地图片使用image>
标签都可以展示图片。但是<img>
标签在网页端和真机模拟都不可以展示图片。
路径直接为 /static/… 不需要相对,不需要@符号。直接从/static目录往下写就行了
数组
新增元素
arr.splice(1,0,xx)
arr.push(xx)
arr.unshfit(xx)
在使用 <script setup>
的单文件组件中,导入的组件可以直接在模板中使用,无需注册
掉起拨打电话接口
<a :href="'tel:' + item.VehiclenoCarManTel">{{item.VehiclenoCarManTel}}</a>
vue2一个对象中的一个值是一个计算属性
怎么搞?—只有计算属性依赖项变化才回触发
devtools–给你的vue3项目的main.js加上这一句
app.config.devtools = true
❗vue
循环一定要弄key
- 要不然顺序变化时会出现错误
js 计算精度问题
自己写公共方法:
/**
** 加
**/
add(arg1, arg2) {
var r1, r2, m, c;
try {
r1 = arg1.toString().split(".")[1].length;
} catch (e) {
r1 = 0;
}
try {
r2 = arg2.toString().split(".")[1].length;
} catch (e) {
r2 = 0;
}
c = Math.abs(r1 - r2);
m = Math.pow(10, Math.max(r1, r2));
if (c > 0) {
var cm = Math.pow(10, c);
if (r1 > r2) {
arg1 = Number(arg1.toString().replace(".", ""));
arg2 = Number(arg2.toString().replace(".", "")) * cm;
} else {
arg1 = Number(arg1.toString().replace(".", "")) * cm;
arg2 = Number(arg2.toString().replace(".", ""));
}
} else {
arg1 = Number(arg1.toString().replace(".", ""));
arg2 = Number(arg2.toString().replace(".", ""));
}
return (arg1 + arg2) / m;
},
/**
** 减
**/
sub(arg1, arg2) {
var r1, r2, m, n;
try {
r1 = arg1.toString().split(".")[1].length;
} catch (e) {
r1 = 0;
}
try {
r2 = arg2.toString().split(".")[1].length;
} catch (e) {
r2 = 0;
}
m = Math.pow(10, Math.max(r1, r2)); //last modify by deeka //动态控制精度长度
n = r1 >= r2 ? r1 : r2;
return Number(((arg1 * m - arg2 * m) / m).toFixed(n));
},
/**
** 乘
**/
mul(arg1, arg2) {
var m = 0,
s1 = arg1.toString(),
s2 = arg2.toString();
try {
m += s1.split(".")[1].length;
} catch (e) {}
try {
m += s2.split(".")[1].length;
} catch (e) {}
return (Number(s1.replace(".", "")) * Number(s2.replace(".", ""))) / Math.pow(10, m);
},
/**
** 除
**/
div(arg1, arg2) {
var t1 = 0,
t2 = 0,
r1,
r2;
try {
t1 = arg1.toString().split(".")[1].length;
} catch (e) {}
try {
t2 = arg2.toString().split(".")[1].length;
} catch (e) {}
r1 = Number(arg1.toString().replace(".", ""));
r2 = Number(arg2.toString().replace(".", ""));
return (r1 / r2) * Math.pow(10, t2 - t1);
},
或者xe-utils 解决 js 加减乘除精度问题
善于使用对象处理(存储)多数据
let obj = {}
obj[key] = xx
❗一定一定要记得复杂数据类型的特殊性,需求如果是不改变原数据一定要深拷贝
// 一般使用 JSON.stringify 进行拷贝---在获取的时候用JSON.parse来解构就行了
在用store存储、作为参数传递过去、赋值等等操作一定要注意
❗❗❗removeEventListener
addEventListener 之后一定要记得 removeEventListener
- 取消对一个全局事件的监听。
插件的结束时期
数据传输 传过去=》再传回来(用 uni.navigateTo)
插件使用
❗❗❗回调函数里面如果需要用到 this 记得该回调函数一定得写成箭头函数
存储
要记得 JSON.stringfy
再存储
uni.setStorageSync(app_user_timestamp, JSON.stringify(Date.now())) //设置时间戳
uniapp FormData
形式的参数得更改请求头
if (isFormData) _header['Content-Type'] = 'application/x-www-form-urlencoded'
// 传递的参数是对象
对象
对象一整个赋值会改不到数据,要用 .
来更改属性值
搜索定位功能
uni.pageScrollTo({
scrollTop: this.$refs[res.Data.BillInfo.BillNo][0].$el.offsetTop-310,
duration: 0
});
let obj = {}
obj[key] = xx
❗一定一定要记得复杂数据类型的特殊性,需求如果是不改变原数据一定要深拷贝
// 一般使用 JSON.stringify 进行拷贝---在获取的时候用JSON.parse来解构就行了
在用store存储、作为参数传递过去、赋值等等操作一定要注意
❗❗❗removeEventListener
addEventListener 之后一定要记得 removeEventListener
- 取消对一个全局事件的监听。
插件的结束时期
数据传输 传过去=》再传回来(用 uni.navigateTo)
插件使用
❗❗❗回调函数里面如果需要用到 this 记得该回调函数一定得写成箭头函数
存储
要记得 JSON.stringfy
再存储
uni.setStorageSync(app_user_timestamp, JSON.stringify(Date.now())) //设置时间戳
uniapp FormData
形式的参数得更改请求头
if (isFormData) _header['Content-Type'] = 'application/x-www-form-urlencoded'
// 传递的参数是对象
对象
对象一整个赋值会改不到数据,要用 .
来更改属性值
搜索定位功能
uni.pageScrollTo({
scrollTop: this.$refs[res.Data.BillInfo.BillNo][0].$el.offsetTop-310,
duration: 0
});
v-for
涉及到增删改查时一定好设置一个唯一的id❗
公共的变量/函数/组件写在hooks.js
里面
使多个地方可用到,复用性极强
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FFC1LY75-1681542182741)(C:\Users\19574\AppData\Roaming\Typora\typora-user-images\1681522169143.png)]
一整个对象赋值改不到原始的对象,而是直接改了对象的数组
-
要是想改掉原来对象的属性值,则需要:
-
for (let key in this.bjFormFields1) { this.bjFormFields1[key] = this.rowData[key] }