一、功能点
- 文字可以换行
- 可以随意这是重点加粗的文字
- 对话图标可以显示、隐藏
- 箭头可以调整左右方向、在对话框的上面、下面,以及相对中间偏移
二、具体功能能实现
功能都不复杂,这里简单说一下,哈哈,但有一个重要的点,还是先提前说一下: 对话框里的文字,是用v-html插入进去的,因为要实现内部文字的加粗,需要提前处理,将加粗的文字,用标签包起来。
1、文字换行
输入框回车后,所输入的文字内,会有\n,所以,把\n批量替换成
标签就可以了
js
htmlText = htmlText.replaceAll("\n", `<br />`);
2、内部部分文字加粗
遍历要加粗的文字数组,将需要加粗的文字,用标签包起来,大概的逻辑如下:
js
boldTexts.forEach(boldText => {
if (boldText) {
htmlText = htmlText.replaceAll(boldText, `<>${boldText}</>`);
}
});
htmlText = htmlText.replaceAll("<>", `<span style="font-weight: 900;">`);
htmlText = htmlText.replaceAll("</>", `</span>`);
3、箭头的调整
这个就简单了,就用用css样式去控制下,这里就不细说了,下面有完整的代码,一看就知道了。
完整代码
哈哈,写技术分享,不贴出完整代码的,都是在耍流氓。
vue3
<template>
<div
class="word-pop-container need-bubble"
:class="{'has-horn': showHorn}"
v-if="textHtml"
>
<div class="show-horn" v-if="showHorn" >
<img src="./image/chat.png" />
</div>
<div>
<span v-html="textHtml"></span>
</div>
<div
class="arrow-box"
:class="{
flip: wordPopConfigData.arrowPosition,
'no-filp ': !wordPopConfigData.arrowPosition,
}"
>
<i
class="arrow"
:class="{ flip: wordPopConfigData.arrowFlip }"
:style="{ left: wordPopConfigData.arrowOffsetX + 'px' }"
></i>
</div>
</div>
</template>
<script lang="ts">
import { computed, defineComponent, ref } from "vue";
export default defineComponent({
name: "WordPop",
props: {
configData: {
type: Object,
require: true,
default: (() => {}),
}
},
setup(props) {
const defaultConfigData = ref({
text: "", // 对话文本
boldTexts: [], // 加粗的文字
showHorn: true, // 显示对话图标
arrowPosition: false, // 箭头位置:fanse:下,true:上
arrowFlip: false, // 箭头指向:false右,true:左
arrowOffsetX: -40, // 箭头偏移,单位:像素,相对位置:对话框中间文职,正数向右偏移、负数向左偏移
});
const wordPopConfigData = computed(() => {
return {
...defaultConfigData.value,
...props.configData,
}
});
const textHtml = computed(() => {
let htmlText = wordPopConfigData.value.text;
wordPopConfigData.value.boldTexts.forEach(boldText => {
if (boldText) {
htmlText = htmlText.replaceAll(boldText, `<>${boldText}</>`);
}
});
htmlText = htmlText.replaceAll("<>", `<span style="font-weight: 900;">`);
htmlText = htmlText.replaceAll("</>", `</span>`);
htmlText = htmlText.replaceAll("\n", `<br />`);
return htmlText;
});
// 对话标识
const showHorn = computed(() => {
return Boolean(wordPopConfigData.value.showHorn || false);
});
return {
wordPopConfigData,
showHorn,
textHtml,
};
},
});
</script>
<style lang="less" scoped>
.word-pop-container {
width: auto;
height: auto;
position: relative;
color: #000;
letter-spacing: normal;
text-align: left;
white-space: nowrap;
padding: 10px 18px;
border-radius: 40px;
display: inline-block;
border: 3px solid #f2f2f2;
&.has-horn {
padding: 10px 18px 10px 43px;
}
.show-horn {
position: absolute;
width: 20px;
height: 20px;
top: 0px;
bottom: 0px;
left: 13px;
margin: auto;
img {
width: 100%;
height: 100%;
border-radius: 15px;
}
}
span {
font-size: 16px;
line-height: 1.4;
}
&.need-bubble {
background-color: #fff;
}
.arrow-box {
position: absolute;
width: 30px;
height: 20px;
left: 50%;
bottom: -20px;
&.no-filp {
transform: translateX(-50%);
}
&.flip {
bottom: auto;
top: 0;
transform-origin: top center;
transform: translateX(-50%) rotateX(180deg);
}
}
.arrow {
display: block;
width: 100%;
height: 100%;
background-image: url(./image/sweepWordArrow.png);
background-size: 100% 100%;
background-repeat: no-repeat;
position: absolute;
bottom: 2.3px;
&.flip {
transform-origin: center;
transform: rotateY(180deg);
}
}
}
</style>
四、最后
欢迎各位来用下我用了近2年,搞的一款网页编辑器,一定会让你感到惊讶的,哈哈!
- 网站地址:www.h5nocode.com
之后,我会继续总结,把这个工具里的一些功能模块,抽离出来,放在github.com/lcl6659/vue... 这里,感兴趣的朋友可以看看,顺手给个star,也算是支持一下我了,在此感谢!!