文末
js前端的重头戏,值得花大部分时间学习。
推荐通过书籍学习,《 JavaScript 高级程序设计(第 4 版)》你值得拥有。整本书内容质量都很高,尤其是前十章语言基础部分,建议多读几遍。
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
另外,大推一个网上教程 现代 JavaScript 教程 ,文章深入浅出,很容易理解,上面的内容几乎都是重点,而且充分发挥了网上教程的时效性和资料链接。
学习资料在精不在多,二者结合,定能构建你的 JavaScript 知识体系。
面试本质也是考试,面试题就起到很好的考纲作用。想要取得优秀的面试成绩,刷面试题是必须的,除非你样样精通。
这是288页的前端面试题
Vue CLI
简介
Vue脚手架(Vue CLI)是Vue.js 开发的标准工具,是一个基于 Vue.js 进行快速开发的完整系统。
官网:https://cli.vuejs.org/zh/
Vue脚手架是vue官方提供的vue脚手架工具,能够创建、测试、构建、调试vue项目。用来帮助程序员快速创建一个基于vue库的模板项目:
- 通过
@vue/cli
实现的交互式的项目脚手架。 - 通过
@vue/cli
+@vue/cli-service-global
实现的零配置原型开发。 - 一个运行时依赖 (
@vue/cli-service
),该依赖:- 可升级;
- 基于 webpack 构建,并带有合理的默认配置;
- 可以通过项目内的配置文件进行配置;
- 可以通过插件进行扩展。
- 一个丰富的官方插件集合,集成了前端生态中最好的工具。
- 一套完全图形化的创建和管理 Vue.js 项目的用户界面。
Vue CLI 致力于将 Vue 生态中的工具基础标准化。它确保了各种构建工具能够基于智能的默认配置即可平稳衔接,这样你可以专注在撰写应用上,而不必花好几天去纠结配置的问题。与此同时,它也为每个工具提供了调整配置的灵活性,无需 eject。
使用脚手架开发的项目的特点: 模块化, 组件化,工程化。
安装vue-cli
Node 版本要求
Vue CLI 4.x 需要 Node.js v8.9 或更高版本 (推荐 v10 以上)。你可以使用 n,nvm 或 nvm-windows 在同一台电脑中管理多个 Node 版本。
npm install -g @vue/cli
安装之后,你就可以在命令行中访问 vue
命令。你可以通过简单运行 vue
,看看是否展示出了一份所有可用命令的帮助信息,来验证它是否安装成功。
你还可以用这个命令来检查其版本是否正确:
vue --version
创建项目
命令行创建项目:
vue create 项目名称
也可以使用vue的界面化工具创建项目:
vue ui
启动项目
在开发环境启动项目,开发环境也会使用webpack打包、编译项目,打包的输出是在内存,适合开发项目的时候使用:
npm run serve
npm run serve 会把项目打包在内存中,并可以使用指定的端口号,默认是8080,在浏览器的地址栏访问:http://127.0.0.1:8080 打开项目。
打包项目
在生产环境下使用webpack编译、打包项目,打包的文件会输出到dist文件中,一般是项目开发完毕 或者 阶段性功能完毕打包输出文件,发布上线
npm run build
运行dist 文件夹中的index.html,不能直接双击打开index.html,需要把dist文件夹中所有的文件放到服务器静态目录下,可以使用live server插件、anywhere、nodejs 的public目录。
- 开发过程中使用 npm run serve,开发调试比较方便
- 开发完毕项目打包上线,使用 npm run build ,最终是把dist文件中的内容放到服务器的静态目录
项目结构
├── node_modules
├── public
│ ├── favicon.ico: 页签图标
│ └── index.html: 主页面
├── src
│ ├── assets: 存放静态资源
│ │ └── logo.png
│ │── components: 存放组件
│ │ └── HelloWorld.vue
│ │── App.vue: 汇总所有组件
│ │── main.js: 入口文件
├── .gitignore: git版本管制忽略的配置
├── babel.config.js: babel的配置文件
├── package.json: 应用包配置文件
├── README.md: 应用描述文件
├── package-lock.json:包版本控制文件
对Vue不同构建版本的解释
当以无构建步骤方式使用 Vue 时,组件模板要么是写在页面的 HTML 中,或者是内联的 JavaScript 字符串。在这些场景中,为了执行动态模板编译,Vue 需要将模板编译器运行在浏览器中。相对的,如果我们使用了构建步骤,由于提前编译了模板,那么就无须再在浏览器中运行了。为了减小打包出的客户端代码体积,Vue 提供了多种格式的“构建文件”以适配不同场景下的优化需求。
- 只包含运行时版:前缀为
vue.runtime.*
的文件是只包含运行时的版本:vue.esm.js
:只包含核心代码,不包含编译器,当使用这个版本时,所有的模板都必须由构建步骤预先编译。 - 完整版:名称中不包含
.runtime
的文件则是完全版:vue.runtime.esm.js
:包含核心代码和编译器,并支持在浏览器中直接编译模板。当然,体积也会因此增长不少。
默认的工具链中都会使用仅含运行时的版本,因为所有 SFC 中的模板都已经被预编译了。如果因为某些原因,在有构建步骤时,你仍需要浏览器内的模板编译,你可以更改构建工具配置,将 vue
改为相应的版本 vue/dist/vue.esm-bundler.js
。
完整的版本信息
在 NPM 包的 dist/
目录你将会找到很多不同的 Vue.js 构建版本。这里列出了它们之间的差别:
UMD | ES Module (基于构建工具使用) | ES Module (直接用于浏览器) | |
---|---|---|---|
完整版 | vue.js | vue.esm.js | vue.esm.browser.js |
只包含运行时版 | vue.runtime.js | vue.runtime.esm.js | - |
完整版 (生产环境) | vue.min.js | - | vue.esm.browser.min.js |
只包含运行时版 (生产环境) | vue.runtime.min.js | - | - |
术语
- 完整版:同时包含编译器和运行时的版本。
- 编译器:用来将模板字符串编译成为 JavaScript 渲染函数的代码。
- 运行时:用来创建 Vue 实例、渲染并处理虚拟 DOM 等的核心代码。基本上就是除去编译器的其它一切。
- UMD:UMD(Universal Module Definition通用模块定义) 版本可以通过
<script>
标签直接用在浏览器中。jsDelivr CDN 的 https://cdn.jsdelivr.net/npm/vue@2.7.10 默认文件就是运行时 + 编译器的 UMD 版本 (vue.js
)。 - ES Module (基于构建工具使用):为打包工具提供的 ESM:为webpack提供的现代打包工具。ESM 格式被设计为可以被静态分析,所以打包工具可以利用这一点来进行“tree-shaking”并将用不到的代码排除出最终的包。为这些打包工具提供的默认文件 (
pkg.module
) 是只有运行时的 ES Module 构建 (vue.runtime.esm.js
)。 - ES Module (直接用于浏览器):为浏览器提供的 ESM (2.6+):用于在现代浏览器中通过
<script type="module">
直接导入(vue.esm.browser.js
)。
运行时 + 编译器 vs. 只包含运行时
如果你需要在客户端编译模板 (比如传入一个字符串给 template
选项,或挂载到一个元素上并以其 DOM 内部的 HTML 作为模板),就将需要加上编译器,即完整版:
- vue.js是完整版的Vue:包含 核心代码 + 模板编译器,可以使用使用template配置项
- vue.runtime.esm.js是运行版的Vue:只包含 核心功能,没有模板编译器,所以不能使用template配置项,需要使用render函数接收到的h函数创建组件
// 运行时 + 编译器:需要编译器 vue.js
new Vue({
template: '<div>{{ hi }}</div>'
})
// 只包含运行时:不需要编译器 vue.runtime.esm.js
new Vue({
render (h) {
return h('div', this.hi)
}
})
开发环境 vs. 生产环境模式
对于 UMD 版本来说,开发环境/生产环境模式是硬编码好的:开发环境下用未压缩的代码,生产环境下使用压缩后的代码。
CommonJS 和 ES Module 版本是用于打包工具的,因此我们不提供压缩后的版本。你需要自行将最终的包进行压缩。
CommonJS 和 ES Module 版本同时保留原始的 process.env.NODE_ENV
检测,以决定它们应该运行在什么模式下。你应该使用适当的打包工具配置来替换这些环境变量以便控制 Vue 所运行的模式。把 process.env.NODE_ENV
替换为字符串字面量同时可以让 UglifyJS 之类的压缩工具完全丢掉仅供开发环境的代码块,以减少最终的文件尺寸。
在 webpack 4+ 中,你可以使用 mode
选项:
module.exports = {
mode: 'production'
}
单文件组件
为什么需要单文件组件
在很多 Vue 项目中,我们使用 Vue.component
来定义全局组件,紧接着用 new Vue({ el: '#app'})
在每个页面内指定一个容器元素。
这种方式在很多中小规模的项目中运作的很好,在这些项目里 JavaScript 只被用来加强特定的视图。但当在更复杂的项目中,或者你的前端完全由 JavaScript 驱动的时候,下面这些缺点将变得非常明显:
- 全局定义 (Global definitions) 强制要求每个 component 中的命名不得重复
- 字符串模板 (String templates) 缺乏语法高亮,在 HTML 有多行的时候,需要用到丑陋的
\
- 不支持 CSS (No CSS support) 意味着当 HTML 和 JavaScript 组件化时,CSS 明显被遗漏
- 没有构建步骤 (No build step) 限制只能使用 HTML 和 ES5 JavaScript,而不能使用预处理器,如 Pug (formerly Jade) 和 Babel
什么是单文件组件
一个 Vue 单文件组件 (英文 Single-File Component,简称 SFC),通常使用 *.vue
作为文件扩展名,它是一种使用了类似 HTML 语法的自定义文件格式,用于定义 Vue 组件。.vue
是一种特殊的文件格式,使我们能够将一个 Vue 组件的模板HTML、逻辑JS与样式CSS封装在单个文件中。
每一个 *.vue
文件都由三种顶层语言块构成:<template>
、<script>
和 <style>
,以及一些其他的自定义块。<template>
、<script>
和 <style>
三个块在同一个文件中封装、组合了组件的视图、逻辑和样式。
<template>
:用来写html代码,是组件的模板<script>
:写js代码,需要导出本组件的组件配置对象,在配置对象中定义这个组件中所需要的数据<style>
:写css样式,设置本组件模板中元素的样式
下面是一个单文件组件的示例:
<template>
<div id="app">
<Hello></Hello>
</div>
</template>
<script>
import Hello from './components/Hello.vue';
export default {
name: 'App',
components: {
Hello,
},
};
</script>
<style lang="scss" scoped>
#app{
background-color: '#eee';
}
</style>
script标签中是导出组件的配置对象options,是下面的简写
<script>
const App = Vue.extend({
name: 'App',
components: {},
});
export default App;
</script>
<template>
- 每个
*.vue
文件最多可以包含一个顶层<template>
块。 - 语块包裹的内容将会被提取、传递给
@vue/compiler-dom
,预编译为 JavaScript 渲染函数,并附在导出的组件上作为其render
选项。
<script>
- 每个
*.vue
文件最多可以包含一个<script>
块。 - 这个脚本代码块将作为 ES 模块执行。
- 默认导出应该是 Vue 的组件选项对象,可以是一个对象字面量或是 defineComponent 函数的返回值。
<style>
- 每个
*.vue
文件可以包含多个<style>
标签。 - 一个
<style>
标签可以使用scoped
或module
attribute来帮助封装当前组件的样式。使用了不同封装模式的多个<style>
标签可以被混合入同一个组件。
自动名称推导
SFC 在以下场景中会根据文件名自动推导其组件名:
- 开发警告信息中需要格式化组件名时;
- DevTools 中观察组件时;
- 递归组件自引用时。例如一个名为
FooBar.vue
的组件可以在模板中通过<FooBar/>
引用自己。(同名情况下) 这比明确注册/导入的组件优先级低。
预处理器
代码块可以使用 lang
这个 attribute 来声明预处理器语言,最常见的用例就是在 <script>
中使用 TypeScript:
<script lang="ts">
// use TypeScript
</script>
lang
在任意块上都能使用,比如我们可以在 <style>
标签中使用 SASS 或是 <template>
中使用 Pug:
<template lang="pug">
p {{ msg }}
</template>
<style lang="scss">
$primary-color: #333;
body {
color: $primary-color;
}
</style>
Src 导入
如果你更喜欢将 *.vue
组件分散到多个文件中,可以为一个语块使用 src
这个 attribute 来导入一个外部文件:
<template src="./template.html"></template>
<style src="./style.css"></style>
<script src="./script.js"></script>
请注意 src
导入和 JS 模块导入遵循相同的路径解析规则,这意味着:
- 相对路径需要以
./
开头 - 你也可以从 npm 依赖中导入资源
<!-- 从所安装的 "todomvc-app-css" npm 包中导入一个文件 -->
<style src="todomvc-app-css/index.css" />
注释
在每一个语块中你都可以按照相应语言 (HTML、CSS、JavaScript 和 Pug 等等) 的语法书写注释。对于顶层注释,请使用 HTML 的注释语法 <!-- comment contents here -->
快捷方式
"Vue单文件组件模板": {
"prefix": "govue",
"body": [
"<template>",
"\t<div class=\"$1\">",
"\t\t",
"\t</div>",
"</template>",
"",
"<script>",
"export default {",
"\tname:'$1'",
"}",
"</script>",
"",
"<style scoped lang=\"scss\">",
"",
"</style>",
],
"description": "Vue单文件组件模板"
}
风格指南
本项目的风格指南主要是参照 vue
官方的风格指南。在真正开始使用该项目之前建议先阅读一遍指南,这能帮助让你写出更规范和统一的代码。当然每个团队都会有所区别。其中大部分规则也都配置在了eslint-plugin-vue之中,当没有遵循规则的时候会报错。
当然也有一些特殊的规范,是不能被 eslint 校验的。需要人为的自己注意,并且来遵循。最主要的就是文件的命名规则。
Component
所有的Component
文件都是以大写开头 (PascalCase),这也是官方所推荐的。
但除了 index.vue
。
例子:
@/components/BackToTop/index.vue
@/components/Charts/Line.vue
@/views/search/components/Item.vue
JS 文件
所有的.js
文件都遵循横线连接 (kebab-case)。
例子:
@/utils/open-window.js
@/views/svg-icons/require-icons.js
@/components/MarkdownEditor/default-options.js
Views
在views
文件下,代表路由的.vue
文件都使用横线连接 (kebab-case),代表路由的文件夹也是使用同样的规则。
例子:
@/views/svg-icons/index.vue
@/views/svg-icons/require-icons.js
使用横线连接 (kebab-case)来命名views
主要是出于以下几个考虑。
- 横线连接 (kebab-case) 也是官方推荐的命名规范之一 文档
views
下的.vue
文件代表的是一个路由,所以它需要和component
进行区分(component 都是大写开头)- 页面的
url
也都是横线连接的,比如https://www.xxx.admin/export-excel
,所以路由对应的view
应该要保持统一 - 没有大小写敏感问题
HTML 和静态资源
HTML
Index 文件
public/index.html
文件是一个会被 html-webpack-plugin 处理的模板。在构建过程中,资源链接会被自动注入。
插值
因为 index 文件被用作模板,所以你可以使用 lodash template 语法插入内容:
<%= VALUE %>
用来做不转义插值;<%- VALUE %>
用来做 HTML 转义插值;<% expression %>
用来描述 JavaScript 流程控制。
除了被 html-webpack-plugin
暴露的默认值之外,所有客户端环境变量也可以直接使用。例如,BASE_URL
的用法:
<link rel="icon" href="<%= BASE\_URL %>favicon.ico">
处理静态资源
静态资源可以通过两种方式进行处理:
- 在 JavaScript 被导入或在 template/CSS 中通过相对路径被引用。这类引用会被 webpack 处理。
- 放置在
public
目录下或通过绝对路径被引用。这类资源将会直接被拷贝,而不会经过 webpack 的处理。
从相对路径导入
当你在 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') }})
在其内部,我们通过 webpack 的 Assets Modules 配置,用版本哈希值和正确的公共基础路径来决定最终的文件路径,并将小于 8KiB 的资源内联,以减少 HTTP 请求的数量。
URL 转换规则
- 如果 URL 是一个绝对路径 (例如
/images/foo.png
),会原样保留。 - 如果 URL 以
.
开头,将会被看作相对的模块依赖,并按照你的本地文件系统上的目录结构进行解析。 - 如果 URL 以
~
开头,其后的部分将会被看作模块依赖。这意味着你可以用该特性来引用一个 Node 依赖中的资源:
<img src="~some-npm-package/foo.png">
- 如果 URL 以
@
开头,也会被看作模块依赖。如果你的 webpack 配置中给@
配置了 alias,这就很有用了。所有vue-cli
创建的项目都默认配置了将@
指向<projectRoot>/src
。 (仅作用于模版中)
public
文件夹
任何放置在 public
文件夹的静态资源都会被简单的复制,而不经过 webpack。你需要通过绝对路径来引用它们。
注意我们推荐将资源作为你的模块依赖图的一部分导入,这样它们会通过 webpack 的处理并获得如下好处:
- 脚本和样式表会被压缩且打包在一起,从而避免额外的网络请求。
- 文件丢失会直接在编译时报错,而不是到了用户端才产生 404 错误。
- 最终生成的文件名包含了内容哈希,因此你不必担心浏览器会缓存它们的老版本。
public
目录提供的是一个应急手段,当你通过绝对路径引用它时,留意应用将会部署到哪里。如果你的应用没有部署在域名的根部,那么你需要为你的 URL 配置 publicPath 前缀:
- 在
public/index.html
或其它通过html-webpack-plugin
用作模板的 HTML 文件中,你需要通过<%= BASE_URL %>
设置链接前缀:
<link rel="icon" href="<%= BASE\_URL %>favicon.ico">
- 在模板中,你首先需要向你的组件传入基础 URL:
data () {
return {
publicPath: process.env.BASE\_URL
}
}
然后:
<img :src="`${publicPath}my-image.png`">
何时使用 public
文件夹
- 你需要在构建输出中指定一个文件的名字。
- 你有上千个图片,需要动态引用它们的路径。
- 有些库可能和 webpack 不兼容,这时你除了将其用一个独立的
<script>
标签引入没有别的选择。
使用图片资源
执行 npm run serve 会把vue项目在内存中打包。
执行 npm run build 会把vue项目打包到dist文件内。
图片资源要放在 assets 或者 pubilc 中。
放在public中
放在pubilc中,打包的时候会直接复制pubilc中的图片,放在pubilc中的图片相当于放在服务器根目录的资源
- 在组件中使用:
<template>
、<script>
都是使用 /开头,比如 /img/icon-home.png
<template>
<div>
<img src="/img/head.png" alt="" />
<img :src="imgUrl" alt="" />
<img :src="`${publicPath}img/head.png`">
<div class="box" style="background-image:url('/img/head.png');">box</div>
<div class="box" :style="{background:'url('+ imgUrl +')'}">box</div>
</div>
</template>
<script>
// 在模板中,你首先需要向你的组件传入基础 URL:
export default {
data () {
return {
imgUrl:'/img/head.png',
// process.env 属性返回的是一个包含用户环境信息的对象
// process.env.BASE_URL 获取基础路径
// process.env.NODE_ENV 获取开发环境
publicPath: process.env.BASE_URL
}
}
}
</script>
放在assets中
assets中,打包的时候会把图片经过webpack处理,把图片当做一个模块
- 在
<template>
中使用,可以使用 ./ 或者 …/ 开头的路径,比如:./img/home.png - 在
<script>
中,可以使用 import 导入的方式,导入之后需要在data或者computed中定义变量接收 - 在
<style>
中使用,可以使用 ./ 或者 …/ 开头的路径,比如:./img/home.png
路径别名@:@ 在vue-cli中是指向 <projectRoot>/src
的别名
<template>
<div>
<img alt="Vue logo" src="@/assets/logo.png" />
<img alt="Vue logo" src="./assets/logo.png" />
<img :src="imgurl" alt="" />
<img :src="img" alt="" />
<div :style="{background:'url('+imgurl+')'}">box2</div>
</div>
</template>
<script>
import timg from '@/assets/img/timg.jpg'; //导入图片
export default {
name: 'App',
data() {
return {
imgurl: timg,
img: require('@/assets/logo.png')
};
},
}
</script>
<style>
div{
background-image: url('./assets/img/timg.jpg');
}
</style>
使用CSS
引用静态CSS资源
- 所有编译后的 CSS 都会通过 css-loader 来解析其中的
url()
引用,并将这些引用作为模块请求来处理。 - 可以根据本地的文件结构用相对路径来引用静态资源。
// main.js
// 引入本地静态资源
import '@/styles/base.scss';
import '@/styles/base.css';
CSS预处理器
使用sass
- 安装模块
npm install -D sass-loader sass
- 在style标签中添加 lang=“scss”,注意是 ‘scss’ 不是 ‘sass’
<style lang="scss">
</style>
使用less
- 安装模块
npm install -D less-loader less
- 在style标签上添加 lang=“less”
<style lang="less">
</style>
其他
使用less或者sass的时候如果报错:this.getOptions is not a function 原因:
- sass中 sass-loader安装的的版本过高,解决:重新安装较低版本
npm uninstall sass-loader -D
npm uninstall node-sass -D
npm install sass-loader@10.1.1 -D
npm install node-sass@5.00 -D
- less中 less-loader 版本过高,解决:重新安装较低版本
npm uninstall less-loader -D
npm install less-loader@5.0.0 -D
组件的样式 Scoped
当 style 标签有 scoped 属性时,它的 CSS 只作用于当前组件中的元素。这类似于 Shadow DOM 中的样式封装。它有一些注意事项,但不需要任何 polyfill。它通过使用 PostCSS 来实现以下转换:
<style scoped>
.example {
color: red;
}
</style>
<template>
<div class="example">hi</div>
</template>
转换结果:
### 文末
我一直觉得技术面试不是考试,考前背背题,发给你一张考卷,答完交卷等通知。
首先,技术面试是一个 认识自己 的过程,知道自己和外面世界的差距。
更重要的是,技术面试是一个双向了解的过程,要让对方发现你的闪光点,同时也要 试图去找到对方的闪光点,因为他以后可能就是你的同事或者领导,所以,面试官问你有什么问题的时候,不要说没有了,要去试图了解他的工作内容、了解这个团队的氛围。
**前端面试题汇总**

**JavaScript**
**[开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】](https://bbs.youkuaiyun.com/forums/4304bb5a486d4c3ab8389e65ecb71ac0)**

**性能**

**linux**

**前端资料汇总**
