记录工作中软件项目开发的一些使用记录和遇到的问题
1. 纯前端实现汉字转拼音 —— pinyin-pro 库
汉字转拼音 —— pinyin-pro 库
一般实现汉字转拼音的功能都是请求服务端 api 实现,而对于一些比较简单的需求,我们可以通过一个 npm 工具包 —— pinyin-pro ,纯前端实现中文汉字转拼音的功能。 npm地址
1. 特色功能
- 支持汉字、词语、句子多种格式输入获取
- 获取拼音
- 获取声母
- 获取韵母
- 获取拼音首字母
- 获取音调
- 获取多音字的多种拼音
- 支持人名姓氏模式
- 支持自定义拼音
- 支持字符串和数组两种输出形式
2. 安装
npm 安装
npm install pinyin-pro
引入 浏览器 script 引入:
<!--引入某个版本,如3.3.0版本-->
<!-- <script src="https://cdn.jsdelivr.net/gh/zh-lx/pinyin-pro@3.3.0/dist/pinyin-pro.js"></script> -->
<!--引入最新版本-->
<script src="https://cdn.jsdelivr.net/gh/zh-lx/pinyin-pro@latest/dist/pinyin-pro.js"></script>
<script>
var { pinyin } = pinyinPro;
pinyin('汉语拼音'); // 'hàn yǔ pīn yīn'
</script>
ESModule 引入:
import { pinyin } from 'pinyin-pro';
pinyin('汉语拼音'); // 'hàn yǔ pīn yīn'
commonjs 引入:
const { pinyin } = require('pinyin-pro');
pinyin('汉语拼音'); // 'hàn yǔ pīn yīn'
3. 参数
pinyin(word, options) 接收两个参数
-
word: 必填。String 类型,需要转化为拼音的中文
-
options: 可选。Object 类型,用于配置各种输出形式,options 的键值配置如下:
4.使用示例
4.1获取拼音
import { pinyin } from 'pinyin-pro';
// 获取带音调拼音
pinyin('汉语拼音'); // 'hàn yǔ pīn yīn'
// 获取不带声调的拼音
pinyin('汉语拼音', { toneType: 'none' }); // 'han yu pin yin'
// 获取声调转换为数字后缀的拼音
pinyin('汉语拼音', { toneType: 'num' }); // 'han4 yu3 pin1 yin1'
// 获取数组形式带音调拼音
pinyin('汉语拼音', { type: 'array' }); // ["hàn", "yǔ", "pīn", "yīn"]
// 获取数组形式不带声调的拼音
pinyin('汉语拼音', { toneType: 'none', type: 'array' }); // ["han", "yu", "pin", "yin"]
// 获取数组形式声调转换为数字后缀的拼音
pinyin('汉语拼音', { toneType: 'num', type: 'array' }); // ["han4", "yu3", "pin1", "yin1"]
4.2 获取声母
import { pinyin } from 'pinyin-pro';
// 获取声母
pinyin('汉语拼音', { pattern: 'initial' }); // 'h y p y'
// 获取数组形式声母
pinyin('汉语拼音', { pattern: 'initial', type: 'array' }); // ["h", "y", "p", "y"]
4.3 获取韵母
import { pinyin } from 'pinyin-pro';
// 获取带音调韵母
pinyin('汉语拼音', { pattern: 'final' }); // 'àn ǔ īn īn'
// 获取不带音调韵母
pinyin('汉语拼音', { pattern: 'final', toneType: 'none' }); // 'an u in in'
// 获取音调为数字的韵母
pinyin('汉语拼音', { pattern: 'final', toneType: 'num' }); // 'an4 u3 in1 in1'
// 获取数组形式带音调韵母
pinyin('汉语拼音', { pattern: 'final', type: 'array' }); // ["àn", "ǔ", "īn", "īn"]
// 获取数组形式不带音调韵母
pinyin('汉语拼音', { pattern: 'final', toneType: 'none', type: 'array' }); // ["an", "u", "in", "in"]
// 获取数组形式音调为数字的韵母
pinyin('汉语拼音', { pattern: 'final', toneType: 'num', type: 'array' }); // ['an4', 'u3', 'in1', 'in1']
4.4 获取音调
import { pinyin } from 'pinyin-pro';
// 获取音调
pinyin('汉语拼音', { pattern: 'num' }); // '4 3 1 1'
// 获取数组形式音调
pinyin('汉语拼音', { pattern: 'num', type: 'array' }); // ["4", "3", "1", "1"]
4.5 获取拼音首字母
import { pinyin } from 'pinyin-pro';
// 获取拼音首字母
pinyin('赵钱孙李额', { pattern: 'first' }); // 'z q s l é'
// 获取不带音调拼音首字母
pinyin('赵钱孙李额', { pattern: 'first', toneType: 'none' }); // 'z q s l e'
// 获取数组形式拼音首字母
pinyin('赵钱孙李额', { pattern: 'first', type: 'array' }); // ['z', 'q', 's', 'l', 'é']
// 获取数组形式不带音调拼音首字母
pinyin('赵钱孙李额', { pattern: 'first', toneType: 'none', type: 'array' }); // ['z', 'q', 's', 'l', 'e']
4.6 获取单个字的多音
只有单字可以获取到多音模式, 词语、句子无效。同样可以通过配置 options 选项获取数组形式、韵母等格式
import { pinyin } from 'pinyin-pro';
// 获取多音
pinyin('好', { multiple: true }); // 'hǎo hào'
// 获取数组形式多音
pinyin('好', { multiple: true, type: 'array' }); // ["hǎo", "hào"]
4.8 姓氏模式
通过设置 mode: 'surname' 开启姓氏模式后,匹配到百家姓中的姓氏优先输出姓氏拼音
import { pinyin } from 'pinyin-pro';
// 不开启姓氏模式
pinyin('我叫曾小贤'); // 'wǒ jiào céng xiǎo xián'
// 开启姓氏模式
pinyin('我叫曾小贤', { mode: 'surname' }); // 'wǒ jiào zēng xiǎo xián'
4.9 自定义拼音
包内部导出了 customPinyin 方法,支持用户自定义设置词句拼音,当中文中匹配用户自己定义的词句拼音时,优先使用用户自定义的词句拼音
import { pinyin, customPinyin } from 'pinyin-pro';
customPinyin({
干一行行一行: 'gàn yī háng xíng yī háng',
});
pinyin('干一行行一行'); // 'gàn yī háng xíng yī háng'
2. 实现复制功能
Clipboard.writeText方法
Clipboard 接口的 writeText() 方法可以写入特定字符串到操作系统的剪切板。会返回一个Promise ,一旦剪贴板的内容被更新,它就会被解析。如果调用者没有写入剪贴板的权限,则拒绝写入剪贴板(reject)
项目中使用
onCopy() {
navigator.clipboard.writeText(this.detailData.clientSecret).then(() => {
this.$message.success('复制成功')
})
}
3. echarts 添加点击事件
-
在
setOption echarts后,添加this.echarts.on(‘click’, function())即可添加左击事件,function里面的params是echarts的对象,打印出来查看echarts信息,如关系图的节点信息。根据信息自定义点击部位。 -
以下代码是柱状图的点击事件,点击bar打印信息(根据params中的type类型自定义点击部位):
-
在 ECharts 中事件分为两种类型:
- 一种是用户鼠标操作点击,或者
hover图表的图形时触发的事件; - 另一种是用户在使用可以交互的组件后触发的行为事件,例如在切换图例开关时触发的
legendselectchanged事件(这里需要注意切换图例开关是不会触发legendselected事件的),数据区域缩放时触发的datazoom事件等等; 常见的事件类型:click、dblclick、mousedown、mousemove、mouseup、mouseover、mouseout、globalout、contextmenu事件等
this.cmpChart.on('click', function (params) {
if (params.componentType === 'series') {
console.log('您点击了我')
}
})
<script>
// 1. 基于准备好的dom,初始化ECharts实例
var myChart = echarts.init(document.getElementById('main'));
// 2. 指定图表的配置项和数据
var option = {
......
};
// 3. 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
// 4. 处理点击事件并且跳转到相应的百度搜索页面
myChart.on('click', function (params) {
// 此处一般写:click事件触发后的回调,来完成额外的功能
});
</script>
如果遇到报错
vue 父子组件传值报错:this.$emit is not a function 解决
报错基本上都是因为this指向问题,基本上就是 function 和 () => 之间的问题,进行这俩的替换基本上都可以解决。我碰到了此问题,因为this指向了方法,而不是vue,
-
function函数的this是使用时指定。(创建function函数时,this是undefined,只有在函数被调用的时候,this指向调用者)
-
箭头函数的this是创建时指定。(当箭头函数被创建的时候,会根据当前上下文来bind当前的this,函数在之后的调用过程中,都能访问到创建该函数的上下文)
function函数的初衷就是为了创建对象,所以我们用function函数来当普通函数在web端调用的时候,很容易出现各种问题,而后面出现的箭头函数极大的解决了这个问题。 所以,我建议在之后的代码编写中,当需要使用创建对象的时候,使用function函数,而仅仅需要当做执行方法时,用箭头函数。这样写起代码来思路很更加清晰。
4. vue监听路由变化的几种方式
vue页面开发中,我们经常需要根据路由的变化去实现一些操作,那么如何监听路由的变化呢?当然是利用vue中的 watch ,请看代码。
一、监听路由从哪儿来到哪儿去
watch:{
$route(to,from){
console.log(from.path);//从哪来
console.log(to.path);//到哪去
}
}
二、监听路由变化获取新老路由信息
watch:{
$route:{
handler(val,oldval){
console.log(val);//新路由信息
console.log(oldval);//老路由信息
},
// 深度观察监听
deep: true
}
}
三、监听路由变化触发方法
methods:{
getPath(){
console.log(1111)
}
},
watch:{
'$route':'getPath'
}
四、全局监听路由
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
const router = new Router({
routes: [
{
path: '/wechat-user-statistics',
name: 'wechat-user-statistics',
component: WechatUserStatistics
},
....
]
})
// 全局监听路由
router.beforeEach((to, from, next) => {
console.log(to);
next();
});
export default router
五、组件内部监听
beforeRouteEnter (to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当钩子执行前,组件实例还没被创建
},
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
beforeRouteLeave (to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
}
5. css盒子阴影 (box-shadow)
语法 box-shadow: h-shadow v-shadow blur spread color inset;
注释: box-shadow向框添加一个或多个阴影. 该属性是由逗号分隔的阴影列表,每个阴影由2-4个长度值、可选的颜色值及可选的inset关键词来规定。省略长度的值是0。
div{
width:250px;
height:250px;
background:greenyellow;
box-shadow:black 0px 0px 10px;//将h-shadow,v-shadow设为0px,实现四周阴影
}
6.vue中怎么实时监听div元素盒子的宽高
在Vue中实时监听div盒子的宽高可以使用resize事件结合refs来实现。
首先,在div盒子上添加一个ref属性,例如:
<div ref="box"></div>
然后,在Vue组件的mounted生命周期钩子中添加事件监听:
methods:{
handleResize() {
if (this.$refs.box) {
const width = this.$refs?.box?.offsetWidth
const height = this.$refs.box.offsetHeight
// 在这里处理宽高变化的逻辑
if (width < 960) {
}
// console.log('盒子宽度:', width, '盒子高度:', height)
}
}
},
mounted() {
window.addEventListener('resize', this.handleResize)
},
在Vue组件的methods中定义handleResize方法来处理宽高变化:
beforeDestroy() {
window.removeEventListener('resize', this.handleResize)
},
这样就能实时监听div盒子的宽高了。
7. CSS:hover时改变另一元素的显示/隐藏(3种情况)
情况1.改变子元素(父元素:hover 子元素)
<style>
.parent {
margin-left: 40px;
width: 200px;
height: 200px;
background: #cc66dd;
}
.child {
width: 100px;
height: 100px;
background: #3333dd;
display: none;
}
.parent:hover .child {
display: block;
}
</style>
<body>
<div class="parent">
父
<div class="child">子</div>
</div>
</body>
情况2.改变兄弟元素(兄弟1:hover+兄弟2)
<style>
.brother1 {
width: 100px;
height: 100px;
background: #cc66dd;
}
.brother2 {
width: 100px;
height: 100px;
background: #3333dd;
display: none;
}
.brother1:hover+.brother2 {
display: block;
}
</style>
<body>
<div class="brother1">大弟</div>
<div class="brother2">二弟</div>
</body>
情况3.改变兄弟元素下子元素(兄弟1:hover+兄弟2>兄弟2的儿子)
<style>
.brother1{
width: 100px;
height:100px;
background: #cc66dd;
}
.brother2{
width: 100px;
height: 100px;
background: #3333dd;
}
.brother2-son{
width: 50px;
height: 50px;
background: #ffff00;
display: none;
}
.brother1:hover+.brother2>.brother2-son{
display: block;
}
</style>
<body>
<div class="brother1">大弟</div>
<div class="brother2">二弟
<div class="brother2-son">二弟儿子</div>
</div>
</body>
ps:工作中用过的一些知识点,自己记录的笔记和整理来网络上的资源 ,方便以后复习使用。