两年前写用nvue直播间功能时遇到的问题,是因为nvue中文本不能写自适应宽度,挺奇葩的。
以下是为了在用nvue必须实现某些功能才无奈写用的,正常情况写个max-width,再加上padiing就可以了
话不多说,直接上重点了
核心代码
代码简解,计算出一段文本的字节数,包含中文、英文、特殊符号、表情包的计算逻辑
function countLineStr(str, size) {
var textNum = 0
var a = 0,
c = 0,
d = 0,
b = 0,
b1 = 0,
b2 = 0,
b3 = 0,
b4 = 0,
b5 = 0,
b6 = 0,
b7 = 0,
b8 = 0,
b9 = 0,
e = 0
// 获取中文和中文字符内容
if (str.match(/[—]/g)) {
a = str.match(/[—]/g).length * 0.12
}
a = str.match(/[\u4E00-\u9FA5\u0391-\uFFE5]/g) ? a + str.match(/[\u4E00-\u9FA5\u0391-\uFFE5]/g).length : a + 0
console.log(a)
// 获取英文内容
if (str.match(/[a-z]/gi)) {
// 0.579
b1 = str.match(/[aoekvyEFLST]/g) ? (str.match(/[aoekvyEFLST]/g).length * 0.579) : 0
// 0.654
b2 = str.match(/[bpqdghnuBKPRYXZ]/g) ? (str.match(/[bpqdghnuBKPRYXZ]/g).length * 0.654) : 0
// 0.503
b3 = str.match(/[szcx]/g) ? (str.match(/[szcx]/g).length * 0.51) : 0
// 0.398
b4 = str.match(/[frtJ]/g) ? (str.match(/[frtJ]/g).length * 0.398) : 0
// 0.295
b5 = str.match(/[iljI]/g) ? (str.match(/[iljI]/g).length * 0.295) : 0
// 0.748
b6 = str.match(/[ACGUV]/g) ? (str.match(/[ACGUV]/g).length * 0.748) :
0
// 0.815
b7 = str.match(/[wDHNOQ]/g) ? (str.match(/[wDHNOQ]/g).length * 0.815) : 0
// 0.978
b8 = str.match(/[m]/gi) ? (str.match(/[m]/gi).length * 0.978) : 0
// 1.019
b9 = str.match(/[W]/g) ? (str.match(/[W]/g).length * 1.019) : 0
b = b1 + b2 + b3 + b4 + b5 + b6 + b7 + b8 + b9
}
// 获取数字内容
// c = str.match(/[0-9]/g) ? (str.match(/[0-9]/g).length -(str.match(/[0-9]/g).length-1)*(1- 0.588)) : 0
c = str.match(/[0-9]/g) ? (str.match(/[0-9]/g).length * 0.588) : 0
// c = str.match(/[0-9]/g) ? (str.match(/[0-9]/g).length * 2) : 0
// 获取特殊符号内容
var ts = str.match(
/[^\u4E00-\u9FA5\u0391-\uFFE50-9a-z\u{1F601}-\u{1F64F}\u{2702}-\u{27B0}\u{1F680}-\u{1F6C0}\u{1F170}-\u{1F251}\u{1F600}-\u{1F636}\u{1F681}-\u{1F6C5}\u{1F30D}-\u{1F567}]/gui
)
if (ts) {
// 0.579
// var e1 = str.match(/[$]/g) ? (str.match(/[$]/g).length -(str.match(/[$]/g).length-1)* (1-0.579)) : 0
var e1 = str.match(/[$]/g) ? (str.match(/[$]/g).length * 0.579) : 0
// 0.654
var e2 = str.match(/[#]/g) ? (str.match(/[#]/g).length * 0.654) : 0
var e3 = str.match(/[-/"?_*]/g) ? (str.match(/[-/"?_*]/g).length * 0.503) : 0
var e4 = str.match(/[{}()!]/g) ? (str.match(/[{}()!]/g).length * 0.34) : 0
var e5 = str.match(/[.:;']/g) ? (str.match(/[.:;']/g).length * 0.257) : 0
var e6 = str.match(/[~+=<^]/g) ? (str.match(/[~+=<^]/g).length * 0.75) : 0
var e7 = str.match(/[@]/g) ? (str.match(/[@]/g).length * 1.04) : 0
// 0.891
var e8 = str.match(/[%&]/g) ? (str.match(/[%&]/g).length * 0.891) : 0
// 1.628/2
var e9 = 0
// (/[%&@~+=<^.:;'{}()!-/"?_*#$]/g)
e = e1 + e2 + e3 + e4 + e5 + e6 + e7 + e8 + e9
}
// 获取表情包正则
// /[\u{1F601}-\u{1F64F}\u{2702}-\u{27B0}\u{1F680}-\u{1F6C0}\u{1F170}-\u{1F251}\u{1F600}-\u{1F636}\u{1F681}-\u{1F6C5}\u{1F30D}-\u{1F567}]/gu
var zz = str.match(
/\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation}|\p{Emoji}\uFE0F/gu
)
if (zz) {
// d = (zz.length) * 1.374
console.log(zz.length)
d = zz.length * 1.374
a = a - (zz.length * 2)
}
textNum = (a + b + c + d + e)
return Math.ceil(textNum)
}
使用指南
1.核心代码放utils文件里
2.在要使用的页面引用
import util from '@/utils/util.js'
3.使用(写法请按实际情况调整)
① 计算一段文本的字节数
this.systemFontWidth = util.countLineStr(this.infoList.courseTitle)
②文本宽度= (字节数 × 自己想要的每个字节占宽 )+ 自己需要的padding宽度
:style="'width:'+((systemFontWidth*27)+140>=436?436:(systemFontWidth*27)+140)+'rpx' "
③给文本设置水平居中样式
首先,我们知道nvue格式是只能使用flex布局,即display属性仅能为flex,且默认 flex-direction: column
。
flex-direction: row;
flex-wrap: wrap;
align-items: center;