ESlint 使用备忘

安装到项目中

 npm install eslint --save-dev

生成一个配置文件

npx eslint --init

参考下列选项,注意第一条选择第3个To check syntax, find problems, and enforce code style,可以检查代码风格问题

✔ How would you like to use ESLint? · style
✔ What type of modules does your project use? · esm
✔ Which framework does your project use? · react
✔ Does your project use TypeScript? · No / Yes
✔ Where does your code run? · browser
✔ How would you like to define a style for your project? · guide
✔ Which style guide do you want to follow? · standard
✔ What format do you want your config file to be in? · JavaScript

vscode中开启保存时自动修复,

1 安装ESlint扩展
2 打开vscode的配置文件,添加下面的配置
  // #每次保存的时候将代码按eslint格式进行修复
    "editor.codeActionsOnSave": {
        "source.fixAll.eslint": true
    },

常用规则

'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', // allow console during development
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', // allow debugger during development
// 以下为该项目自定义部分
// indent: [2, 4], // 缩进风格 - 开启缩进4格
'no-spaced-func': 2, // 函数调用时 函数名与()之间不能有空格 - 开启
'no-const-assign': 2, // 禁止修改const声明的变量 - 开启
'space-before-function-paren': [0, 'always'], // 函数定义时括号前面要有空格 - 关闭
'eol-last': 0, // 文件以单一的换行符结束 - 关闭
camelcase: 0, // 强制驼峰法命名 - 关闭
'no-undef': 0, // 不能有未定义的变量 - 关闭
'no-alert': 0, // 禁止使用alert confirm prompt - 关闭
'arrow-parens': 0 // 箭头函数用小括号括起来 - 关闭

判断h5页面是否在微信小程序的web-view里面

思路是通过使用微信的SDK(https://res.wx.qq.com/open/js/jweixin-1.3.2.js)提供的wx.miniProgram.getEnv方法来判断当前环境。

直接用下面的代码,或者用我写好的页面直接放到小程序的web-view里面测试:https://liuxiaofan.com/test/mp.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    1111
    <script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.3.2.js"></script>
    <script>
            var ua = navigator.userAgent.toLowerCase();
            if (ua.match(/MicroMessenger/i) == "micromessenger") {
                //ios的ua中无miniProgram,但都有MicroMessenger(表示是微信浏览器)
                wx.miniProgram.getEnv((res) => {
                    if (res.miniprogram) {
                        alert("在小程序里")
                    } else {
                        alert("不在小程序")
                    }
                })
            } else {
                alert("不在微信")
            }
    </script>
</body>
</html>

 

video事件及属性备忘

事件

<video src="test.mp4" controls width="400" height="300" id="video"></video>
  
  <script>
    var video = document.getElementById('video')

    // 1、loadstart:视频查找。当浏览器开始寻找指定的音频/视频时触发,也就是当加载过程开始时
    video.addEventListener('loadstart', function(e) {
      console.log('提示视频的元数据已加载')
      console.log(e)
      console.log(video.duration)            // NaN
    })

    // 2、durationchange:时长变化。当指定的音频/视频的时长数据发生变化时触发,加载后,时长由 NaN 变为音频/视频的实际时长
    video.addEventListener('durationchange', function(e) {
      console.log('提示视频的时长已改变')
      console.log(e)
      console.log(video.duration)           // 528.981333   视频的实际时长(单位:秒)
    })

    // 3、loadedmetadata :元数据加载。当指定的音频/视频的元数据已加载时触发,元数据包括:时长、尺寸(仅视频)以及文本轨道
    video.addEventListener('loadedmetadata', function(e) {
      console.log('提示视频的元数据已加载')
      console.log(e)
    })

    // 4、loadeddata:视频下载监听。当当前帧的数据已加载,但没有足够的数据来播放指定音频/视频的下一帧时触发
    video.addEventListener('loadeddata', function(e) {
      console.log('提示当前帧的数据是可用的')
      console.log(e)
    })

    // 5、progress:浏览器下载监听。当浏览器正在下载指定的音频/视频时触发
    video.addEventListener('progress', function(e) {
      console.log('提示视频正在下载中')
      console.log(e)
    })

    // 6、canplay:可播放监听。当浏览器能够开始播放指定的音频/视频时触发
    video.addEventListener('canplay', function(e) {
      console.log('提示该视频已准备好开始播放')
      console.log(e)
    })

    // 7、canplaythrough:可流畅播放。当浏览器预计能够在不停下来进行缓冲的情况下持续播放指定的音频/视频时触发
    video.addEventListener('canplaythrough', function(e) {
      console.log('提示视频能够不停顿地一直播放')
      console.log(e)
    })

    // 8、play:播放监听
    video.addEventListener('play', function(e) {
      console.log('提示该视频正在播放中')
      console.log(e)
    })

    // 9、pause:暂停监听
    video.addEventListener('pause', function(e) {
      console.log('暂停播放')
      console.log(e)
    })

    // 10、seeking:查找开始。当用户开始移动/跳跃到音频/视频中新的位置时触发
    video.addEventListener('seeking', function(e) {
      console.log('开始移动进度条')
      console.log(e)
    })

    // 11、seeked:查找结束。当用户已经移动/跳跃到视频中新的位置时触发
    video.addEventListener('seeked', function(e) {
      console.log('进度条已经移动到了新的位置')
      console.log(e)
    })

    // 12、waiting:视频加载等待。当视频由于需要缓冲下一帧而停止,等待时触发
    video.addEventListener('waiting', function(e) {
      console.log('视频加载等待')
      console.log(e)
    })

    // 13、playing:当视频在已因缓冲而暂停或停止后已就绪时触发
    video.addEventListener('playing', function(e) {
      console.log('playing')
      console.log(e)
    })

    // 14、timeupdate:目前的播放位置已更改时,播放时间更新
    video.addEventListener('timeupdate', function(e) {
      console.log('timeupdate')
      console.log(e)
    })

    // 15、ended:播放结束
    video.addEventListener('ended', function(e) {
      console.log('视频播放完了')
      console.log(e)
    })

    // 16、error:播放错误
    video.addEventListener('error', function(e) {
      console.log('视频出错了')
      console.log(e)
    })

    // 17、volumechange:当音量更改时
    video.addEventListener('volumechange', function(e) {
      console.log('volumechange')
      console.log(e)
    })

    // 18、stalled:当浏览器尝试获取媒体数据,但数据不可用时
    video.addEventListener('stalled', function(e) {
      console.log('stalled')
      console.log(e)
    })

    // 19、ratechange:当视频的播放速度已更改时
    video.addEventListener('ratechange', function(e) {
      console.log('ratechange')
      console.log(e)
    })
  </script>

属性

<!-- video 不支持 IE8及以下版本浏览器,支持三种视频格式:MP4,WebM 和 Ogg -->
  <video src="test.mp4" controls width="400" height="300"></video>

  <!-- 禁止下载 -->
  <video src="test.mp4" controls controlslist="nodownload" width="400" height="300"></video>

  <!-- 禁止下载,禁止全屏 -->
  <video src="test.mp4" controls controlslist="nodownload nofullscreen" width="400" height="300"></video>

  <!-- 自动播放 (不同浏览器的表现不一样) -->
  <video src="test.mp4" controls autoplay width="400" height="300"></video>

  <!-- 默认静音播放(可手动点开继续播放) -->
  <video src="test.mp4" controls muted width="400" height="300"></video>

  <!-- 循环播放 -->
  <video src="test.mp4" controls loop width="400" height="300"></video>

  <!-- 预加载 -->
  <video src="test.mp4" controls preload width="400" height="300"></video>

  <!-- 贴图 -->
  <video src="test.mp4" poster="poster.jpg" controls width="400" height="300"></video>

  <!-- 音量控制 -->
  <video src="test.mp4" poster="poster.jpg" controls width="400" height="300" id="_volume"></video>
  <script>
    var video = document.getElementById('_volume')
    video.volume = 2 // 取值范围:0 到 1,0 是静音,0.5 是一半的音量,1 是最大音量(默认值)
  </script>

  <!-- 播放时间控制 -->
  <video src="test.mp4" poster="poster.jpg" controls width="400" height="300" id="_time"></video>
  <script>
    var video = document.getElementById('_time')
    console.log(video.currentTime)  // 视频当前正在播放的时间(单位:s),进度条拖到哪就显示当前的时间
    video.currentTime = 60  // 默认从60秒处开始播放
  </script>

  <!-- 播放地址切换 (常见于切换超清  高清 流畅,不同画质的视频地址不同) -->
  <video src="test.mp4" controls autoplay width="400" height="300" id="_src"></video>
  <script>
    var video = document.getElementById('_src')
    console.log(video.src)     // http://127.0.0.1:8001/test.mp4   绝对地址,DOM 中是相对地址
    // video.src = 'test-2.mp4'   // 直接替换掉了原来的视频src
    setTimeout(() => {
      video.src = 'test-2.mp4'  // 播放到第 30s 的时候,自动切换视频
    }, 30000)
  </script>

  <!-- 备用地址切换 -->
  <video controls autoplay width="400" height="300" id="_source">
    <source src="test3.mp4" type="video/mp4" />
    <source src="test9.mp4" type="video/mp4" />
    <source src="test-2.mp4" type="video/mp4" />
  </video>
  <script>
    var video = document.getElementById('_source')
    setTimeout(() => {
      console.log(video.currentSrc)     // http://127.0.0.1:8001/test.mp4
    }, 1000)

    // HTTP 载入失败,状态码 404。媒体资源 http://127.0.0.1:8001/test3.mp4 载入失败。
    // HTTP 载入失败,状态码 404。媒体资源 http://127.0.0.1:8001/test9.mp4 载入失败。
    // http://127.0.0.1:8001/test-2.mp4
    // 当第一段视频加载失败时,自动加载下一段视频

 

5 模式和环境变量 – Vue CLI

1 三种模式

  • development 模式用于 vue-cli-service serve
  • test 模式用于 vue-cli-service test:unit
  • production 模式用于 vue-cli-service build 和 vue-cli-service test:e2e

当运行 vue-cli-service 命令时,所有的环境变量都从对应的环境文件中载入。如果文件内部不包含 NODE_ENV 变量,它的值将取决于模式,例如,在 production 模式下被设置为 “production”,在 test 模式下被设置为 “test”,默认则是 “development”。

如果你想要在构建命令中使用开发环境变量,需要使用–mode参数,例如:

vue-cli-service build --mode development

2 环境变量

在项目根目录中新建下列文件来指定环境变量文件

.env                # 在所有的环境中被载入
.env.local          # 在所有的环境中被载入,但会被 git 忽略
.env.[mode]         # 只在指定的模式中被载入
.env.[mode].local   # 只在指定的模式中被载入,但会被 git 忽略

环境文件的内容格式只允许包含环境变量的“键=值”对,例如:

// .env.dev
VUE_APP_ENV=dev
NODE_ENV=development
# 默认base地址
VUE_APP_API_BASE=https://api-xxx.com

3 在客户端侧代码中使用环境变量

在环境文件中,以 VUE_APP_ 开头的变量会被 webpack.DefinePlugin 静态嵌入到客户端侧的包中。你可以在项目的代码中这样访问它们:

console.log(process.env.VUE_APP_SECRET)

除了 VUE_APP_* 变量之外,在你的应用代码中始终可用的还有两个特殊的变量:

NODE_ENV - 会是 "development"、"production" 或 "test" 中的一个。具体的值取决于应用运行的模式。
BASE_URL - 会和 vue.config.js 中的 publicPath 选项相符,即你的应用会部署到的基础路径。

所有解析出来的环境变量都可以在 public/index.html 中以 HTML 插值中介绍的方式使用。

在 vue.config.js 文件中计算环境变量。它们仍然需要以 VUE_APP_ 前缀开头。这可以用于版本信息:

// vue.config.js
process.env.VUE_APP_VERSION = require('./package.json').version

module.exports = {
  // config
}

4 只在本地有效的变量

.local结尾的本地环境文件默认会被忽略,且出现在 .gitignore 中。比如 .env.development.local 将会在 development 模式下被载入,且被 git 忽略。

4. webpack 相关 – Vue CLI

1 简单的配置方式

在 vue.config.js 中的 configureWebpack 选项提供一个对象,该对象将会被 webpack-merge 合并入最终的 webpack 配置。

// vue.config.js
module.exports = {
  configureWebpack: {
    plugins: [
      new MyAwesomeWebpackPlugin()
    ]
  }
}

2 链式操作 (高级)

审查项目的 webpack 配置可以通过命令保存到output.js内查看

vue inspect > output.js

3 修改 Loader 选项

// vue.config.js
module.exports = {
  chainWebpack: config => {
    config.module
      .rule('vue')
      .use('vue-loader')
        .tap(options => {
          // 修改它的选项...
          return options
        })
  }
}

4 添加一个新的 Loader

// vue.config.js
module.exports = {
  chainWebpack: config => {
    // GraphQL Loader
    config.module
      .rule('graphql')
      .test(/\.graphql$/)
      .use('graphql-tag/loader')
        .loader('graphql-tag/loader')
        .end()
      // 你还可以再添加一个 loader
      .use('other-loader')
        .loader('other-loader')
        .end()
  }
}

5 修改插件选项

比方说你想要将 index.html 默认的路径从 /Users/username/proj/public/index.html 改为 /Users/username/proj/app/templates/index.html。

// vue.config.js
module.exports = {
  chainWebpack: config => {
    config
      .plugin('html')
      .tap(args => {
        return [/* 传递给 html-webpack-plugin's 构造函数的新参数 */]
      })
  }
}

3. css相关 – Vue CLI

1 引用静态资源

所有编译后的 CSS 都会通过 css-loader 来解析其中的 url()来进行引用,如果你想要引用一个 npm 依赖中的文件,或是想要用 webpack alias,则需要在路径前加上 ~

2 预处理器

如果创建项目时没有选择预处理器 (Sass/Less/Stylus),可以手动安装相应的 webpack loader,例如:

npm install -D sass-loader sass

3 自动化导入

通常一个项目中我们会有一些公共的css文件来定义颜色,mixin等等,例如variable.sass里面定义了一些字号、颜色等等。每次我们在页面中要使用这些公共的变量时都需要先把variable.sassimport进来,有点麻烦。你可以使用 style-resources-loader来完成自动导入,来避免手动操作。配置方法如下:

// vue.config.js
const path = require('path')

module.exports = {
  chainWebpack: config => {
    const types = ['vue-modules', 'vue', 'normal-modules', 'normal']
    types.forEach(type => addStyleResource(config.module.rule('scss').oneOf(type)))
  },
}

function addStyleResource (rule) {
  rule.use('style-resource')
    .loader('style-resources-loader')
    .options({
      patterns: [
        path.resolve(__dirname, './src/styles/variable.sass'),
      ],
    })
}

4 PostCSS

通过 vue.config.js 中的 css.loaderOptions.postcss 配置 postcss-loader。项目默认开启了 autoprefixer。如果要配置目标浏览器,可使用 package.json 的 browserslist 字段。

M1芯片Mac nginx使用

默认端口

8080

默认的配置文件地址

/opt/homebrew/etc/nginx/nginx.conf

默认的WEB根目录

/opt/homebrew/var/www

如果要指定你启动的NGINX.CONF文件

nginx -c /路径

停止NGINX

nginx -s stop

重启NGINX

nginx -s reload

M1新片Mac安装 HomeBrew

由于github国内访问非常的不稳定,现在使用HomeBrew官方的安装脚本很难顺利安装完成了,比较好的方式就是使用镜像安装,网上查了一圈,发现已经有人做好了现成的脚本,2021年7月7日亲测可用,具体步骤如下:

1. 执行安装脚本

/bin/zsh -c "$(curl -fsSL https://gitee.com/huwei1024/HomebrewCN/raw/master/Homebrew.sh)"

参考结果

        开始执行Brew自动安装程序
             [cunkai.wang@foxmail.com]
           [2021-07-07 13:48:08][11.2]
       https://zhuanlan.zhihu.com/p/111014448


请选择一个下载镜像,例如中科大,输入1回车。
源有时候不稳定,如果git克隆报错重新运行脚本选择源。cask非必须,有部分人需要。
1、中科大下载源 2、清华大学下载源 3、北京外国语大学下载源 4、腾讯下载源(不显示下载进度) 5、阿里巴巴下载源(缺少cask源)
请输入序号: 1

  你选择了中国科学技术大学下载源

!!!此脚本将要删除之前的brew(包括它下载的软件),请自行备份。
->是否现在开始执行脚本(N/Y)y

--> 脚本开始执行
==> 通过命令删除之前的brew、创建一个新的Homebrew文件夹
(设置开机密码:在左上角苹果图标->系统偏好设置->"用户与群组"->更改密码)
(如果提示This incident will be reported. 在"用户与群组"中查看是否管理员)
请输入开机密码,输入过程不显示,输入完后回车
Password:
开始执行
-> 创建文件夹 /opt/homebrew/Homebrew
此步骤成功
   ---备份要删除的文件夹到系统桌面....
   ---/Users/liuxiaofan/Library/Caches/Homebrew/ 备份完成
   ---备份要删除的文件夹到系统桌面....
   ---/opt/homebrew/Caskroom 备份完成
-> 创建文件夹 /opt/homebrew/Caskroom
此步骤成功
   ---备份要删除的文件夹到系统桌面....
   ---/opt/homebrew/Cellar 备份完成
-> 创建文件夹 /opt/homebrew/Cellar
此步骤成功
   ---备份要删除的文件夹到系统桌面....
   ---/opt/homebrew/var/homebrew 备份完成
-> 创建文件夹 /opt/homebrew/var/homebrew
此步骤成功
-> 创建文件夹 /opt/homebrew/var/homebrew/linked
此步骤成功
git version 2.30.1 (Apple Git-130)

下载速度觉得慢可以ctrl+c或control+c重新运行脚本选择下载源
==> 克隆Homebrew基本文件(32M+)

未发现Git代理(属于正常状态)
Cloning into '/opt/homebrew/Homebrew'...
remote: Enumerating objects: 194316, done.
remote: Total 194316 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (194316/194316), 49.91 MiB | 4.71 MiB/s, done.
Resolving deltas: 100% (145009/145009), done.
此步骤成功
==> 创建brew的替身
此步骤成功
==> 克隆Homebrew Core(224M+) 
此处如果显示Password表示需要再次输入开机密码,输入完后回车
Cloning into '/opt/homebrew/Homebrew/Library/Taps/homebrew/homebrew-core'...
remote: Enumerating objects: 989892, done.
remote: Total 989892 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (989892/989892), 396.10 MiB | 2.89 MiB/s, done.
Resolving deltas: 100% (682362/682362), done.
此步骤成功
==> 克隆Homebrew Cask(248M+) 类似AppStore 
此处如果显示Password表示需要再次输入开机密码,输入完后回车
Cloning into '/opt/homebrew/Homebrew/Library/Taps/homebrew/homebrew-cask'...
remote: Enumerating objects: 632124, done.
remote: Total 632124 (delta 0), reused 0 (delta 0)B | 1.82 MiB/s   
Receiving objects: 100% (632124/632124), 265.04 MiB | 981.00 KiB/s, done.
Resolving deltas: 100% (451506/451506), done.
此步骤成功
==> 配置国内镜像源HOMEBREW BOTTLE
此步骤成功

==> 安装完成,brew版本

11.2
brew -v

zsh:363: command not found: brew

    失败 查看下面文章第二部分的常见错误
    https://zhuanlan.zhihu.com/p/111014448
    如果没有解决,把运行脚本过程截图发到 cunkai.wang@foxmail.com --end

2. 因为M1芯片的包安装位置不在是以前的/usr/local/而是/opt/homebrew,所以要将配置文件里的环境变量改过来

1、首先进入根目录
$ cd ~
2、创建.zshrc文件
$ touch .zshrc
3、打开文件进行编辑
$ open -e .zshrc
4、如果有旧的环境就修改,没有就新增
export PATH=/opt/homebrew/bin:$PATH export PATH=/opt/homebrew/sbin:$PATH
参考结果 .zshrc文件内容
# HomeBrew export HOMEBREW_BOTTLE_DOMAIN=https://mirrors.ustc.edu.cn/homebrew-bottles # export PATH=”/usr/local/bin:$PATH” # export PATH=”/usr/local/sbin:$PATH” export PATH=/opt/homebrew/bin:$PATH export PATH=/opt/homebrew/sbin:$PATH # HomeBrew END
5、保存
使用command + s保存文件,然后关闭
6、生效环境变量
$ source .zshrc
7、测试
$ brew -v
参考结果
liuxiaofan@Richards-M1 ~ % brew -v Homebrew 3.2.1-26-g3cbf7b7-dirty Homebrew/homebrew-core (git revision 2107f7374a; last commit 2021-07-07) Homebrew/homebrew-cask (git revision 835d572f82; last commit 2021-07-07)

将文本中的url转化为超链接,包含端口

今天接到一个需求,要求在聊天窗口中,用户输入的文本内容,如果里面有超链接地址,就自动转换为a标签,让用户可以点击。

这个需求N年前做的sass项目就实现过,不过这次要求要把端口号也解析出来,例如http://localhost:3010/这样,趁机复习一下正则。

废话不多说,直接上代码

// 将文本中的url转化为超链接,包含端口
export const handleTextUrl = text => {
  let result = text || ''
  let reg = /(http:\/\/|https:\/\/)((\w|=|\?|\.|\/|&|-|:)+)/g
  if (result) {
    result = text.replace(reg, '<a href="$1$2" target="_blank">$1$2</a>')
  }
  return result
}
// handleTextUrl('测试一个地址:http://wiki.kaikeba.cn/pages/viewpage.action?pageId=24184041')
// handleTextUrl('http://localhost:3010/')

 

2. HTML 和静态资源 – Vue CLI

浏览器兼容性

package.json 文件里的 browserslist 字段 (或一个单独的 .browserslistrc 文件),指定了项目的目标浏览器的范围。这个值会被 @babel/preset-env 和 Autoprefixer 用来确定需要转译的 JavaScript 特性和需要添加的 CSS 浏览器前缀。

Polyfill

翻译为一块代码或插件,可以让旧浏览器兼容新语法,默认情况会根据browserslist 配置来决定项目需要的 polyfill

现代模式

为了兼容老浏览器,经过babel编译后的代码十分臃肿,而最新版本的浏览器已经支持了es6,所以你需要一个现代版的包,用下面的命令
vue-cli-service build --modern

 

HTML

public/index.html 文件是一个会被 html-webpack-plugin 处理的模板。在构建过程中,资源链接会被自动注入。所有客户端环境变量也可以直接使用。例如,BASE_URL 的用法:
<link rel="icon" href="<%= BASE_URL %>favicon.ico">

 

Preload

预先加载,<link rel=”preload”> 是一种 resource hint,可以指定一些资源在页面渲染完成之前提前加载,这些提示会被 @vue/preload-webpack-plugin 注入

Prefetch

也是一种 resource hint,页面加载完成后,利用空闲时间提前获取用户未来可能会访问的内容。
可以通过 chainWebpack 的 config.plugin(‘prefetch’) 进行修改和删除。

多页应用

Vue CLI 支持使用 vue.config.js 中的 pages 选项构建一个多页面的应用。例如:
pages: {
    admin: {
      entry: 'src/client.js',
      template: 'public/client.html',
      filename: 'client.html'
    },
    index: {
      entry: 'src/main.js',
      template: 'public/index.html',
      filename: 'index.html'
    }
  },

 

处理静态资源

放置在 public 目录下或通过绝对路径被引用的文件,将会直接被拷贝,而不会经过 webpack 的处理。

模块加载限制

所有 <img src=”…”>、background: url(…) 和 CSS @import 的资源 URL 都会被解析为一个模块依赖。
所以,url(./image.png) 会被翻译为 require(‘./image.png’),假设一个页面有100张图片,文件大小不一,为了减少请求数,我们可以设置一个值来决定小于这个值的文件都会放到一起请求。代码如下:
// vue.config.js
module.exports = {
  chainWebpack: config => {
    config.module
      .rule('images')
        .use('url-loader')
          .loader('url-loader')
          .tap(options => Object.assign(options, { limit: 10240 }))
  }
}

 

url转换规则

如果 URL 以 ~ 开头,其后的任何内容都会作为一个模块请求被解析。这意味着你甚至可以引用 Node 模块中的资源

public 文件夹

任何放置在 public 文件夹的静态资源都会被简单的复制,而不经过 webpack。你需要通过绝对路径BASE_URL来引用它们。
在模板中使用base_url
<img :src="`${publicPath}my-image.png`">
...
data () {
  return {
    publicPath: process.env.BASE_URL
  }
}