代码下载
模块化相关规范
传统开发模式的主要问题:命名冲突、文件依赖。
模块化就是把单独的一个功能封装到一个模块(文件)中,模块之间相互隔离,但是可以通过特定的接口公开内部成员,也可以依赖别的模块,好处就是:方便代码的重用,从而提升开发效率,并且方便后期的维护。
模块化的分类
浏览器端的模块化:
- AMD(Asynchronous Module Definition,异步模块定义),代表产品为:Require.js(http://www.requirejs.cn/)
- CMD(Common Module Definition,通用模块定义),代表产品为:Sea.js(https://seajs.github.io/seajs/docs/)
服务器端的模块化
服务器端的模块化是使用CommonJS规范:
- 使用require引入其他模块或者包
- 使用exports或者module.exports导出模块成员
- 一个文件就是一个模块,都拥有独立的作用域
大一统的模块化规范 -- ES6模块化
ES6 语法规范中,在语言层面上定义了 ES6 模块化规范,是浏览器端与服务器端通用的模块化开发规范,ES6模块化规范中定义:
- 每一个js文件都是独立的模块
- 导入模块成员使用import关键字
- 暴露模块成员使用export关键字
Node.js 中通过 babel 体验 ES6 模块化
1、安装babel,在终端依次执行如下命令,安装相应包:
npm install --save-dev @babel/core @babel/cli @babel/preset-env @babel/node
npm install --save @babel/polyfill
2、创建babel.config.js,在项目目录中创建babel.config.js文件,编辑js文件中的代码如下:
const presets = [
["@babel/env",{
targets:{
edge:"17",
firefox:"60",
chrome:"67",
safari:"11.1"
}
}]
]
//暴露
module.exports = { presets }
3、创建index.js文件,在项目目录中创建index.js文件作为入口文件,在index.js中输入需要执行的js代码:
console.log("ok");
4、使用npx执行文件,打开终端,输入命令:
npx babel-node index.js
ES6 模块化基本语法
默认导出 与 默认导入:
默认导出语法 export default 默认导出的成员,新建m1模块,导出如下内容:
let a = 1;
let b = 2;
let c = 3;
function show() {
console.log('show');
}
export default {
a, b, show
};
默认导入语法 import 接收名称 from '模块标识符',在index.js中导入m1模块:
import m1 from "./m1";
console.log(m1);
// 输出:{ a: 1, b: 2, show: [Function: show] }
**注意:在一个模块中,只允许使用export default向外默认暴露一次成员,千万不要写多个export default,这样会报错。如果在一个模块中没有向外暴露成员,其他模块引入该模块时将会得到一个空对象 **
按需导出 与 按需导入
按需导出语法 export let s1 = 10
export let name = '张三';
export let age = 18;
export function say() {
console.log('hello!');
}
按需导入语法 import { s1 } from '模块标识符'
import { name, age, say } from "./m1";
console.log(name);
console.log(age);
console.log(say);
/* 输出:
张三
18
[Function: say]
*/
注意:每个模块中可以使用多次按需导出。一个模块中既可以按需导入也可以默认导入,一个模块中既可以按需导出也可以默认导出。
直接导入并执行模块代码
有时候,只想单纯执行某个模块中的代码,并不需要得到模块中向外暴露的成员,此时,可以直接导入并执行模块代码。
新建 m2 模块:
console.log('hello world!');
直接导入并执行模块代码:
import "./m2";
// 输出:hello world!
webpack
当前 Web 开发面临的困境:
- 文件依赖关系错综复杂
- 静态资源请求效率低
- 模块化支持不友好
- 浏览器对高级 Javascript 特性兼容程度较低
- etc...
webpack 是一个流行的前端项目构建工具(打包工具),可以解决当前 web 开发中所面临的困境。
webpack 提供了友好的模块化支持,以及代码压缩混淆、处理 js 兼容问题、性能优化等强大的功能,从而让程序员把工作的重心放到具体的功能实现上,提高了开发效率和项目的可维护性。
webpack 的基本使用
创建项目
1、新建项目空白目录,并运行 npm init --y 命令,初始化包管理配置文件 package.json
2、新建 src 源代码目录;新建 src -> index.html 首页;初始化首页基本的结构
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
<li>11</li>
<li>12</li>
<li>13</li>
<li>14</li>
<li>15</li>
<li>16</li>
<li>17</li>
<li>18</li>
<li>19</li>
<li>20</li>
</ul>
3、运行 npm install jquery --S 命令,安装 jQuery,创建index.js文件,通过模块化的形式,实现列表隔行变色效果
import $ from 'jQuery'
$(function(){
$('li:odd').css('backgroundColor', 'red');
$('li:even').css('backgroundColor', 'green');
})
注意:此时项目运行会有错误,因为import $ from "jquery";这句代码属于ES6的新语法代码,在浏览器中可能会存在兼容性问题,所以需要webpack来帮助解决这个问题。
在项目中安装和配置 webpack
1、运行 npm install webpack webpack-cli -D 命令,安装 webpack 相关的包
2、在项目根目录中,创建名为 webpack.config.js 的 webpack 配置文件,初始化如下基本配置:
module.exports = {
mode: 'development' // mode 用来指定构建模式,可以设置为development(开发模式),production(发布模式)
}
mode设置的是项目的编译模式
- 如果设置为development则表示项目处于开发阶段,不会进行压缩和混淆,打包速度会快一些;
- 如果设置为production则表示项目处于上线发布阶段,会进行压缩和混淆,打包速度会慢一些。
3、在 package.json 配置文件中的 scripts 节点下,新增 dev 脚本如下:
"scripts": {
"dev": "webpack"
}
注意:scripts节点下的脚本,可以通过 npm run 运行,如运行终端命令 npm run dev
将会启动webpack进行项目打包
4、在终端中运行 npm run dev 命令,启动 webpack 进行项目打包。等待webpack打包完毕之后,找到默认的dist路径中生成的main.js文件,将其引入到html页面中:
<script src="../dist/main.js"></script>
配置打包的入口与出口
在webpack 5.x中,默认会将src/index.js 作为默认的打包入口js文件,默认会将dist/main.js 作为默认的打包输出js文件。如果不想使用默认的入口/出口js文件,可以通过改变 webpack.config.js 来设置入口/出口的js文件,如下:
const path = require('path');
module.exports = {
mode: 'development', // mode 用来指定构建模式,可以设置为development(开发模式),production(发布模式)
// 设置入口文件路径
entry: path.join(__dirname, './src/index.js'),
// 设置出口文件
output: {
path: path.join(__dirname, './dist'),
filename: 'res.js'
}
}
配置 webpack 的自动打包
1、运行 npm install webpack-dev-server -D 命令,安装支持项目自动打包的工具,并在 webpack.config.js 中向外暴露的配置对象新增如下配置节点:
module.exports = {
devServer: {
static: __dirname,//根目录,需要点击进入src才能查看
// static: path.join(__dirname, 'src'),//可以直接访问到src页面,实现页面的实时查看。
// host: "localhost", // 服务器域名
// port: 8080, // 服务器端口号
// open: true// 是否自动打开浏览器
}
}
2、修改 package.json -> scripts 中的 dev 命令如下:
"scripts": {
"dev": "webpack-dev-server" // script 节点下的脚本,可以通过 npm run 执行
}
配置自动打包相关的参数:
-
--open 打包完成后自动打开浏览器页面
-
--host 配置 IP 地址
-
--port 配置端口
"scripts": {
"dev": "webpack-dev-server --open --host 127.0.0.1 --port 8888"
}
3、将 src -> index.html 中,script 脚本的引用路径修改为 /res.js
:
<script src="/res.js"></script>
4、运行 npm run dev 命令,重新进行打包
5、在浏览器中访问 http://localhost:8080 地址,查看自动打包效果
注意:
- webpack-dev-server 会启动一个实时打包的 http 服务器
- webpack-dev-server 打包生成的输出文件,默认放到了项目根目录中,而且是虚拟的、看不见的
配置 html-webpack-plugin 生成预览页面
运行 npm install html-webpack-plugin -D 命令,安装生成预览页面的插件
修改 webpack.config.js 文件头部区域,添加如下配置信息:
// 导入生成预览页面的插件,得到一个构造函数
const HtmlWebpackPlugin = require('html-webpack-plugin')
const htmlPlugin = new HtmlWebpackPlugin({ // 创建插件的实例对象
template: './src/index.html', // 指定要用到的模板文件
filename: 'index.html' // 指定生成的文件的名称,该文件存在于内存中,在目录中不显示
})
修改 webpack.config.js 文件中向外暴露的配置对象,新增如下配置节点:
module.exports = {
plugins: [ htmlPlugin ] // plugins 数组是 webpack 打包期间会用到的一些插件列表
}
webpack中的加载器
默认webpack只能打包js文件,如果想要打包非js文件,需要调用loader加载器才能打包,loader 加载器可以协助 webpack 打包处理特定的文件模块。
注意:指定多个loader时的顺序是固定的,而调用loader的顺序是从后向前进行调用
打包处理 css 文件
1、运行 npm i style-loader css-loader -D 命令,安装处理 css 文件的 loader
2、在 webpack.config.js 的 module -> rules 数组中,添加 loader 规则如下:
module.exports = {
// 所有第三方文件模块的匹配规则
module: {
rules: [
{ test: /\.css$/, use: ['style-loader', 'css-loader'] }
]
}
}
3、在 src 目录中新建 css 目录,创建 1.css
文件,初始化如下:
ul {
list-style: none;
}
4、在 index.js 中导入 css:
import './css/1.css'
其中,test 表示匹配的文件类型, use 表示对应要调用的 loader;use 数组中指定的 loader 顺序是固定的,多个 loader 的调用顺序是:从后往前调用。
打包处理 less 文件
1、运行 npm i less-loader less -D 命令
2、在 webpack.config.js 的 module -> rules 数组中,添加 loader 规则如下:
module: {
rules: [
{ test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] }
]
}
3、在css 目录,创建 1.less
文件,初始化如下:
body {
margin: 0;
padding: 0;
ul {
margin: 0;
padding: 0;
}
}
4、在 index.js 中导入 less:
import './css/1.less'
打包处理 scss 文件
运行 npm i sass-loader node-sass -D 命令
在 webpack.config.js 的 module -> rules 数组中,添加 loader 规则如下:
module: {
rules: [
{ test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader'] }
]
}
3、在css 目录,创建 1.scss
文件,初始化如下:
body {
margin: 0;
padding: 0;
ul {
margin: 0;
padding: 0;
}
}
4、在 index.js 中导入 scss:
import './css/1.scss'
配置 postCSS 自动添加 css 的兼容前缀(-ie-,-webkit-)
1、运行 npm i postcss-loader autoprefixer -D 命令
2、在项目根目录中创建 postcss 的配置文件 postcss.config.js,并初始化如下配置:
const autoprefixer = require('autoprefixer') // 导入自动添加前缀的插件
module.exports = {
plugins: [ autoprefixer ] // 挂载插件
}
3、在 webpack.config.js 的 module -> rules 数组中,修改 css 的 loader 规则如下:
module: {
rules: [
{ test:/\.css$/, use: ['style-loader', 'css-loader', 'postcss-loader'] }
]
}
4、在 index.html 中增加如下代码:
<input type="text" placeholder="请输入姓名...">
5、在 css -> 1.css
文件中增加如下样式:
::placeholder {
color: red;
}
打包样式表中的图片和字体文件
过去在webpack4中,处理图片资源通过file-loader和url-loader进行处理:
1、运行 npm i url-loader file-loader -D 命令
2、在 webpack.config.js 的 module -> rules 数组中,添加 loader 规则如下:
module: {
rules: [
{ test: /\.jpg|png|gif|bmp|ttf|eot|svg|woff|woff2$/, use: 'url-loader?limit=16940' }
]
}
其中 ? 之后的是 loader 的参数项。limit 用来指定图片的大小,单位是字节(byte),只有小于 limit 大小的图片,才会被转为 base64 图片。
webpack5已经将两个loader功能内置到webpack中了,只需要简单配置即可处理图片资源:
1、在 webpack.config.js 的 module -> rules 数组中,添加规则如下:
module: {
rules: [
{ test: /\.jpg|png|gif|bmp|ttf|eot|svg|woff|woff2$/,
type: 'asset', // 这里使用asset相当于就是webpack4中使用了url-loader来处理
parser: {
dataUrlCondition: {
maxSize: 16941 // 小于16941字节的图片会被base64处理
}
}
}
]
}
注意:type: 'asset/resource'
是Webpack 5的一个新特性,它取代了以往的 file-loader 和 url-loader
2、在 index.html 中增加如下代码:
<div class="box"></div>
3、在 css -> 1.css
文件中增加如下样式:
.box {
width: 580px;
height: 340px;
background-color: red;
background: url('../images/1.jpg');
}
打包处理 js 文件中的高级语法
1、安装babel转换器相关的包:npm i babel-loader @babel/core @babel/runtime -D
2、安装babel语法插件相关的包:npm i @babel/preset-env @babel/plugin-transform-runtime @babel/plugin-proposal-class-properties -D
3、在项目根目录中,创建 babel 配置文件 babel.config.js 并初始化基本配置如下:
module.exports = {
presets: [ '@babel/preset-env' ],
plugins: [ '@babel/plugin-transform-runtime', '@babel/plugin-proposal-class-properties' ]
}
4、在 webpack.config.js 的 module -> rules 数组中,添加 loader 规则如下:
// exclude 为排除项,表示 babel-loader 不需要处理 node_modules 中的 js 文件
{ test: /\.js$/, use: 'babel-loader', exclude: /node_modules/ }
5、在 index.js 中增加如下代码:
class Person {
static info = 'aaa'
}
console.log(Person.info);
Vue 单文件组件
传统Vue组件的缺陷:
- 全局定义的组件必须保证组件的名称不重复
- 字符串模板缺乏语法高亮,在 HTML 有多行的时候,需要用到丑陋的 \
- 不支持 CSS 意味着当 HTML 和 JavaScript 组件化时,CSS 明显被遗漏
- 没有构建步骤限制,只能使用 HTML 和 JavaScript, 而不能使用预处理器(如:Babel)
针对传统组件的问题,Vue 提供了一个解决方案 ------ 使用 Vue 单文件组件。使用Vue单文件组件,每个单文件组件的后缀名都是.vue,每一个Vue单文件组件都由三部分组成:
- template组件组成的模板区域
- script组成的业务逻辑区域
- style样式区域
新建 src -> components 目录,并于 components 目录新建 app.vue 单文件组件:
<template>
<!-- 这里用于定义Vue组件的模板内容 -->
<div>
<h1>我是 VUE 组件</h1>
<p>姓名:{{name}},年龄:{{age}}</p>
</div>
</template>
<script>
// 这里用于定义Vue组件的业务逻辑
export default {
data: function() {
return {
name: '张三',
age: 18
}
},
methods: {}
}
</script>
<style scoped>
/* 这里用于定义组件的样式 */
h1 {
color: red;
}
p {
color: cyan;
}
</style>
补充:安装Vetur插件可以使得.vue文件中的代码高亮
webpack 中配置 vue2 组件的加载器
1、运行 npm i vue-loader@15.x vue-template-compiler -D 命令,(注:Vue2不支持vue-loader 16+以上的版本 )
2、在 webpack.config.js 配置文件中,添加 vue-loader 的配置项如下:
const { VueLoaderPlugin } = require('vue-loader')
module.exports = {
module: {
rules: [
// ... 其它规则
{ test: /\.vue$/, loader: 'vue-loader' }
]
},
plugins: [
// ... 其它插件
new VueLoaderPlugin() // 请确保引入这个插件!
]
}
在 webpack 项目中使用 vue
1、运行 npm i vue@2.x -S 安装 vue2
2、在 src -> index.js 入口文件中,通过 import Vue from 'vue' 来导入 vue 构造函数,并引入 VUE 单文件组件 app.vue
:
import Vue from 'vue'
import App from './components/app.vue'
3、创建 vue 的实例对象,并指定要控制的 el 区域,通过 render 函数渲染 App 根组件:
const vm = new Vue({
el: '#app',
render: h => h(App)
})
h => h(App)
中 => 是 es6 的箭头函数语法。但是h跟踪源码后发现 h 是 createElement 函数的别名。由于箭头函数只有一个形参可以省略小括号;函数体中只有一句代码且代码的执行结果就是返回值可以省略大括号,于是上面的写法等价于:
function(createElement){
return creatElemnt(App);
}
webpack 打包发布
上线之前需要通过webpack将应用进行整体打包,可以通过 package.json 文件配置打包命令:
"scripts": {
"build": "webpack"
}
在项目打包之前,可以将dist目录删除,执行 npm run build 命令生成全新的dist目录
Vue 脚手架
Vue 脚手架用于快速生成 Vue 项目基础架构,其官网地址为:https://cli.vuejs.org/zh/
安装 Vue 脚手架:
npm install -g @vue/cli
查看版本号,确认是否安装成功:
vue -V
基于脚手架创建vue项目
1、基于 交互式命令行 的方式,创建 vue 项目
- 命令:vue create my-project
- 选择Manually select features(选择特性以创建项目)
- 勾选特性可以用空格进行勾选3项:Babel, Router, Linter / Formatter
- 选择版本 2.x
- 是否选用历史模式的路由:n
- ESLint选择:ESLint + Standard config
- 何时进行ESLint语法校验:Lint on save
- Babel,ESLint等配置文件如何放置:In dedicated config files(单独使用文件进行配置)
- 是否保存为模板:n
2、基于 图形化界面 的方式,创建 vue 项目
- 执行 vue ui 命令,打开 http://localhost:8000 页面
- 选择目录创建新项目,填写项目名称,点击下一步
- 选择一套预设,手动或默认,点击下一步
- 选择功能,开启 Babel、Router,Linter / Formatter,使用配置文件,点击下一步
- 选择配置,选择 2.x vue 版本,关闭使用历史模式路由,选择 ESLint + Standard config 配置文件,开启 Lint on save,点击创建项目
- 填写预设名,点击保存预设并创建项目
- 默认进入项目仪表盘,还有 插件、依赖、配置、任务面板;点击项目名称可以看到在编辑器中打开、重命名、Vue 项目管理器列表
- 进入任务面板,点击运行按钮,等待运行完毕,点击启动app就可以查看项目效果了
Vue 脚手架生成的项目结构分析
结构 | 说明 |
---|---|
node_modules | 依赖包目录 |
public | 静态资源目录 |
src | 源码目录 |
src/assets | 资源目录 |
src/components | 组件目录 |
src/views | 视图组件目录 |
src/App.vue | 根组件 |
src/main.js | 入口js |
src/router.js | 路由js |
babel.config.js | babel配置文件 |
vue.config.js | vue配置文件 |
.eslintrc.js | lint配置文件 |
Vue 脚手架的自定义配置
脚手架5.x之后,项目搭建时,vue.config.js会自动创建,写法如下:
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,
// publicPath: '/', // 启动页地址
// outputDir: 'dist', // 打包的目录
// lintOnSave: true, // 在保存时校验格式
// productionSourceMap: false, // 生产环境是否生成 SourceMap
devServer: {
host: 'localhost', // 主页地址
port: 8888, // 端口号
open: true, // 自动打开浏览器访问主页
// proxy: null, // 设置代理
}
})
Element-UI
Element-UI:一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库。官网地址为: http://element-cn.eleme.io/#/zh-CN
基于命令行方式手动安装
1、安装依赖包 npm install --legacy-peer-deps element-ui --save
2、导入 Element-UI 相关资源
// 导入组件库
import ElementUI from 'element-ui';
// 导入组件相关样式
import 'element-ui/lib/theme-chalk/index.css';
// 配置 Vue 插件
Vue.use(ElementUI);
3、src -> app.vue 文件中添加 Element-UI 元素:
<el-row>
<el-button>默认按钮</el-button>
<el-button type="primary">主要按钮</el-button>
<el-button type="success">成功按钮</el-button>
<el-button type="info">信息按钮</el-button>
<el-button type="warning">警告按钮</el-button>
<el-button type="danger">危险按钮</el-button>
</el-row>
4、运行 npm run serve时会报错,修改 vue.config.js 文件 lintOnSave: false
基于图形化界面自动安装
1、运行 vue ui 命令,打开图形化界面,通过 Vue 项目管理器,进入具体的项目配置面板
2、点击 插件 -> 添加插件,进入插件查询面板,搜索 vue-cli-plugin-element 并安装
3、配置插件,选择按需导入从而减少打包后项目的体积,点击完成安装
4、点击 任务 -> serve -> 运行 -> 启动app