Vue技法
聚焦和选中
<input
class="scan-field"
placeholder="请扫描SN"
ref="sn"
v-model="sn"
type="text"
@keyup.enter="getAsn"
/>
this.$refs.sn.focus(); // 聚焦到 sn 输入框
this.$refs.sn.select(); // 选中 sn 输入框内的文本
错误消息提示
this.$vux.toast.text(`请输入大于0且小于等于${totalQty}的数字`);
this.$vux.toast.show({
type: "text",
width: "60%", // 增大宽度
text: (res.Message || "查询条码信息失败")
.replace(/"/g, '') // 删除双引号
.replace(/(.{20})/g, "$1\n"), // 每20字符强制换行
time: 1500, // 延长显示时间
styles: {
'word-break': 'break-all',
'white-space': 'pre-line', // 保留换行符
'text-align': 'left',
'max-height': '40vh',
'overflow-y': 'auto'
}
});
this.$vux.toast.show({
type: "text",
width: "80%",
text: "条码不能为空",
time: "1500",
});
this.$vux.toast.show({
type: "text",
width: "60%",
text: `请输入大于0且小于${totalQty}的数字`,
time: "1500",
});
let that = this;
this.$vux.alert.show({
title: "首次扫码提示",
content: firstScanRes.Message,
onHide() {
that.$refs.packageNo.select();
},
time: "1500",
});
用箭头函数() => {}替代let that = this;
clearData() {
this.$vux.confirm.show({
title: "提示",
content: "是否确认清空记录?",
onConfirm: () => {
this.middlearray = [];
this.snCode = "";
this.movecount = "";
this.$tips.successAudio.play();
this.$refs.tocompanyCode.focus();
}
});
},
双行性提示
this.$vux.toast.show({
type: "text",
width: "80%",
text: `首次扫码提示<br/>firstScanRes.Message`,
time: "1500",
onHide() {
_this.$refs.packageNo.select();
},
});
this.$vux.toast.show({
type: "text",
width: "80%",
text: `🎉 已满托 (${this.middlearray.length}/${this.firstScanResult.PackageQty})<br/>请点击确定提交`,
time: "3000",
});
确认性提示
// 检查是否为一步收货且是暂存库位
if (this.dataItem.IsRecInStorage && isTemporary) {
return new Promise((resolve) => {
this.$vux.confirm.show({
title: '是否收货至暂存库位提示',
content: '当前收货库位为暂存库位,是否继续收货?',
onConfirm: () => {
resolve(true);
},
onCancel: () => {
this.location = ''; // 清空库位
this.$refs.loc.select(); // 聚焦库位输入框
resolve(false);
}
});
});
}
return true;
加载
this.$vux.loading.show({
text: "Loading"
});
this.$vux.loading.hide();
这两个代码片段都是使用 vux组件库中的 loading组件,但功能不同:
this.$vux.loading.show({ text: "Loading" });- 作用:显示一个加载中的提示框
- 效果:会在页面上显示一个带有"Loading"文字和旋转动画的加载提示
- 通常用于发起异步请求时,提示用户等待
this.$vux.loading.hide();- 作用:隐藏当前显示的加载提示框
- 效果:会关闭之前通过
show()方法显示的加载提示 - 通常用于异步请求完成时,表示加载结束
典型的使用场景是:
this.$vux.loading.show({ text: "Loading" }); // 显示加载中
axios.get('/api/data').then(response => {
// 处理数据...
}).finally(() => {
this.$vux.loading.hide(); // 无论成功失败都隐藏加载提示
});
如果不调用 hide()方法,加载提示会一直显示,造成用户困惑。
示例
this.$vux.loading.show({
text: "Loading"
}); // 显示加载中
this.$axiosApi.deleteSnCacheList(this.dataItem.TaskId)
.then(res => {
this.$vux.loading.hide(); // 无论成功失败都隐藏加载提示
if (res.Success) {this.$refs.input.select();
} else {
this.$vux.toast.show({
text: res.Message,
width: "15em",
type: "text",
time: 5000
});
that.$refs.input.select();
}
});
强制换行
word-break: break-all;
word-break: break-all; 是 CSS文本换行属性,作用:强制让文字 / 单词在任意位置断开换行,不考虑单词完整性,填满整行。
通俗理解:正常英文会整个单词一起换行,不会把单词切开;加了 break-all 后:不管是不是完整单词,到行尾直接切断,立刻换行,不留空白。
对比:
/* 正常(默认)*/
word-break: normal;
/* 强制任意位置断开 */
word-break: break-all;


文本换行 & 溢出截断
先分清核心 3 个易混淆属性
word-break:控制单词 / 字符 要不要强行断开overflow-wrap(原word-wrap):超长无空格单词 是否换行white-space:控制空格、换行、是否强制不折行
1. word-break 核心极简区分
/* 任意字符强制切断,防溢出(表格/长串编码用) */
.break-all {
word-break: break-all;
}
/* 中日韩文不拆词,精致排版用 */
.keep-all {
word-break: keep-all;
}
2. 推荐折中方案(美观防溢出)
.wrap-safe {
overflow-wrap: break-word;
}
3. 单行省略号(高频)
.ellipsis-1 {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
4. 多行省略号(2行)
.ellipsis-2 {
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
简易测试样例
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>文本换行终极对比(完美清晰版)</title>
<style>
.demo {
width: 160px;
border: 2px solid red;
padding: 10px;
margin: 12px 0;
background: #f8f8f8;
}
/* 1. 默认:一定会溢出 */
.normal {
white-space: nowrap; /* 强制不换行 → 必溢出 */
}
/* 2. 强制任意切断单词 */
.break-all {
word-break: break-all;
}
/* 3. 整词优先,不切单词 */
.break-word {
overflow-wrap: break-word;
}
/* 4. 单行省略号 */
.ellipsis {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
/* 5. 两行省略 */
.line-clamp {
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
</style>
</head>
<body>
<h3>1. 默认(一定会溢出盒子)</h3>
<div class="demo normal">
I love programming very much every single day day day
</div>
<h3>2. word-break: break-all(强制切断单词)</h3>
<div class="demo break-all">
I love programming very much every single day day day
</div>
<h3>3. overflow-wrap: break-word(完整保留单词)</h3>
<div class="demo break-word">
I love programming very much every single day day day
</div>
<h3>4. 单行省略号...</h3>
<div class="demo ellipsis">
I love programming very much every single day day day
</div>
<h3>5. 两行省略...</h3>
<div class="demo line-clamp">
I love programming very much every single day day day
</div>
</body>
</html>

音频提示
音频文件写在js下,新增文件 audioTips.js:src -> assets -> js -> audioTips.js
src
├─assets
│ ├─js
│ │ ├─audioTips.js【音频文件】
├─components
├─router
├─static
├─views
└─vuex
audioTips.js 文件如下
let audioTips = {};
let errorAudio = document.createElement("AUDIO"); //生成一个audio元素
errorAudio.controls = false; // 隐藏音频控件(不显示播放/暂停按钮等)
errorAudio.src = require('@/assets/others/errortips1.wav'); // 绑定音频文件路径
audioTips.errorAudio = errorAudio; // 将错误提示音存入对象
let successAudio = document.createElement("AUDIO"); //生成一个audio元素
successAudio.controls = false; //隐藏音频控件(不显示播放/暂停按钮等)
successAudio.src = require('@/assets/others/successtips.mp3'); //绑定音频文件路径
audioTips.successAudio = successAudio; // 将成功提示音存入对象
export default audioTips;
main.js 文件中导入 audioTips.js
import Vue from 'vue'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import App from './App'
import router from './router'
import axios from 'axios'
import VueAxios from 'vue-axios'
import Vuex from 'vuex'
import './assets/plugins/hybrid-api.js'
import './assets/plugins/vux-plugins.js'
import './assets/plugins/sie-components.js'
import './assets/plugins/tool.js'
import Vant from 'vant';
import 'vant/lib/index.css';
Vue.use(Vant);
Vue.use(ElementUI);
import audioTips from "@/assets/js/audioTips.js"
Vue.prototype.$tips = audioTips;
import SvgIcon from '@/components/SvgIcon.vue';
Vue.component('SvgIcon', SvgIcon);
// import '@/assets/js/vconsole.min.js'
import axiosConfig from './assets/js/axios-config.js'
import store from './vuex'
import login from '@/assets/js/devLogin.js'
import Viewer from 'v-viewer'
import 'viewerjs/dist/viewer.css'
Vue.use(Viewer)
Viewer.setDefaults({
title:false,
toolbar:false
})
Vue.use(Vuex)
Vue.use(VueAxios, axios)
Vue.config.productionTip = false
/* eslint-disable no-new */
function newVue() {
// login('XK', 'XUke+0301').then(res => {
login('J009321', 'Hhj2025.').then(res => {
//login('CC', '242019').then(res => {
store.commit("changeUserInfo", {
attr: 'userData',
val: res
})
axiosConfig()
new Vue({
el: '#app',
router,
store,
components: {
App
},
template: '<App/>'
})
})
if (window.cordova) {
Vue.prototype.$hybridApi.configHeader({
show: false
}); //配置去掉v平台的首页
Vue.prototype.$hybridApi.layout('212A48');
}
}
if (process.env.NODE_ENV === 'development') {
// run dev时执行
newVue()
} else { //run build
var u = navigator.userAgent;
var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; //android终端
var isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
//根据配置来引入
if (isAndroid) {
//安卓
document.write('<script src="static\/js\/android\/cordova.js"><\/script>');
} else { }
document.addEventListener('deviceready', function () {
newVue()
})
}
实际使用方法如下
# Vue界面直接写入
this.$tips.successAudio.play();
this.$tips.errorAudio.play();
浙公网安备 33010602011771号