1. MVVM 模式
1.1 MVVM 模式的概念
MVVM 是 Model-View-ViewModel 的简写。
- M:Model,模型,包括数据和一些基本操作
- V:View,视图,页面渲染结果
- VM:View-Model,模型与视图间的双向操作(无需开发人员干涉)
1.2 MVVM 模式的作用
在 MVVM 之前,开发人员从后端获取需要的数据模型,然后要通过 DOM 操作 Model 渲染到 View 中。而后当用户操作视图,我们还需要通过 DOM 获取 View 中的数据,然后同步到 Model 中。
在 MVVM 中的 VM 要做的事情就是把 DOM 操作完全封装起来,开发人员不用再关心 Model 和 View 之间是如何互相影响的:
- 只要我们 Model 发生了改变,View 上自然就会表现出来。
- 当用户修改了 View,Model 中的数据也会跟着改变。
1.3 MVVM 模式的应用
Vue 就是一款 MVVM 模式的框架
2. Vue 简介
Vue 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。
3. Node 和 NPM
NPM 是 Node 提供的模块管理工具,可以非常方便的下载安装很多前端框架,包括 Jquery、Angular.js、Vue.js 都有。为了后面学习方便,我们先安装 node 及 NPM 工具。
3.1 下载 Node.js
-
下载地址:https://nodejs.org/en/,建议下载 LTS 版本
-
安装完成后,打开命令提示符,查看版本信息
node -v
3.2 设置 NPM 镜像仓库
-
Node 自带了 NPM 了,打开命令提示符,查看版本信息
npm -v
-
npm 默认的仓库地址是在国外网站,速度较慢,建议设置到淘宝镜像。但是切换镜像是比较麻烦的。推荐一款切换镜像的工具 nrm。
-
安装 nrm,这里 -g 代表全局安装
npm install nrm -g
-
查看 npm 的仓库列表,带 * 的就是当前选中的镜像仓库
nrm ls
-
指定要使用的镜像源
nrm use taobao
-
安装完成要重启下电脑
4. Vue 快速入门
4.1 创建工程
-
打开 IDEA
-
Create New Project --> Empty Project --> Next
-
填写项目信息 --> Finish
-
New Modules --> Static Web --> Static Web --> Next
-
填写项目信息 --> Finish
4.2 安装 Vue
-
点击 IDEA 中的左下角的 Teminal 按钮
-
进入 demo1 目录
cd demo1
-
初始化项目(然后会在 demo1 目录生成一个 package.json 文件,它是 NodeJS 约定的用来存放项目的信息和配置等信息的文件)
npm init -y
-
安装 Vue ,–save 代表本地安装(然后就会在 demo1 目录生成一个 node_modules 目录,并且在下面有一个 vue 目录)
npm install vue --save
4.3 Vue 入门案例
4.3.1 Vue 声明式渲染
实现用 Vue 来渲染 name 这个数据
-
首先通过 new Vue() 来创建 Vue 实例
-
然后构造函数接收一个对象,对象中有一些属性:
- el:是 element 的缩写,通过 id 选中要渲染的页面元素
- data:数据,数据是一个对象,里面有很多属性,都可以渲染到视图中
-
页面中的 h1 元素中,我们通过 {{name}} 的方式,来渲染刚刚定义的 name 属性。
代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!--花括号 js 表达式-->
<h1>Hello {{name}}</h1>
</div>
</body>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
// 初始化一个 Vue 实例
var app = new Vue({
el: "#app",// Element 选择器
data: {
name: "Vue" // 定义数据模型
}
});
</script>
</html>
页面效果
4.3.2 双向绑定
实现 input 元素和 num 的双向绑定
- 我们在 data 添加了属性:num
- 在页面中有一个 input 元素,通过 v-model 与 num 进行绑定。
- 同时通过 {{num}} 在页面输出
代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!--双向绑定,v-model:数据模型-->
<input type="text" v-model="num">
<h1>{{num}}</h1>
</div>
</body>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
var app = new Vue({
el: "#app",
data: {
num: 100
}
});
</script>
</html>
实现效果
修改文本框内容,数字也会变化
4.3.3 事件处理
添加点击事件
我们在页面添加一个按钮,用 v-on 指令添加点击事件
代码如下
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<input type="text" v-model="num">
<!--vue-on:事件名-->
<input type="button" value="点我加 1" v-on:click="num++">
<h1>{{num}}</h1>
</div>
</body>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
var app = new Vue({
el: "#app",
data: {
num: 100
}
});
</script>
</html>
点击事件也可以是一个方法
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<input type="text" v-model="num">
<!--vue-on:事件名-->
<input type="button" value="点我加 1" v-on:click="increase">
<h1>{{num}}</h1>
</div>
</body>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
var app = new Vue({
el: "#app",
data: {
num: 100
},
methods: {
increase() {
this.num++;
}
}
});
</script>
</html>
页面效果
5. Vue 实例
5.1 创建 Vue 实例
每个 Vue 应用都是通过用 Vue 函数创建一个新的 Vue 实例开始的
代码如下
var vm = new Vue({
// 选项
})
Vue 实例的数据和方法
- el
- data
- methods
- 等等…
5.2 指定 HTML 模板
每个 Vue 实例都需要关联一段 HTML 模板,Vue 会基于此模板进行视图渲染,我们可以通过 el 属性来指定。
代码如下
HTML 模板
<div id="app">
</div>
Vue 实例
var app = new Vue({
el:"#app"
})
5.3 双向数据绑定
当 Vue 实例被创建时,它会尝试获取在 data 中定义的所有属性,用于视图的渲染,并且监视 data 中的属性变化,当 data 发生改变,所有相关的视图都将重新渲染,这就是"响应式"系统。
代码如下
HTML 模板
<div id="app">
<input type="text" v-model="name"/>
</div>
Vue 实例
var app = new Vue({
el:"#app",
data:{
name:"Vue"
}
})
5.4 定义方法
Vue 实例中除了可以定义 data 属性,也可以定义方法,并且在 Vue 实例的作用范围内使用。
代码如下
HTML 模板
<div id="app">
<!--vue-on:事件名-->
<input type="button" value="点我加 1" v-on:click="increase">
<h1>{{num}}</h1>
</div>
Vue 实例
var app = new Vue({
el: "#app",
data: {
num: 100
},
methods: {
increase() {
this.num++;
}
}
});
5.5 生命周期钩子
5.5.1 生命周期
每个 Vue 实例在被创建时都要经过一系列的初始化过程 :创建实例,装载模板,渲染模板等等。Vue 为生命周期中的每个状态都设置了钩子函数(监听函数)。每当 Vue 实例处于不同的生命周期时,对应的钩子函数就会被触发调用。
生命周期
5.5.2 钩子函数
一共八个钩子函数
- beforeCreated:在实例化时调用。
- created:在创建实例之后进行调用。
- beforeMount:页面加载完成,没有渲染时调用。如:此时页面还是{{name}}
- mounted:页面渲染后调用。如:此时页面中的 {{name}} 已被渲染成 Vue
- beforeUpdate:组件更新之前调用。
- updated:组件更新之后调用。
- beforeDestroy:该函数将在销毁实例前调用 。
- destroyed:改函数将在销毁实例时调用。
实例
我们可以在 Vue 中定义一个 created 函数,代表这个时期的钩子函数
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h1>{{num}}</h1>
</div>
</body>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
var app = new Vue({
el: "#app",
data: {
num: 100
},
created: function () {
this.num = 10000;
}
});
</script>
</html>
页面效果
6. 指令
6.1 指令的概念
指令 (Directives) 是带有 v- 前缀的特殊特性,主要的功能就是操作DOM
6.2 插值表达式
6.2.1 花括号
格式
{{表达式}}
说明
- 该表达式支持 JS 语法,可以调用 JS 内置函数
- 表达式必须有返回结果。例如:1+1,没有结果的表达式不允许使用,例如:var a = 1+1
- 可以直接获取 Vue 实例中定义的数据或函数
实例
HTML 模板
<div id="app">
<h1>Hello {{name}}</h1>
</div>
Vue 实例
var app = new Vue({
el: "#app",
data: {
name: "Vue"
}
});
6.2.2 v-text 和 v-html
使用 {{}} 方式在数据未加载完成时,页面会显示出原始的 {{}},加载完毕后才显示正确数据,我们称为插值闪烁。
使用 v-text 和 v-html 指令来替代 {{}},这样不会出现插值闪烁,当没有数据时,会显示空白。
说明
- v-text:将数据输出到元素内部,如果输出的数据有 HTML 代码,会作为普通文本输出
- v-html:将数据输出到元素内部,如果输出的数据有 HTML 代码,会被渲染
实例
HTML 模板
<div id="app">
<h1>Hello <span v-text="name"></span></h1>
<h1>Hello <span v-html="name"></span></h1>
</div>
Vue 实例
var app = new Vue({
el: "#app",
data: {
name: "<span>Vue</span>"
}
});
页面效果
6.3 v-model
v-model 是双向绑定,视图(View)和模型(Model)之间会互相影响。
v-model的可使用元素
- input
- select
- textarea
- checkbox
- radio
- components(Vue中的自定义组件)
实例
HTML 模板
<div id="app">
<input type="checkbox" v-model="language" value="Java"/>Java<br/>
<input type="checkbox" v-model="language" value="PHP"/>PHP<br/>
<input type="checkbox" v-model="language" value="Swift"/>Swift<br/>
<h1>
你选择了:{{language.join(',')}}
</h1>
</div>
Vue 实例
var app = new Vue({
el: "#app",
data: {
language: []
}
})
页面效果
勾选选择框后,选择内容也会变化
6.4 v-on
6.4.1 基本用法
v-on 指令用于给页面元素绑定事件。
格式
v-on:事件名 = "js片段或函数名"
// 或简写为
@事件名 = "js片段或函数名"
6.4.2 事件修饰符
事件修饰符处理了许多 DOM 事件的细节,让我们不再需要花大量的时间去处理这些烦恼的事情,而能有更多的精力专注于程序的逻辑处理。
事件修饰符
- .stop :阻止事件冒泡到父元素
- .prevent:阻止默认事件发生
- .capture:使用事件捕获模式
- .self:只有元素自身触发事件才执行。(冒泡或捕获的都不执行)
- .once:只执行一次
实例
HTML 模板
<div id="app">
<!--右击事件,并阻止弹出菜单-->
<button v-on:contextmenu.prevent="num++">点我加 1</button>
<br/>
<h1>{{num}}</h1>
</div>
Vue 实例
var app = new Vue({
el: "#app",
data: {
num: 100
}
});
6.4.3 按键修饰符
在监听键盘事件时,我们经常需要检查常见的键值,v-on 可以在监听键盘事件时添加按键修饰符。
实例
监听 Enter 键
<input v-on:keyup.enter="submit">
<!-- 缩写语法 -->
<input @keyup.enter="submit">
6.5 v-for
通过 v-for 指令来实现遍历数据渲染页面。
6.5.1 遍历数组
语法
v-for = "item in items"
- items:要遍历的数组,需要在 vue 的 data 中定义
- item:迭代得到的数组元素的别名
实例
HTML 模板:
<div id="app">
<ul>
<li v-for="user in users">
{{user.name}}-{{user.age}}-{{user.sex}}
</li>
</ul>
</div>
Vue 实例
var app = new Vue({
el: "#app",
data: {
users: [
{name: "张三", age: 18, sex: "男"},
{name: "李四", age: 21, sex: "女"},
{name: "王五", age: 24, sex: "男"}
]
}
})
页面效果
6.5.2 数组角标
在遍历的过程中,如果我们需要知道数组角标,可以指定第二个参数 index
语法
v-for="(item,index) in items"
- items:要迭代的数组
- item:迭代得到的数组元素别名
- index:迭代到的当前元素索引,从 0 开始。
实例
HTML 模板
<div id="app">
<ul>
<li v-for="(user,index) in users">
{{index+1}}. {{user.name}}-{{user.age}}-{{user.sex}}
</li>
</ul>
</div>
Vue 实例
var app = new Vue({
el: "#app",
data: {
users: [
{name: "张三", age: 18, sex: "男"},
{name: "李四", age: 21, sex: "女"},
{name: "王五", age: 24, sex: "男"}
]
}
})
页面效果
6.5.3 遍历对象
v-for 除了可以迭代数组,也可以迭代对象。
语法:
v-for="value in object"
v-for="(value,key) in object"
v-for="(value,key,index) in object"
- 1 个参数时,得到的是对象的属性值
- 2 个参数时,第一个是属性值,第二个是属性名
- 3 个参数时,第三个是索引,从0开始
实例
HTML 模板
<div id="app">
<ul>
<li v-for="(value, key, index) in user">
{{index + 1}}. {{key}} - {{value}}
</li>
</ul>
</div>
Vue 实例
var app = new Vue({
el: "#app",
data: {
user: {name: "张三", age: 18, sex: "男"}
}
})
页面效果
6.6 v-if 和 v-show
6.6.1 v-if
v-if,条件判断。当得到结果为 true 时,所在的元素才会被渲染。
语法:
v-if = "布尔表达式"
实例
HTML 模板
<div id="app">
<button @click="show=!show">点我</button>
<h1 v-if="show">看到我啦!</h1>
</div>
Vue 实例
var app = new Vue({
el: "#app",
data: {
show: false
}
});
页面效果
点击按钮出现内容
6.6.2 v-if 与 v-on 结合使用
当 v-if 和 v-for 出现在一起时,因为 v-for 优先级更高,所以会先遍历,再判断条件。
实例
HTML 模板
<div id="app">
<ul>
<li v-for="(user,index) in users" v-if="user.sex=='男'">
{{index+1}}. {{user.name}}-{{user.age}}-{{user.sex}}
</li>
</ul>
</div>
Vue 实例
var app = new Vue({
el: "#app",
data: {
users: [
{name: "张三", age: 18, sex: "男"},
{name: "李四", age: 21, sex: "女"},
{name: "王五", age: 24, sex: "男"}
]
}
})
页面效果
只显示男性用户信息
6.6.3 v-else-if 和 v-else
你可以使用 v-else-if 和 v-else 指令来表示 v-if 的 else 块
注意:
- v-else-if 元素必须紧跟在带 v-if 或者 v-else-if 的元素的后面,否则它将不会被识别。
- v-else 元素必须紧跟在带 v-if 或者 v-else-if 的元素的后面,否则它将不会被识别。
实例
HTML 模板
<div id="app">
<button v-on:click="random=Math.random()">点我呀</button>
<h1>random = {{random}}</h1>
<h1 v-if="random > 0.75">
random > 0.75
</h1>
<h1 v-else-if="random > 0.5">
random > 0.5
</h1>
<h1 v-else-if="random > 0.25">
random > 0.25
</h1>
<h1 v-else>
random <= 0.25
</h1>
</div>
Vue 实例
var app = new Vue({
el: "#app",
data: {
random: 1
}
})
页面效果
6.6.4 v-show
另一个用于根据条件展示元素的选项是 v-show 指令。与 v-if 不同的是带有 v-show 的元素始终会被渲染并保留在 DOM 中,v-show 只是简单地切换元素的 CSS 属性 display。
实例
HTML 模板
<div id="app">
<button @click="show=!show">点我</button>
<h1 v-show="show">看到我啦!</h1>
</div>
Vue 实例
var app = new Vue({
el: "#app",
data: {
show: false
}
});
页面效果
6.7 v-bind
html 属性不能使用双大括号形式绑定,只能使用 v-bind 指令。
6.7.1 绑定 style 样式
实例
HTML 模板
<div id="app">
<input type="text" v-model="store">
<!--v-bind:class 可以简写为 :class-->
<input type="button" value="加入购物车" v-bind:class="{disabled: store==0}">
</div>
CSS 样式
.disabled{
opacity: 0.6;
cursor: not-allowed;
}
Vue 实例
var app = new Vue({
el: "#app",
data: {
store: 0
}
});
页面效果
数量为 0 时,不可以加入购物车
6.8 计算属性
在插值表达式中使用 js 表达式是非常方便的,但是如果 js 表达式的内容很长,就会显得不够优雅,Vue 中提供了计算属性,来替代复杂的 js 表达式。
实例
HTML 模板
<div id="app">
<h1>当前时间:{{now}}</h1>
</div>
Vue 实例
var app = new Vue({
el: "#app",
data: {
time: 1580801398417 // 毫秒值
},
computed: {
now() { // 计算属性本质是一个方法,但是必须返回结果
const date = new Date(this.time);
return date.toLocaleString();
}
}
})
页面效果
注意
我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的依赖进行缓存的。计算属性只有在它的相关依赖发生改变时才会重新求值。这就意味着只要 time 还没有发生改变,多次访问 time 计算属性会立即返回之前的计算结果,而不必再次执行函数。
6.9 watch
watch 可以让我们监控一个值的变化,从而做出相应的反应。
实例
HTML 模板
<div id="app">
<input type="text" v-model="message">
</div>
Vue 实例
var app = new Vue({
el: "#app",
data: {
message: ""
},
watch: {
// 第一个参数是当前的值,第二个参数是上一个的值
message(newVal, oldVal) {
console.log(newVal, oldVal);
}
}
})
页面效果
实时监控文本框输入的值
7. 组件化
在大型应用开发的时候,页面可以划分成很多部分。往往不同的页面,也会有相同的部分。例如可能会有相同的头部导航。但是如果每个页面都独自开发,这无疑增加了我们开发的成本。所以我们会把页面的不同部分拆分成独立的组件,然后在不同页面就可以共享这些组件,避免重复开发。
7.1 全局组件
通过 Vue 的 component 方法来定义一个全局组件。
实例
HTML 模板
<div id="app">
<!--使用全局组件-->
<counter></counter>
</div>
Vue 实例
// 定义全局组件,两个参数:1.组件名称。2.组件参数
Vue.component("counter",{
template: "<button @click='num++'>点我 num+1, num = {{num}}</button>",
data() {
return {
num:0
}
}
})
var app = new Vue({
el:"#app",
})
页面效果
说明
- 组件其实也是一个 Vue 实例,因此它在定义时也会接收:data、methods、生命周期函数等
- 不同的是组件不会与页面的元素绑定,否则就无法复用了,因此没有 el 属性。
- 但是组件渲染需要 HTML 模板,所以增加了 template 属性,值就是 HTML 模板
- 全局组件定义完毕,任何 Vue 实例都可以直接在 HTML 中通过组件名称来使用组件了。
- data 必须是一个函数,不再是一个对象。
7.2 组件的复用
定义好的组件,可以任意复用多次,并且每个组件之间互不干扰。
实例
HTML 模板
<div id="app">
<!--使用全局组件-->
<counter></counter>
<counter></counter>
<counter></counter>
</div>
Vue 实例
// 定义全局组件,两个参数:1.组件名称。2.组件参数
Vue.component("counter",{
template: "<button @click='num++'>点我 num+1, num = {{num}}</button>",
data() {
return {
num:0
}
}
})
var app = new Vue({
el:"#app",
})
页面效果
每个 counter 之间互不影响
说明
当我们定义 counter 组件时,它的 data 并不是像之前直接提供一个对象:
data: {
num: 0
}
取而代之的是,一个组件的 data 是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝:
data() {
return {
num:0
}
}
7.3 局部组件
定义全局组件,就意味着即便以后你不再使用这个组件,它依然会随着 Vue 的加载而加载。因此,对于一些并不频繁使用的组件,我们会采用定义局部组件。
实例
HTML 模板
<div id="app">
<!--使用局部组件-->
<count></count>
</div>
Vue 实例
// 定义局部组件,结构就是全局组件的第二个参数
var count = {
template: "<button @click='num++'>点我 num+1, num = {{num}}</button>",
data() {
return {
num: 0
}
}
}
var app = new Vue({
el: "#app",
components:{
// 将定义的对象注册为组件
count:count
}
})
页面效果
说明
- components 就是当前 Vue 对象子组件集合。
- key 就是子组件名
- value 就是组件对象名
- 效果与刚才的全局注册是类似的,不同的是,这个 counter 组件只能在当前的 Vue 实例中使用
7.4 组件通信
通常一个单页应用会以一棵嵌套的组件树的形式来组织:
- 页面首先分成了顶部导航、左侧内容区、右侧边栏三部分
- 左侧内容区又分为上下两个组件
- 右侧边栏中又包含了3个子组件
各个组件之间以嵌套的关系组合在一起,那么这个时候不可避免的会有组件间通信的需求。
7.4.1 父组件向子组件的通信
说明
- 在父组件中,自定义属性(属性名任意,属性值为要传递的数据)
- 子组件通过 props 接收父组件数据,通过自定义属性的属性名
实例
HTML 模板
<div id="app">
<!--在父组件中,自定义属性-->
<hello title="Hello Vue !"></hello>
</div>
Vue 实例
// 子组件
Vue.component("hello",{
template: "<h1>{{title}}</h1>", // 直接使用 props 接收到的属性来渲染页面
props:["title"] // 通过 props 来接收一个父组件传递的属性
})
// 父组件
var app = new Vue({
el: "#app"
})
页面效果
7.4.2 动态传递和静态传递
给 prop 传入一个静态的值:
<hello title="Hello Vue !"></hello>
给 prop 传入一个动态的值:
<hello :title="42" ></hello>
注意:静态传递的值都是字符串类型的,动态传递的值会解析为 JS 表达式
7.4.3 子组件向父组件的通信
子组件接收到父组件属性后,默认是不允许修改的。既然只有父组件能修改,那么修改的函数一定是放在父组件。子组件来调用父组件的函数,该怎么做呢?
说明
vue 提供了一个内置的 this.$emit() 函数,用来调用父组件绑定的函数
实例
HTML 模板
<div id="app">
<h1>num: {{num}}</h1>
<!--父组件调用父组件中方法-->
<counter @add="superAdd"></counter>
</div>
Vue 实例
// 子组件
Vue.component("counter",{
// 子组件调用子组件中方法
template: "<button @click='subAdd'>点我num++</button>",
methods: {
subAdd() {
// 子组件调用父组件的方法,值是自定义事件名
this.$emit("add")
}
}
})
// 父组件
var app = new Vue({
el: "#app",
data: {
num: 0
},
methods: {
superAdd() {
this.num++;
}
}
})
页面效果
8. 路由
现在我们来实现这样一个功能:
一个页面,包含登录和注册,点击不同按钮,实现登录页和注册页切换
8.1 初步实现
代码如下
-
编写登录组件
const loginForm = { template: ` <div> <h2>登录页</h2> 用户名:<input type="text"><br> 密 码:<input type="password"><br> <input type="button" value="登录"> </div> `, }
-
编写注册组件
const registerForm = { template: ` <div> <h2>注册页</h2> 用 户 名:<input type="text"><br> 密  码:<input type="password"><br> 确认密码:<input type="password"><br> <input type="button" value="注册"> </div> `, }
-
编写父组件,并引入登录注册组件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <span>登录</span> <span>注册</span> <hr> <login-Form></login-Form> <register-Form></register-Form> </div> </body> <script src="../node_modules/vue/dist/vue.js"></script> <script src="js/loginForm.js"></script> <script src="js/registerForm.js"></script> <script> var app = new Vue({ el: "#app", components: { loginForm, registerForm } }) </script> </html>
页面效果
8.2 进一步实现
现在登录页和注册页都有了,但它们现在是一起显示的。我希望的是点击登录和注册两个按钮,能够实现在登录页和注册页之间切换。
但是如何才能动态加载组件,实现组件切换呢?我们可以使用 vue-router 模块。
安装 vue-router
-
点击 IDEA 中的左下角的 Teminal 按钮
-
安装 vue-router
npm install vue-router --save
代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!--router-link 指定跳转路径-->
<span><router-link to="/login">登录</router-link></span>
<span><router-link to="/register">注册</router-link></span>
<hr>
<router-view></router-view>
</div>
</body>
<script src="../node_modules/vue/dist/vue.js"></script>
<script src="../node_modules/vue-router/dist/vue-router.js"></script>
<script src="js/loginForm.js"></script>
<script src="js/registerForm.js"></script>
<script>
// 创建 VueRouter 对象
const router = new VueRouter({
// 路由规则
routes: [
{
path: "/login", // 请求路径
component: loginForm // 组件名称
},
{
path: "/register",
component: registerForm
}
]
})
var app = new Vue({
el: "#app",
// 引用 router 对象
router
})
</script>
</html>
页面效果