一、ETag相关
ETag(Entity Tag)是 HTTP 1.1 协议中的一部分,用于确定浏览器缓存的一个资源在服务器上是否已经被修改。它是一个可以分配给特定版本和实例的资源的标识符,通常是一个哈希值。服务器可以在发送资源时,将该资源的 ETag 一起发送给客户端。然后客户端在再次请求该资源时,会将此 ETag 值一起发送给服务器,服务器根据 ETag 判断资源是否有变动。
ETag 的工作原理是这样的:
- 浏览器第一次请求一个资源(比如一个图片),服务器在返回这个资源的同时,也把这个资源的 ETag 值(通常是一个哈希值)在响应头中一并返回,浏览器收到资源后,会将这个资源及其 ETag 值缓存起来。
- 当浏览器再次请求这个资源时,会将之前保存的 ETag 值放在请求头中一并发送给服务器。服务器会比对请求头中的 ETag 值和服务器上该资源的当前 ETag 值是否一致,以此来判断资源是否有变动。
- 如果 ETag 没变,说明资源没有变动,服务器会返回 304 状态码,告诉浏览器直接使用本地缓存即可。如果 ETag 变了,说明资源已经被改动过,服务器会返回新的资源内容和新的 ETag 值。
使用 ETag 的方法如下:
- 在服务器端,可以在响应头中添加 ETag,例如
ETag: "12345"
。 - 在客户端,可以在请求头中添加 If-None-Match,例如
If-None-Match: "12345"
。
ETag 可以有效地节省带宽和服务器资源,因为当资源没有变化时,服务器可以不用返回资源内容,只需要返回一个 304 状态码即可。同时,ETag 也有助于防止同时写入("mid-air"写入)。这是当多个用户同时尝试更改同一资源时可能会发生的问题。通过将 ETag 值放入 If-Match 请求头中,可以让服务器只在 ETag 值匹配时才执行操作。如果 ETag 值不匹配,说明资源已经被其他用户更改,服务器可以返回 412(Precondition Failed)状态码,拒绝执行操作。
二、JS引用方式
type=Module和UMD(Universal Module Definition)是JavaScript模块加载方式的两种不同策略。它们的主要区别在于使用方式和兼容性。
当在<script>标签中使用type="module"时,该脚本将被当作ES6模块。这意味着在这样的脚本中可以使用import和export语法。此外,这些脚本默认是延迟加载的,即它们会等到所有HTML文档都被完全加载和解析后再运行。
ES6模块是现代浏览器支持的原生模块系统。然而,老版本的浏览器并不支持ES6模块,因此如果要支持老版本浏览器,可能需要使用一些构建工具,如Babel和webpack等,将ES6模块转换为其他类型的模块。
UMD(Universal Module Definition)
UMD是一种兼容CommonJS和AMD两种规范的模块定义方式。这种方式的主要目的是使一个模块能够在各种环境中运行,包括浏览器环境和服务器环境。
UMD模块可以通过<script>标签直接在浏览器中引入,并且不需要特殊的属性。然而,由于UMD模块需要兼容多种环境,所以它的代码通常会比其他类型的模块更复杂。
总结起来,type=module更适合于现代浏览器环境,而UMD则旨在提供一种在各种环境中都能运行的通用解决方案。
三、VUE3 国际化实现方案
Vue3的国际化实现方案主要使用的是vue-i18n插件。以下是一个示例:
首先,安装vue-i18n插件:
npm install vue-i18n@next
然后,创建一个i18n.js文件,用于配置国际化选项:
import { createI18n } from 'vue-i18n'
const messages = {
en: {
message: {
hello: 'Hello World'
}
},
zh: {
message: {
hello: '你好,世界'
}
}
}
const i18n = createI18n({
locale: 'en', // 设置默认语言
messages,
})
export default i18n
在你的main.js中,引入这个配置并挂载到Vue实例上:
import { createApp } from 'vue'
import App from './App.vue'
import i18n from './i18n'
createApp(App).use(i18n).mount('#app')
在你的组件中,你可以使用$t方法来获取国际化的消息:
<template>
<p>{{ $t('message.hello') }}</p>
</template>
你也可以在任何地方动态切换语言:
this.$i18n.locale = 'zh'
四、VUE实例的生命周期管理
Vue实例的生命周期管理是通过一系的生命周期钩子函数来实现的,这些钩子函数在Vue实例的不同阶段被调用,可以让开发者在恰当的时机添加自己的代码。
以下是Vue实例的生命周期钩子函数:
beforeCreate
:在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。created
:在实例创建完成后被立即调用。在这一步,实例已完成以下的配置:数据观测(data observer),属性和方法的运算,watch/event事件回调。然而,挂载阶段还没开始,$el属性目前不可见。beforeMount
:在挂载开始之前被调用,相关的render函数首次被调用。mounted
:在el被新创建的vm.$el替换,并挂载到实例上去之后调用该钩子。如果root实例挂载了一个文档内的元素,当mounted被调用时vm.$el也在文档内。beforeUpdate
:数据更新时调用,发生在虚拟DOM重新渲染和打补丁之前。可以在这个钩子中进一步改变状态,这不会触发附加的重渲染过程。updated
:由于数据更改导致的虚拟DOM重新渲染和打补丁,在这之后会调用该钩子。beforeDestroy
:实例销毁之前调用。在这一步,实例仍然完全可用。destroyed
:Vue实例销毁后调用。调用后,所有的事件监听器会被移除,所有的子实例也会被销毁。
以上就是Vue实例的生命周期管理,通过这些钩子函数,我们可以更好地控制和管理Vue实例的状态。
五、Vite和Webpack最核心的区别和不同
Vite和Webpack是两种用于现代前端开发的构建工具,它们在许多方面有所不同,但最关键的区别主要在于以下几点:
构建速度:Vite使用了ESBuild,比Webpack更快。ESBuild采用Go语言编写,利用多核并行转译,大大提高了打包速度。而Webpack的构建速度相对较慢。
开发模式:Vite在开发模式下,采用原生ESM模块,按需编译,无需等待整个应用编译完成,从而实现了极快的热更新。而Webpack在开发模式下,需要对所有模块进行编译打包,然后才能进行热更新。
插件系统:Vite的插件系统更简单,更易于使用。Vite插件基于rollup插件设计,对于开发者来说,使用起来更加方便。而Webpack的插件系统相对复杂,需要更多的学习和理解。
配置:Vite的配置相对简单,更加易于理解和使用。而Webpack的配置更加复杂。
兼容性:Webpack更老,因此对旧的浏览器和语法有更好的支持。Vite则需要现代浏览器支持原生ESM。
体积:相比于Webpack,Vite的体积更小,更轻量。
默认支持:Vite默认支持Vue.js,而Webpack则需要配置。
在选择哪个工具时,需要考虑项目的具体需求,如构建速度、兼容性、易用性等因素。
六、关于ESM
ESM是ES Modules的缩写,它是JavaScript的官方模块系统,是ECMAScript 6(也称为ES2015)引入的一种新的模块化方式。
在ESM中,你可以使用import和export关键字来导入和导出函数、对象或值。这种模块化方式可以帮助你更好地组织和共享代码。
ESM与之前的CommonJS模块系统(在Node.js中使用)有一些关键的区别,包括:
ESM是静态的,这意味着你不能在运行时改变或创建模块。所有的导入和导出都需要在顶级范围(非函数内)进行,并且必须在编译时确定。这使得静态分析和优化(如tree shaking)成为可能。
ESM支持异步加载和动态加载。
ESM支持循环依赖和默认导出。
由于ESM是JavaScript语言的标准组成部分,因此它在现代浏览器中得到了广泛的支持,也被许多现代JavaScript工具(如Babel,Webpack,Rollup,Vite等)所支持。