JavaScript 中 箭头函数(Arrow Function)的语法差异.

bug重现

在项目调试的时候,发现javascript在过滤数组的时候,发现竟然为空数组。

var ages = [32, 33, 16, 40]; //想要获取除了第二个元素外的所有元素
//第一种写法:
var a = ages.filter((_, index) => index !== 1);

//第二种写法:
var a = ages.filter((_, index) => { index !== 1 });

这两种写法,就因为有一个{}导致结果完全不一样,第一种写法能够返回预想中的效果。

第二种写法就会返回一个空的数组。

原因

  • 第一种写法,没有{},那么他就不是一个代码块,等于直接返回 index !== 1 的元素。
  • 第二种写法,因为有{},那么就是一个代码块,而我们没有给return,那么就返回一个undefined。

修改:

如果我们硬性要求添加{},那么我们就应该添加一个return

var a = ages.filter((_, index) => { return index !== 1 });

VUE3中使用动态组件

有时候一个页面中我们需要加载很多个组件,而且这些组件需要根据服务器请求的数据来判断该用哪个组件。

举个使用场景:我们在做IM或者客服软件,在加载聊天记录的时候,就要根据服务器给出不同类型的消息加载不同的消息组件,有文本,图片,视频,音频,表情,附件等等。

如果我们用v-if也是可以做的,在组件多的情况下代码看起来就特别的臃肿,那么我们这个时候就可以用动态组件来做这个事情。

我们使用vue框架提供的动态组件component来做。

<component :is="item.component" v-for="(item,index) in messageList":key="index" :message="item"></component>

如果此代码放在vue2中是完全没有问题的,因为item.component是动态的组件名称。如果在vue3中就无效了。

原因是vue3使用的是组件实例,不再是组件名称。

那么我们需要添加一些东西

<script setup>
import ComA "./ComponentA";
import ComB "./ComponentB";

defineOptions({
  components: {
    ComA , ComB 
  }
})

</script>

我看网络上有写说用resolveComponent动态实例化,如下:

<component :is="resolveComponent(item.component)" v-for="(item,index) in messageList":key="index" :message="item"></component>


<script setup>
import {resolveComponent} from "vue";
import ComA "./ComponentA";
import ComB "./ComponentB";

</script>

在本人电脑上尝试无效果。

关于Chrome Extensions 消息通讯

有些功能需要用到消息通讯,比如我们需要获取某个网站的cookie发送到后台服务器,那么我们手动点击之后,需要获取cookie,然后发送。

一、设置服务脚本

定义接收通讯消息的处理脚本。

{ 
 "background": {
    "service_worker": "background/service-worker.js",
    "type": "module"
  },
  "host_permissions": [
    "https://*/*",
    "http://*/*"
  ],
  "permissions": [
    "cookies", 
    "declarativeNetRequestFeedback",
    "declarativeNetRequestWithHostAccess",
    "declarativeNetRequest",
    "webRequest"
  ]
}

二、在前台发送消息给服务脚本

通过chrome的api发送“chrome.runtime.sendMessage”

<template>
 <button type="primary" style="width: 100%;" @click="onSendMessage">发送消息</el-button>
</template>

<script>
const onSendMessage= async () => {
  const res = await chrome.runtime.sendMessage({
    diyData: dataBody
  });
}
<script>

三、接收

chrome.runtime.onMessage.addListener(
    function (request, sender, sendResponse) {
        console.log(request)
        console.log(sender)
        console.log(sendResponse)
        const data = request.diyData;

   chrome.cookies.getAll({
            domain: "taobao.com"
        }, function (cookies) {
            let cookieString = ""
            cookies.forEach(function (cookie) {
                 cookieString += cookie.name + "=" + cookie.value + ";"
            }
            fetch( "http://www.xx.com/api/data",
            {
                method: "post",
                headers: {
                   'Content-Type': 'application/json'
                },
                body: JSON.stringify(data),
            }
            ).then(
                res => {
                    console.log(res);
                    let reader = res.body.pipeThrough(new TextDecoderStream())
                        .getReader();
                    reader.read().then(rs => {
                        const data = JSON.parse(rs.value)
                        sendResponse(data); //发送给前端。
                    })
                }
            ).catch(
                err => {
                    console.log(err)
                }
            )
        });
    }
)

如果出现问题了,记得看看自己在清单中是否申请了权限。

Vue子组件每次加载都执行Mounted周期函数

Vue框架为了提高性能,对组件进行了缓存,所以第二次加载相同的子组件的时候,是不会创建新的dom,而是使用缓存。

但是有时候我们需要每次加载子组件都执行一次Mounted函数来做一些数据的初始化或者请求等等,所以这是个麻烦事了。

vue组件通过key来识别组件是否缓存,那么我们可以在组件上面添加一个key值,每次请求的时候都不一样,这样就可以解决上面的问题(不考虑性能问题)。

父组件

<template>
 <div>
   <Com :key="randdomKey"></Com>
 </div>
</template>

在每次要加载显示Com子组件的时候,就改变randdomKey的值即可。

在Vue3中使用Chart.js组件

在开发一个后台的时候,我们需要经常用到各种图表展示数据,然后数据更加直观,同时也让自己的项目逼格更高。今天我们就用Vue3+Chart.js组件来展示数据。

我们在已经安装了Vue3的基础上来安装Chart.js.

Chart.js官网地址:https://www.chartjs.org/

一、安装Chart.js

npm install chart.js

二、在vue组件中使用

html代码:

        <div class="card-content-image">
          <canvas id="planetChart" width="100%" height="380"></canvas>
        </div>

script代码

<script setup>
import Chart from 'chart.js/auto';
import {onMounted} from "vue";

const data = {
  labels: ['22-10-01', '22-10-02', '22-10-03', '22-10-04', '22-10-05', '22-10-06', '22-10-07', '22-10-08', '22-10-09', '22-10-10', '22-10-11', '22-10-12'],
  datasets: [
    {
      label: 'Dataset 1',
      data: [23, 42, 35, 27, 43, 22, 17, 31, 22, 22, 102, 16],
    },
    {
      label: 'Dataset 2',
      data: [213, 42, 35, 27, 43, 22, 17, 31, 22, 22, 12, 16],
    }
  ]
}

onMounted(() => {
  const ctx = document.getElementById('planetChart');
  let chart = new Chart(ctx, {
    type: 'line',
    data: data,
    options: {
      responsive: true,
      plugins: {
        legend: {
          position: 'top',
        },
        title: {
          display: true,
          text: '7日数组走势图'
        }
      }
    },
  });
})
</script>

展示结果:

注意

如果提示 chart: can't acquire context from the given item 是组件还没有加载完成导致的,把执行放入 onMounted 钩子函数中就可以了。

更多的配置,比如颜色,背景色等参考官网配置文档:https://www.chartjs.org/docs/latest/configuration/