这篇文章主要为大家详细介绍了Vue CLI3搭建的项目中路径相关问题的解决,具有一定的参考价值,可以用来参考一下。
感兴趣的小伙伴,下面一起跟随四海网的小编两巴掌来看看吧!
最近在试水 Vue CLI 3,并且尝试配置一个多页面(多应用)项目出来,期间又遇到各种路径问题,于是...于是有了下面的唠叨。
以下都是基于 Vue CLI 3 来举例说明的,使用 2.x 版本的其实也类似
首先,参考 官方文档对静态资源处理的说明,并通过自己的实践,可以总结出以下内容
静态资源可以通过两种方式进行处理:
1、以下情况下,资源不会被 webpack 处理,而是被直接拷贝:
2、以下情况下,资源会被 webpack 处理(URL的resolve、minify、uglify、转 base64 等):
我们应该根据实际情况去选择我们要引用的资源是否要被处理,然后用对应的、正确的方式去引用它们以达到目的。以下对使用绝对路径和相对路径的方法和注意事项进行描述。
默认情况下,Vue CLI 会假设你的应用是被部署在一个域名的根路径上(对应选项 baseUrl: '/'
),例如 https://www.my-app.com/
。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.my-app.com/my-app/,则设置 baseUrl 为 /my-app/。正因为以上的可能情况,我们应该在打算引用纯静态资源(那些不被webpack处理的资源,一般就是 public 目录下的资源)的时候,都确保使用 baseUrl 作为 URL 的开头,以下列举在不同文件中配合 baseUrl 选项写绝对路径的使用方法和注意事项:
我们可以使用lodash template 语法插入 baseUrl:
代码如下:
<link rel="icon" href="<%= BASE_URL %>favicon.ico" rel="external nofollow" >
我们可以通过 Vue CLI 提供的客户端环境变量 process.env.BASE_URL 来获取 baseUrl:
代码如下:
/* 在需要的组件中定义 baseUrl,然后在 <template> 下使用 */
<template>
<div id="app">
<img :src="imgUrl">
<img :src="`${baseUrl}imgs/my_image.png`">
</div>
</template>
<script>
export default {
name: 'App',
data() {
return {
baseUrl: process.env.BASE_URL,
isBigImg: Math.random() > 0.5
}
}
computed: {
// 动态地获取不同的静态资源
imgUrl() {
if (this.isBigImg) {
return `${baseUrl}imgs/my_image_big.png`
} else {
return `${baseUrl}imgs/my_image.png`
}
}
}
};
</script>
/* 个人建议可以在全局定义,减去在每个组件内定义的麻烦
Vue.prototype.$baseUrl = process.env.BASE_URL
// 在 <template> 下使用
<img :src="`${$baseUrl}imgs/my_image.png`">
代码如下:
import axios from 'axios';
const baseUrl = process.env.BASE_URL;
axios.defaults.baseURL = `http://www.example.com${baseUrl}api/`
因为 sass 文件中无法获取环境变量或 webpack 内的配置,于是最直接的方法就是自定义一个变量,然后在每个需要使用到它的文件引用它。
代码如下:
// config.scss
$baseUrl: "/";
// icon.scss
@import "config"
.icon-test {
display: inline-block;
background: url($baseUrl + 'imgs/icon_test.png') no-repeat;
width: 10px;
height: 10px;
}
这样做还是有比较大的麻烦:
那么,有没有什么办法能避免人工操作、避免多次的定义并且避免使用可能潜在错误的引用呢?幸亏的确是有的! sass-loader 提供了一个 data 选项,可以为全局注入变量或样式文件;
代码如下:
// vue.config.js
const baseUrl = process.env.NODE_ENV === 'production' ? '/sub/' : '/';
module.exports = {
baseUrl,
css: {
loaderOptions: {
sass: {
data: `$baseUrl: "${baseUrl}";`
}
}
}
}
这样我们就可以在全局的 `sass` 文件中使用 `$baseUrl` 这个变量了,而且在只定义一次的情况下,能根据编译环境变化而变化。
使用相对路径也会存在一些坑,接下来会列举常见的关于相对路径的坑与解决方法:
有时候我们需要使用 JavaScript 动态的引用某些资源,且希望这些资源被 webpack 一同打包,我们先看这种做法:
代码如下:
computed: {
background () {
return `./bgs/${this.id}.jpg`
}
}
我们会发现打包没报错,但是在页面上可以发现这些资源的请求都是 404。这是因为类似 ./bgs/${this.id}.jpg 这样的动态字符串在打包阶段不会被 webpack 识别为依赖,资源也就不会被打包了。为了让 webpack 识别这些依赖,我们可以这样做:
代码如下:
computed: {
background () {
return require('./bgs/' + this.id + '.jpg')
}
}
通过使用 require() 让 webpack 将括号内的 URL 识别为一个依赖并传入对应的 loader 进行处理。
要特别注意,以上的例子中,./bgs/ 目录下的所有图片都会被打包,因为 webpack 无法得知页面在运行时会使用哪张图片,所以 webpack 会把所有的图片都打包了。
先来看一个例子:
代码如下:
// 文件目录
// src
// |--assets
// | |
// | |-fonts
// | | |- iconfont.eot
// | |
// | |-css
// | |
// | |-iconfont.scss
// |
// |--app.vue
代码如下:
// iconfont.scss
@font-face {
font-family: "iconfont";
src: url("../fonts/iconfont.eot");
...
}
代码如下:
// app.vue
<style lang="scss">
@import './assets/css/iconfont.scss'
</style>
往往我们在打包的时候会报错(以上例子会报错),说找不到 iconfont.eot。 sass-loader 文档中有对 url() 进行了单独的说明:
Since Sass/libsass does not provide url rewriting, all linked assets must be relative to the output.
If you're just generating CSS without passing it to the css-loader, it must be relative to your web root.
If you pass the generated CSS on to the css-loader, all urls must be relative to the entry-file (e.g. main.scss).
大致意思就是, sass-loader 并不提供 url 的重写,所有的 scss 文件被 sass-loader 处理成最终的 CSS 后(编译过程中 url 不会被重写即保持原样),再传递给 css-loader 处理。也就是说,所有的 url 都是相对于输出的!在 Vue CLI 搭建的项目中,它们都是相对于使用这些 scss 文件的 vue 文件的。对于上例,是相对于 app.vue 的,因此报错。我们会很自然的会希望路径的引用是相对于 scss 文件本身的,sass-loader 文档中也给出了解决方案:
Add the missing url rewriting using the resolve-url-loader. Place it before the sass-loader in the loader chain.
Library authors usually provide a variable to modify the asset path. bootstrap-sass for example has an $icon-font-path. Check out this working bootstrap example.
第一个方法:使用 resolve-url-loader 来弥补 sass-loader 缺失的 url 重写功能,注意要放到 sass-loader 以前调用。
第二个方法:Library 作者一般都会提供变量,用来设置资源路径,如 bootstrap-sass 可以通过 $icon-font-path 来设置。参见this working bootstrap example。
这样看来解决的思路有两种:
在这里提供一下我喜欢的方法。与其考虑 让路径的引用是相对于 scss 文件本身 或 让路径直接相对于 vue 文件,我们可以换个思路,让所有路径都是以根目录往下找,并让 webpack 对路径进行重写,但是直接用 /src/ 这种绝对路径的写法会让这些资源不被 webpack 打包。在前文提及到的,webpack 有个强大的机制,也就是 ~,通过在 url 前面添加 ~ 可以告诉 webpack 要把它当做一个模块来处理,也就是会被 webpack 打包。配合 webpack 提供的别名 @(/src),我们可以对上例做修改:
代码如下:
// iconfont.scss
@font-face {
font-family: "iconfont";
src: url("~@/assets/fonts/iconfont.eot");
...
}
这样子,通过 webpack 对模块的处理,可以正确通过编译!这样做的好处是可大大避免书写相对路径可能产生的错误,每次只需“无脑”从根目录往下找就是了,又可以减小依赖、减少配置项。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持四海网。
本文来自:http://www.q1010.com/184/6214-0.html
注:关于Vue CLI3搭建的项目中路径相关问题的解决的内容就先介绍到这里,更多相关文章的可以留意四海网的其他信息。
关键词:vue.js
四海网收集整理一些常用的php代码,JS代码,数据库mysql等技术文章。