Vue处理静态资源:public、assets⽬录
前⾔: webpack中的require解析
⾸先明确⼀点,在项⽬中的fig.js等项⽬配置⽂件中使⽤的require属于nodejs范畴,⽽进⼊index.js后,加载的组件中的require 都属于webpack的解析范畴。
webpack中require的⽤法:
let url = "@/assets/images/carousel/logo.svg"
require(url) //报错
let url = "logo.svg"
require("@/assets/images/carousel/"+url); //正确
这是因为你修改页⾯后,webpack进⾏编译,等待编译完,需要进⾏⼯程的打包,然后打包正确,才能热加载运⾏并刷新页⾯。
如果require中传⼊的是个变量,它有可能是计算机系统中的任何⽬录下的任何⽂件,那么在打包静态资源时它有可能会将
你的电脑整个磁盘遍历⼀遍(它很傻)。所以⾄少需要给出在哪个路径下,这样才能精确的将那个路径下的对应⽂件打包,然后在代码运⾏时,直接⽤对应⽂件名⽣成正则匹配(因为打包后的⽂件,可能有hash值。不能直接查⽂件名),到后,加载到代码中。
所以,请记住尽可能详细的指定require中的路径,然后拼接变量.
接下来说下打包后的路径问题:
webpack将项⽬中的静态资源编译打包后,⽣成的路径已经不是原来的那个路径了。如
src/assets/image/logo.jpg
编译后可能变成
dist/public/image/logo.1d997ea3.jpg
⽽通过require("src/assets/image/logo.jpg"),会⾃动到并加载dist/public/image/logo.1d997ea3.jpg⽂件
Vue 是如何处理静态资源的?
Vue 静态资源可以通过两种⽅式进⾏处理:
1、在 JavaScript 被导⼊或在 template/CSS 中通过相对路径被引⽤。这类引⽤会被 webpack 处理(如:assets⽬录的⽂件)。
2、放置在public⽬录下或通过绝对路径引⽤。这类资源将会直接被拷贝,⽽不会经过 webpack 的处理。
⼀、URL 转换规则
1、<template>部分的路径处理
Vue Loader 在编译单⽂件组件中的 <template> 块时,它也会将所有遇到的资源 URL 转换为 webpack 模块请求。(这样我们就没必要⼿动调⽤require了,⽽是交给vue-loader处理了)
vue-loader默认可以处理的标签/特性的组合如下:
{
video: ['src', 'poster'],
img: 'src', //即img元素上的src属性
source: 'src', //source元素上的src属性
image: 'xlink:href'
}
⾯对上⾯的标签组合,vue-loader会⾃动进⾏资源url的转换。
转换规则:
a、如果路径是绝对路径,会被原样保留。如/src/assets/image/login/title.png
//代码
<template>
<img src="/src/assets/image/login/title.png" alt="">
</template>
//渲染后html页⾯
<img data-v-70c98a68="" src="/src/assets/image/login/title.png" alt="">
/
/当然这个图⽚是⽆法展⽰的,因为编译后title.png已不在src/assets/image/login下了
b、如果路径以 . 开头,将会被看作相对的模块依赖。如 ./titlea.png
//代码
<img src="./titlea.png" alt="">
//渲染后html页⾯
<img data-v-70c98a68="" src="/static/img/titlea.1e9fa570.png" alt="">
c、如果路径以 @ 开头,也会被看作模块依赖。如果你的 webpack 配置中给 @ 配置了 alias,这就很有⽤了。所有 vue-cli 创建的项⽬都默认配置了将 @ 指向 /src
//代码
<img src="@/assets/image/login/title.png" alt="">
//渲染后html页⾯
<img data-v-70c98a68="" src="/static/img/title.1e9fa570.png" alt="">
d、如果路径以 ~ 开头,其后的部分将会被看作模块依赖,既可以加载含有别名的静态资源,⼜可以加载node-modules中的资源。如
//代码
<img src="~@/assets/image/login/title.png" alt="">
//渲染后html页⾯
<img data-v-70c98a68="" src="/static/img/title.1e9fa570.png" alt="">
//代码
<img src="~[npm包名]/xxx/logo.png" alt="">
//渲染后的html页⾯
<img data-v-70c98a68="" src="/static/img/logo.2f53e458.png" alt="">
2、<style>部分的路径处理
由于vue-loader在处理style时,采⽤的是style-loader,所以可能和上⾯<template>部分的转换规则不太⼀样。
在vue-loader的内部使⽤了如下的配置(不⼀定配置,也有可能通过js直接给rules赋值):
//在vue-loader的内部使⽤css-loader
module: {
rules: [
{
test: /\.css$/,
loader: 'css-loader',
options: {
url: true, //默认选项
},
},
],
},
};
url为true时,则意味着可以将url中的字符串通过require()加载进来。
转换规则
a、如果路径是绝对路径,会被原样保留。如/src/assets/image/login/title.png
//代码
<style scoped>
.login-wrap {
background-image: url("/src/assets/image/login/title.png");
}
</style>
//渲染后css
.login-wrap[data-v-70c98a68] {
background-image: url(/src/assets/image/login/title.png);
}
同样这个图⽚是⽆法展⽰的,因为编译后title.png已不在src/assets/image/login下了。
b、如果路径以 . 开头,将会被看作相对的模块依赖。如 ./titlea.png
//代码
<style scoped>
.login-wrap {
background-image: url("./titlea.png");
}
</style>
//渲染后css
.login-wrap[data-v-70c98a68] {
background-image: url(/static/img/titlea.1e9fa570.png);
}
c、如果路径以 ~ 开头,其后的部分将会被看作模块依赖,即可以加载含有别名的静态资源,⼜可以加载node-modules中的资源。如
//代码
<style scoped>
.login-wrap {
background-image: url("~[npm包名]/logo.png");
}
</style>
//渲染后css
.login-wrap[data-v-70c98a68] {
background-image: url(/static/img/logo.e05643fc.png);
}
//代码
正则匹配等级域名网址<style scoped>
.login-wrap {
background-image: url("~@/assets/image/login/bg.png");
}
</style>
//渲染后css
.login-wrap[data-v-70c98a68] {
background-image: url(/static/img/bg.1d997ea3.png);
}
注意:和上⾯的<template>相⽐,唯独少了直接⽤@开头的⽅式url("@/assett/logo.png"),所以下⾯写法是错误的
//代码
<style scoped>
.login-wrap {
background-image: url("@/assets/image/login/bg.png");
}
</style>
⼆、从相对路径导⼊(assets⽬录)
当在 JavaScript、CSS 或*.vue⽂件中使⽤相对路径 (必须以.开头) 引⽤⼀个静态资源时,该资源将会被包含进 webpack 的依赖图中。编译过程中,所有诸如<img src="...">、background: url(...)和 CSS @import的资源 URL 都会被解析为⼀个模块依赖。
例如,url(./image.png)会被翻译为require('./image.png'),⽽:
<img src="./image.png">
将会被编译到:
h('img', { attrs: { src: require('./image.png') }})
在其内部,Vue 通过file-loader⽤版本哈希值和正确的公共基础路径来决定最终的⽂件路径,再⽤url-loader将⼩于 4kb 的资源内联,以减少HTTP 请求的数量。
可以通过调整内联⽂件的⼤⼩限制。例如,下列代码会将其限制设置为 10kb:
// ports = {
chainWebpack: config => {
.use('url-loader')
.loader('url-loader')
.tap(options => Object.assign(options, { limit: 10240 }))
}}
三、public⽂件夹
任何放置在public⽂件夹的静态资源都会被简单的复制,⽽不经过 webpack 。需要通过绝对路径来引⽤。
注意 Vue 推荐将资源作为模块依赖图的⼀部分导⼊,这样会通过 webpack 的处理并获得如下好处:
1、脚本和样式表会被压缩且打包在⼀起,从⽽避免额外的⽹络请求。
2、⽂件丢失会直接在编译时报错,⽽不是到了⽤户端才产⽣ 404 错误。
3、最终⽣成的⽂件名包含了内容哈希,因此你不必担⼼浏览器会缓存它们的⽼版本。
public⽬录提供的是⼀个应急⼿段,当通过绝对路径引⽤时,需要留意应⽤会部署到哪⾥。如果没有部署在域名的根部,需要为你的 URL 配置前缀:
在public/index.html或其它通过html-webpack-plugin⽤作模板的 HTML ⽂件中,需要通过<%= BASE_URL %>设置链接前缀:
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
在模板中,⾸先需要向你的组件传⼊基础 URL:data () {
return {
publicPath: v.BASE_URL
}
}
然后:
<img :src="`${publicPath}my-image.png`">
如publicPath设置为'/','/hls265/h265.m3u8'即可访问:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论