开发笔记(运维系统)--汉字转拼音、复制功能、echarts点击事件、vue监听路由的变化、监听div元素的变化、CSS:hover时改变另一元素的显示/隐藏

265 阅读7分钟

记录工作中软件项目开发的一些使用记录和遇到的问题

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 的键值配置如下:

image.png

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 添加点击事件

  1. setOption echarts后,添加 this.echarts.on(‘click’, function()) 即可添加左击事件,function里面的paramsecharts的对象,打印出来查看echarts信息,如关系图的节点信息。根据信息自定义点击部位。

  2. 以下代码是柱状图的点击事件,点击bar打印信息(根据params中的type类型自定义点击部位):

  3. 在 ECharts 中事件分为两种类型:

  • 一种是用户鼠标操作点击,或者 hover图表的图形时触发的事件;
  • 另一种是用户在使用可以交互的组件后触发的行为事件,例如在切换图例开关时触发的 legendselectchanged事件(这里需要注意切换图例开关是不会触发legendselected事件的),数据区域缩放时触发的 datazoom 事件等等; 常见的事件类型: clickdblclickmousedownmousemovemouseupmouseovermouseoutglobaloutcontextmenu 事件等
 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,

image.png

  • 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;

image.png 注释: 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 子元素)

project6.gif

<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)

project7.gif

  <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的儿子) project8.gif

	<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:工作中用过的一些知识点,自己记录的笔记和整理来网络上的资源 ,方便以后复习使用。