【Vue】Vue基础教程(5)
前言:
本文内容:webpack学习使用、vue-router路由、vue+elementUI
推荐免费Vue基础教程视频:[【狂神说Java】Vue最新快速上手教程通俗易懂_哔哩哔哩_bilibili
webpack学习使用
什么是Webpack
本质上,webpack是一个JavaScript应用程序的静态模块打包器(module bundler)。当webpack处理应用程序时,他会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有模块打包成一个或多个bundle
。
Webpack是当下最热门的前端资源模块化管理和打包工具,它可以将许多松散耦合的模块按照依赖和规则打包成符合生产环境部署的前端资源。
模块化的演进
Script标签
1 | <script src="modeule.js"></script> |
这是最原始的JavaScript文件加载方式,如果把每一个文件看作是一个模块,那么他们的接口通常是暴露在全局作用域下
,也就是定义来window对象中,不同模块的调用都是一个作用域。
原始加载方式的弊端:
- 全局作用域下容易造成变量冲突
- 文件只能按照
<script>
的书写顺序进行加载 - 开发人员必须主观解决模块和代码库的依赖关系
- 在大型项目中各种资源难以管理,长期积累的问题导致代码库混乱
CommonsJS
服务器端的NodeJS遵循CommonsJS规范,该规范核心思想是允许模块通过require方法来同步加载所需依赖的其他模块,然后通过exports或module。exports来导出需要暴漏的接口。
1 | require("module"); |
优点
- 服务器端模块便于复用
- npm中大量的模块包可以使用
缺点:
- 同步的模块加载方式不适合在浏览器环境中,同步意味着阻塞加载,浏览器资源是异步加载的
- 不能非阻塞的并行加载多个模块
实现:
- 服务端的NodeJS
- Browserify,浏览器端的CommonsJS实现,可以使用npm的模块,但是编译打包后的文件体积较大
- modules-webmake,类似Browserify,但不如Browserify灵活
- wreq,Browserify的前身
AMD
Asynchronous Module Definition规范其实主要是一个接口define(id?,dependencies?,factory);它要在声明模块的时候指定所有的依赖dependencies,并且还要当作形参传到factory中,对于依赖的模块提前执行。
1 | define("module",["dep1","dep2"],function(d1,d2){ |
优点:
- 适合在浏览器环境中异步加载模块
- 可以并行加载多个模块
缺点:
- 提高了开发成本,代码的阅读和书写比较困难,模块定义方式的语义不畅
- 不符合通用的模块化思维方式
实现
- RequireJS
- curl
CMD
Commons Module Definition 规范和AMD很相似,尽量保持简单,并于CommonsJS和NodeJS的Modules规范保持了很大的兼容性。
1 | define(function(require,exports,module){ |
优点:
- 依赖就近,延迟执行
- 可以很容易在NodeJS中运行
缺点:
- 依赖SPM打包,模块的加载逻辑片中
实现:
- Sea.js
- coolie
ES6模块
EcmaScript6标准增加了JavaScript语言层面的模块体系定义。ES6模块的设计思想,是尽量静态化,使编译时就能确定模块的依赖关系,以及输入和输出的变量。CommonsJS和AMD模块,都只能在运行时确定这些东西。
1 | import "jQuery"; |
优点:
- 容易进行静态分析
- 面向未来的EcmaScript标准
缺点:
- 原生浏览器端还没实现该标准
- 全新的命令,新版的NodeJS才支持
实现:
- Babel
大家期望的模块系统
可以兼容多种模块风格,尽量可以利用已有的代码,不仅仅是JavaScript的模块化,还有CSS,图片,文字等资源也需要模块化。
安装Webpack
Webpack是一款模块加载器兼打包工具,它能把各种资源,如JS,JSX,ES6,SASS,LESS,图片等都作为模块来处理和使用。
安装
1 | npm install webpack -g |
测试是否安装成功
webpack -v
webpack-cli -v
配置
创建webpack.config.js配置文件
- entry:入口文件,指定Webpack用哪个文件作为项目的入口
- output:输出,指定Webpack把处理完成的文件放到指定路径
- module:模块,用于处理各种类型的文件
- plugins:插件,如:热更新,代码重用等
- resolve:设置路径指向
- watch:监听,用于设置文件改动后直接打包
直接运行webpack
命令打包
如果运行webpack提示没安装webpack-cli,可以先运行webpack-cli,根据提示安装webpack即可
使用Webpack
-
创建项目
webpack-study
-
创建一个名为modules的目录,用于放置JS模块等资源文件
-
在modules下创建模块文件,如hello.js,用于编写JS模块相关代码
1
2
3
4;// 暴露一个方法
exports.sayHi = function(){
document.write("<h1>Jokerdig.com</h1>");
}; -
在modules下创建一个名为main.js的入口文件,用于打包时设置entry属性
1
2let hello = require("./hello");
hello.sayHi(); -
在项目目录下创建webpack.config.js配置文件,使用webpack命令打包
1
2
3
4
5
6module.exports = {
entry: './modules/main.js',
output: {
filename: "./js/bundle.js"
}
}; -
打包后的代码
1
(()=>{var r={645:(r,o)=>{o.sayHi=function(){document.write("<h1>Jokerdig.com</h1>")}}},o={};(function t(e){var i=o[e];if(void 0!==i)return i.exports;var n=o[e]={exports:{}};return r[e](n,n.exports,t),n.exports})(645).sayHi()})();
-
新建index.html,运行测试
1
2
3
4
5
6
7
8
9
10
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script src="dist/js/bundle.js"></script>
</body>
</html> -
运行结果
webpack --watch 监听打包
vue-router路由
说明
Vue Router是Vue.js官方的路由管理器,它和Vue.js的核心深度集成,让构建单页面应用变得简单。包含的功能:
- 嵌套的路由、是图标
- 模块化的、基于组件的路由配置
- 路由参数、查询、通配符
- 基于Vue.js过度系统的视图过渡效果
- 细粒度的导航控制
- 带有自动激活的CSS class的链接
- HTML5历史模式或hash模式,在IE9中自动降级
- 自定义的滚动条行为
安装
基于第一个vue-cli
进行测试学习
vue-router是一个插件包,通过命令进行安装
注意 3.x版本的vue-router对应vue2.x版本,4.x版本的vue-router对应vue3.x版本,版本不对应会有不兼容的问题;
1 | # 安装 默认安装新版本 |
如果一个模块化工程中使用它,必须要通过Vue.use()明确地安装路由功能
1 | import Vue from 'vue' |
测试
使用之前创建的myvue
进行测试
-
安装
vue-router
-
整理项目,删除多余内容
App.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22<template>
<div id="app">
<h1>Jokerdig.com</h1>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>main.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14import Vue from 'vue'
import App from './App'
import VueRouter from 'vue-router'
Vue.config.productionTip = false
// 显示声明使用VueRouter
Vue.use('VueRouter');
new Vue({
el: '#app',
components: { App },
template: '<App/>'
}) -
使用
npm run dev
进行测试Your application is running here: http://localhost:8089
添加内容后数据直接更新,并不需要刷新页面(称为热部署)
1
2浏览器显示:
Jokerdig.com
组件练习
-
新建
router
文件夹,在文件夹下新建index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28import Vue from 'vue'
import VueRouter from "vue-router";
import Content from '../components/Content'
import Main from '../components/Main'
Vue.use(VueRouter);
// 导出配置路由
export default new VueRouter({
routes: [
{
// 路由路径
path: '/content',
name: 'content',
// 跳转组件
component: Content
},
{
// 路由路径
path: '/main',
name: 'main',
// 跳转组件
component: Main
}
]
}); -
在
components
文件夹下新建Content.vue
和Main.vue
Content.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14<template>
<h1>这是内容页面哦</h1>
</template>
<script>
export default {
name: "Content"
}
</script>
<style scoped>
</style>Main.vue
1
2
3
4
5
6
7
8
9
10
11
12
13<template>
<h1>首页</h1>
</template>
<script>
export default {
name: "Main"
}
</script>
<style scoped>
</style> -
修改
App.vue
和main.js
App.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27<template>
<div id="app">
<h1>Vue-Router练习</h1>
<router-link to="/main">跳首页</router-link>
<router-link to="/content">跳内容页</router-link>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>main.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14import Vue from 'vue'
import App from './App'
import router from './router' // 自动扫描路由配置
Vue.config.productionTip = false
new Vue({
el: '#app',
// 配置路由
router,
components: { App },
template: '<App/>'
}) -
运行测试
1
2
3Vue-Router练习
跳首页 跳内容页
这是内容页面哦
vue+elementUI
实现步骤
-
创建名为hello-vue的工程,初始化
vue init webpack hello-vue
1
2
3
4
5
6
7
8
9
10
11? Project name hello-vue
? Project description A Vue.js project
? Author JokerDaxiong
? Vue build standalone
? Install vue-router? No
? Use ESLint to lint your code? No
? Set up unit tests No
? Setup e2e tests with Nightwatch? No
? Should we run `npm install` for you after the project has been created? (recommended) no
vue-cli · Generated "hello-vue". -
安装依赖,我们需要安装
vue-router
、element-ui
、sass-loader
和node-sass
四个插件1
2
3
4
5
6
7
8
9
10
11
12# 进入工程目录
cd hello-vue
# 安装 vue-router
npm install vue-router@3.5.2 --save-dev
# 安装 element-ui
npm install element-ui -S
# 安装依赖
npm install
# 安装 SASS架加载器 如果使用npm安装报错可以使用cnpm安装
npm install sass-loader node-sass --save-dev
# 启动测试
npm run dev -
npm命令解释
npm install moduleName
:安装模块到项目目录下npm install -g moduleName
:-g的意思是全局安装,具体安装位置要看npm config prefix的位置npm install -save moduleName
: --save的意思是将模块安装到项目目录下,并在package文件的dependencies节点写入依赖,-S为该命令的缩写npm install -save-dev moduleName
:–save-dev的意思是将模块安装到项目目录下,并在package文件的devDependencies节点写入依赖,-D为该命令的缩写
-
创建登录页面
把初始化后不需要的内容删除
构建如下结构
- assets:用于存放资源文件
- components:用于存放Vue功能组件
- views:用于存放Vue视图组件
- router:用于存放vue-router配置
创建首页视图,在views目录下创建一个名为
Main.vue
的视图组件1
2
3
4
5
6
7
8
9
10
11
12
13<template>
<h1>首页</h1>
</template>
<script>
export default {
name: "Main"
}
</script>
<style scoped>
</style>创建登录视图在views目录下创建名为
Login.vue
的视图组件,其中el-*
的元素为ElementUI组件1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84<template>
<div>
<el-form ref="loginForm" :model="form" :rules="rules" label-width="80px" class="login-box">
<h3 class="login-title">欢迎登录</h3>
<el-form-item label="账号" prop="username">
<el-input type="text" placeholder="请输入账号" v-model="form.username"/>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input type="password" placeholder="请输入密码" v-model="form.password"/>
</el-form-item>
<el-form-item>
<el-button type="primary" v-on:click="onSubmit('loginForm')">登录</el-button>
</el-form-item>
</el-form>
<el-dialog
title="温馨提示"
:visible.sync="dialogVisible"
width="30%"
:before-close="handleClose">
<span>请输入账号和密码</span>
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="dialogVisible = false">确 定</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
export default {
name: "Login",
data(){
return {
form: {
username : '',
password : ''
},
// 表单验证 需要在el-form-item元素中增加prop属性
rules: {
username: [
{required: true,message: '账号不能为空',trigger: 'blur'}
],
password: [
{required: true,message: '密码不能为空', trigger: 'blur'}
]
},
// 对话框显示和隐藏
dialogVisible: false
}
},
methods: {
onSubmit(formName){
// 表单绑定验证
this.$refs[formName].validate((valid) => {
if(valid) {
// 使用 vue-router 路由到指定页面 该方式称为编程式导航
this.$router.push("/main");
}else{
this.dialogVisible = true;
return false;
}
});
}
}
}
</script>
<style scoped>
.login-box {
border: 1px solid #DCDFE6;
width: 350px;
margin: 180px auto;
padding: 35px 35px 15px 35px;
border-radius: 5px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
box-shadow: 0 0 25px #909399;
}
.login-title{
text-align: center;
margin: 0 auto 40px auto;
color: #303133;
}
</style>在router文件夹下新建
index.js
,配置路由1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22import Vue from 'vue'
import Router from 'vue-router'
import Main from '../views/Main'
import Login from '../views/Login'
Vue.use(Router)
export default new Router({
routes:[
{
path: '/main',
component: Main
},
{
path: '/login',
component: Login
}
]
}); -
绑定路由,配置
main
App.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15<template>
<div id="app">
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
<style>
</style>main.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20import Vue from 'vue'
import App from './App'
// 扫描router
import router from './router'
// 导入element-ui 和需要的组件
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.config.productionTip = false
Vue.use(router)
Vue.use(ElementUI)
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
render: h => h(App) // elementUI
}) -
运行测试