Vue基础知识
# 1,简介
官网:https://cn.vuejs.org (opens new window)
# 1. 概念
Vue.js
是一套构建用户界面的渐进式框架。Vue
只关注视图层, 采用自底向上增量开发的设计。Vue
的目标是通过尽可能简单的API
实现响应的数据绑定和组合的视图组件。简单的理解:Vue
就是和jQuery
类似但更强的一个前端框架,它的中心思想就是数据驱动。而jQuery
是结构驱动的,具体来说jQuery
不算框架,而是js
库。Vue.js
是目前最火的一个前端框架,React 是最流行的一个前端框架(React 除了开发网站,还可以开发手机App
,Vue
语法也是可以用于进行手机App
开发的,需要借助于Weex
)Vue.js
是前端的主流框架之一,和Angular.js
、React.js
一起,并成为前端三大主流框架!Vue.js
是一套构建用户界面的框架,只关注视图层,它不仅易于上手,还便于与第三方库或既有项目整合。(Vue
有配套的第三方类库,可以整合起来做大型项目的开发)
# 2. 框架和库的区别
- 框架:是一套完整的解决方案;对项目的侵入性较大,项目如果需要更换框架,则需要重新架构整个项目,虽然有这个缺点,但是功能完善。
- 库(插件):提供某一个小功能,对项目的侵入性较小,如果某个库无法完成某些需求,可以很容易切换到其它库实现需求。比如从
Jquery
切换到Zepto
,又比如从EJS
切换到art-template
。
# 3. 为什么要学习前端框架
- 提高开发效率。提高开发效率的发展历程:原生 JS ->
Jquery
之类的类库 -> 前端模板引擎 ->Angular.js
/Vue.js
/React.js
(能够帮助我们减少不必要的DOM
操作;提高渲染效率;双向数据绑定的概念【通过框架提供的指令,我们前端程序员只需要关心数据的业务逻辑,不再关心 DOM 是如何渲染的了】) - 减少少 DOM 操作。在
Vue
中,一个核心的概念,就是让用户不再操作DOM
元素,解放了用户的双手,让程序员可以更多的时间去关注业务逻辑。
# 4. 前端的 MVVM
为了维护和管理前端开发,前端开发一般还要MVVM
的分层开发模式。不要理解成MVC
,MVC
是后端的分层开发概念。而MVVM
是前端视图层的概念,主要关注于视图层分离,也就是说:MVVM
把前端的视图层,分为了 三部分 Model, View , VM (即ViewModel
)。
# 2,安装
# 1. <script>
标签引入 vue.js 文件
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
例如:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>VueJS Tutorials</title>
<link href="styles.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
</body>
</html>
2
3
4
5
6
7
8
9
10
11
12
# 2. 使用 NPM 工具构建
# 最新稳定版
$ npm install vue
2
# 3,基础语法要点
先来个经典的 hello world 热热身。
app.js
//引入vue包后,浏览器的内存中就多了一个Vue的构造函数,只需要new Vue,就能实例化出Vue对象
new Vue({
//el(即elemet): 挂载点,需要绑定的vue根容器(根元素),一切的vue相关操作都在这个元素内进行。元素外不起作用
el: "#vue-app",
//data:数据选项,用于数据的存储,存放key/value。data就是mvvm中的model
data: {
//只需要在元素标签中使用表达式{{key}}或者v-text等插值表达式就能显示key对应的值,省略了麻烦的dom操作
username: "eryajf",
msg: "hello world!",
},
});
2
3
4
5
6
7
8
9
10
11
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>hello world</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<!--引入vue.js-->
</head>
<body>
<div id="vue-app">
<!-- vue根容器 -->
<!--根据data中的key使用模版语法{{}}取出值,vue将{{}}里的内容放到虚拟dom里,再通过虚拟dom将该内容放回真实dom的相关元素里-->
<h1>Hey, {{ username }}</h1>
<h1>{{ msg }}</h1>
</div>
</body>
<script src="app.js"></script>
<!--引入app.js,app.js存储vue对象等相关业务代码-->
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
基础语法要点总结:
MVC 和 MVVM 的区别
Vue 中最基本代码的结构
插值表达式 v-cloak v-text v-html v-bind(缩写是:) v-on(缩写是@) v-model v-for v-if v-show
事件修饰符 : .stop .prevent .capture .self .once
el 指定要控制的区域 data 是个对象,指定了控制的区域内要用到的数据 methods 虽然带个 s 后缀,但是是个对象,这里放置着自定义的函数
在 VM 实例中,如果要访问 data 上的数据,或者要访问 methods 中的方法, 必须带 this
在 v-for 要会使用 key 属性 (只接受 string / number)
v-model 只能应用于表单元素 -->
在 vue 中绑定样式两种方式 v-bind:class v-bind:style
# 4,差(插)值表达式
刚刚上边的示例当中的用法,就是差值表达式,在很多语言中的模板语法,基本上也都是这么使用的。
语法格式:
注意:差值表达式不能写在 html 的标签中,不能作为属性的值的部分。
# 5,关键字
# 1,v-cloak
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>learn vue</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<!--引入vue.js-->
</head>
<body>
<div id="vue-app">
<!-- 使用 v-cloak 结合css样式能够解决差值表达式闪烁的问题-->
<h1 v-cloak>Hey, {{ username }}</h1>
<h1 v-cloak>{{ msg }}</h1>
</div>
</body>
<script>
new Vue({
el: "#vue-app",
data: {
username: "eryajf",
msg: "hello world!",
},
});
</script>
<style>
[v-cloak] {
display: none;
}
</style>
</html>
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
解决使用插值表达式显示 data 数据出现闪烁的问题。步骤是,在有插值表达式内容的标签里添加v-cloak
属性,然后添加如下css
样式表即可解决。
<style>
[v-cloak]{
display: none;
}
</style>
2
3
4
5
# 2,v-text-绑定数据为纯文本
与插值表达式功能是一样的。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>v-text</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="vue-app">
<h1 v-text="username"></h1>
<h1 v-text="msg"></h1>
<!--
<h1>Hey, {{ username }}</h1>
<h1>{{ msg }}</h1>
-->
</div>
</body>
<script>
new Vue({
el: "#vue-app",
data: {
username: "qcmoke",
msg: "hello world !",
},
});
</script>
</html>
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
与插值表达式不同的是不会出现插值表达式的闪烁的问题。原因是 v-text 会覆盖元素中原本的内容,但是 插值表达式 只会替换自己的这个占位符,不会把 整个元素的内容清空。
如何选择插值表达式和 v-text?
如果内容含有 data 没有的一些字符,那么建议使用插值表达式结合v-cloak
属性使用。
如果内容只有 data 里的数据,那么建议使用v-cloak
。
# 3,v-html-绑定 html 数据
作用:用于绑定 data 中的 html 数据。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>learn vue</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<!--引入vue.js-->
</head>
<body>
<div id="vue-app">
<h1 v-html="msg_el"></h1>
</div>
</body>
<script>
new Vue({
el: "#vue-app",
data: {
msg_el: '<h1 style="color: red">hello world !</h1>',
},
});
</script>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
使用 v-text 或者插值表达式只能显示纯文本内容
# 4,v-bind-单向数据绑定
- 作用:用于给
html
元素的属性绑定数据 - 缩写:
:
- 实现步骤:在原来属性的值里写
vue
中data
的key
,并在原属性前添加"v-bind:
",以此来给属性绑定vue
的数据。 - 数据绑定方式:单向数据绑定,即从
model
自动绑定到view
,view
上绑定的属性数据(值)会随着model
值的改变而改变,但是view
中绑定的属性数据(值)的改变不会改变 model 中属性的数据(值)。 - 绑定方向:
model
---->view
。 - 作用范围:所有标签元素。
vue
会将元素中属性绑定的 key 当作是js
表达式返回,所以可以进行合法的运算操作。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>learn vue</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<!--引入vue.js-->
</head>
<body>
<div id="vue-app">
<!-- 在原来属性的值里写vue中data的key,并在原属性前添加"v-bind:",以此来给属性绑定vue的数据 -->
<a v-bind:href="vue_url">vue的官方地址</a>
<br />
<!-- vue会将元素中属性绑定的key当作是js表达式返回,所以可以进行合法的运算操作,同时v-bind可以简写为冒号 -->
<a :href="vue_url+'/v2/guide'">vue的官方文档</a>
</div>
</body>
<script>
new Vue({
el: "#vue-app",
data: {
vue_url: "https://cn.vuejs.org",
},
});
</script>
</html>
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
# 5,v-model-双向数据绑定
- 作用:用于给
html
元素的属性绑定数据 - 缩写:
:
- 实现步骤:在需要表单元素里添加
v-model="data找那个的key"
即可实现双向数据绑定。 - 数据绑定方式:双向数据绑定,即从
model
和view
数据互相绑定,view
上绑定的属性数据(值)会随着model
值的改变而改变,并且view
中绑定的属性数据(值)的改变也会改变 model 中属性的数据(值)。 - 绑定方向:
model
<---->view
。 - 双向数据绑定不可以进行表达式运算操作。
- 作用范围:
v-model
只能使用在表单元素中,如input(radio, text, address, email....)
、select
checkbox
、textarea
等。
测试单向数据绑定和双向数据绑定的区别
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>v-bind</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="vue-app">
单向数据绑定:<input type="text" v-bind:value="key1" /> <br /><br />
双向数据绑定:<input type="text" v-model="key2" />
</div>
</body>
<script>
var vm = new Vue({
el: "#vue-app",
data: {
key1: "value of key1",
key2: "value of key2",
},
});
</script>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
model—>view 方向数据变化情况(通过浏览器的控制台操作内存中的 vue 对象即可改变 model 中的数据)
# 6,v-on-事件绑定
作用:事件绑定。
缩写: @
步骤:在原来的事件属性前添加“v-on:
”,并给事件属性赋vue
的data key
。,最后在vue
对象的methods
属性里添加key
对应的方法。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>learn vue</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<!--引入vue.js-->
</head>
<body>
<div id="vue-app">
请输入你的爱好:<input type="text" v-on:input="changeHobby" />
<br />
===========
<br />
我的爱好是 {{ habby }}
</div>
</body>
<script>
new Vue({
el: "#vue-app",
data: {
habby: "打篮球",
},
methods: {
changeHobby: function (event) {
console.log(event.target.value); // 此处可以通过 event.target.value 拿到input的值
this.habby = event.target.value;
},
},
});
</script>
</html>
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
这里在更改输入内容时,展示的内容也会跟随变化。
点击事件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>learn vue</title>
</head>
<body>
<div id="app">
{{ count }}
<button type="button" @click="addClick">增加</button>
<input type="number" v-model="mystep" />
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script>
new Vue({
el: "#app",
data: {
count: 0,
mystep: 1,
},
methods: {
addClick() {
this.count += Number(this.mystep);
},
},
});
</script>
</html>
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
其中 mystep 应用的时候需要用 Number(this.mystep)
或者 this.mystep-0
转换为 int 类型。
# 7,event 关键字
event 关键字有很多内容,可以打印一下首先来看看:
event.target.value
在响应函数里,可以指明使用 event 内置的参数对象。该对象表示当前事件,可以通过
event.target.value
来获得当前事件对象的值。
# 8,事件修饰符
.stop
阻止冒泡冒泡:在多个绑定有事件的元素嵌套中。当触发一个元素时,伴随着嵌套的元素也会触发事件。
.prevent
阻止默认事件.capture
添加事件侦听器时使用事件捕获模式.self
只当事件在该元素本身触发时触发回.once
事件只触发一次
# 1,.once-事件只触发一次
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>事件修饰符</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="vue-app">
<!--
.once
作用:事件只触发一次
只在第一次点击的时候触发.prevent事件修饰符阻止a标签的默认跳转事件,第二次之后原本的默认跳转事件会被触发 -->
<a :href="vue_url" @click.prevent.once="linkHandler">点击链接</a>
</div>
</body>
<script>
new Vue({
el: "#vue-app", //el属性定义vue的控制区域
data: {
//data属性定义所有vue数据
vue_url: "https://cn.vuejs.org",
},
methods: {
//methods定义所有vue可用的方法
linkHandler() {
console.info("触发链接点击事件!");
},
},
});
</script>
</html>
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
# 2,.stop-阻止冒泡
先来看一个冒泡的案例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>learn vue</title>
</head>
<body>
<div id="app">
<div @click="divHandle">
<button type="button" @click="buttonHandle">点击按钮</button>
</div>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<!--引入vue.js-->
<script>
new Vue({
el: "#app",
data: {
vue_url: "https://cn.vuejs.org",
},
methods: {
divHandle() {
console.log("hello div");
},
buttonHandle() {
console.log("hello button");
},
},
});
</script>
</html>
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
此时点击了 button 的按钮,它的外层 div 也会被传递调用。
那么我们想让这种传递止在哪一层,就只需在这一层引入 .stop
即可:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>learn vue</title>
</head>
<body>
<div id="app">
<div @click="divHandle">
<button type="button" @click.stop="buttonHandle">点击按钮</button>
</div>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<!--引入vue.js-->
<script>
new Vue({
el: "#app",
data: {
vue_url: "https://cn.vuejs.org",
},
methods: {
divHandle() {
console.log("hello div");
},
buttonHandle() {
console.log("hello button");
},
},
});
</script>
</html>
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
# 3,.prevent-阻止默认事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>learn vue</title>
</head>
<body>
<div id="app">
<!-- 使用.prevent事件修饰符阻止a标签的默认跳转事件 -->
<a :href="vue_url" @click.prevent="linkHandle">点击链接</a>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<!--引入vue.js-->
<script>
new Vue({
el: "#app",
data: {
vue_url: "https://cn.vuejs.org",
},
methods: {
linkHandle() {
console.log("触发连接点击事件");
},
},
});
</script>
</html>
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
效果如下:
# 4,.capture-添加事件捕获
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>learn vue</title>
</head>
<body>
<div id="app">
<!-- 事件捕获
默认情况下,冒泡事件是从内向外触发的,如果给外层加上.capture,则会从外网内触发
-->
<div @click.capture="divHandle">
<button type="button" @click="buttonHandle">点击按钮</button>
</div>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<!--引入vue.js-->
<script>
new Vue({
el: "#app",
data: {
vue_url: "https://cn.vuejs.org",
},
methods: {
divHandle() {
console.log("hello div");
},
buttonHandle() {
console.log("hello button");
},
},
});
</script>
</html>
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
# 5,.self-只触发当前元素事件
与前边的用法以及概念类似
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>learn vue</title>
</head>
<body>
<div id="app">
<!-- 事件捕获
默认情况下,冒泡事件是从内向外触发的,如果给外层加上.capture,则会从外网内触发
-->
<div
@click.self="divHandle"
style="width: 100px; height: 100px; background: gray;"
>
<button type="button" @click="buttonHandle">点击按钮</button>
</div>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<!--引入vue.js-->
<script>
new Vue({
el: "#app",
data: {
vue_url: "https://cn.vuejs.org",
},
methods: {
divHandle() {
console.log("hello div");
},
buttonHandle() {
console.log("hello button");
},
},
});
</script>
</html>
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
# 9,按键修饰符
几个常用的按键如下:
.enter
.tab
.delete (捕获“删除”和“退格”键)
.esc
.space
.up
.down
.left
.right
2
3
4
5
6
7
8
9
使用方式:
v-on:keyup.键盘修饰符="事件方法()"
如下:
<!-- 只有在 `key` 是 `Enter` 时调用 `vm.submit()` -->
<input v-on:keyup.enter="submit">
2
如果以上提供的键盘修饰符任然不够用,可以通过以下 js 代码进行扩展。
// 自定义全局按键修饰符
Vue.config.keyCodes.自定义修饰符名称 = 键码值;
2
字母和 数字键 (keyCode) | |||||||
---|---|---|---|---|---|---|---|
按键 | 键码 | 按键 | 键码 | 按键 | 键码 | 按键 | 键码 |
A | 65 | J | 74 | S | 83 | 1 | 49 |
B | 66 | K | 75 | T | 84 | 2 | 50 |
C | 67 | L | 76 | U | 85 | 3 | 51 |
D | 68 | M | 77 | V | 86 | 4 | 52 |
E | 69 | N | 78 | W | 87 | 5 | 53 |
F | 70 | O | 79 | X | 88 | 6 | 54 |
G | 71 | P | 80 | Y | 89 | 7 | 55 |
H | 72 | Q | 81 | Z | 90 | 8 | 56 |
I | 73 | R | 82 | 0 | 48 | 9 | 57 |
数字键 (keyCode) | 功能键 (keyCode) | ||||||
---|---|---|---|---|---|---|---|
按键 | 键码 | 按键 | 键码 | 按键 | 键码 | 按键 | 键码 |
0 | 96 | 8 | 104 | F1 | 112 | F7 | 118 |
1 | 97 | 9 | 105 | F2 | 113 | F8 | 119 |
2 | 98 | * | 106 | F3 | 114 | F9 | 120 |
3 | 99 | + | 107 | F4 | 115 | F10 | 121 |
4 | 100 | Enter | 108 | F5 | 116 | F11 | 122 |
5 | 101 | - | 109 | F6 | 117 | F12 | 123 |
6 | 102 | . | 110 | ||||
7 | 103 | / | 111 |
控制键 键码值 (keyCode) | |||||||
---|---|---|---|---|---|---|---|
按键 | 键码 | 按键 | 键码 | 按键 | 键码 | 按键 | 键码 |
BackSpace | 8 | Esc | 27 | Right Arrow | 39 | -_ | 189 |
Tab | 9 | Spacebar | 32 | Dw Arrow | 40 | .> | 190 |
Clear | 12 | Page Up | 33 | Insert | 45 | /? | 191 |
Enter | 13 | Page Down | 34 | Delete | 46 | `~ | 192 |
Shift | 16 | End | 35 | Num Lock | 144 | [{ | 219 |
Control | 17 | Home | 36 | ;: | 186 | | | 220 |
Alt | 18 | Left Arrow | 37 | =+ | 187 | ]} | 221 |
Cape Lock | 20 | Up Arrow | 38 | ,< | 188 | '" | 222 |
多媒体 键码值 (keyCode) | |||||||
---|---|---|---|---|---|---|---|
按键 | 键码 | 按键 | 键码 | 按键 | 键码 | 按键 | 键码 |
音量加 | 175 | ||||||
音量减 | 174 | ||||||
停止 | 179 | ||||||
静音 | 173 | ||||||
浏览器 | 172 | ||||||
邮件 | 180 | ||||||
搜索 | 170 | ||||||
收藏 | 171 |
示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>learn vue</title>
</head>
<body>
<div id="app">
<input
type="text"
v-model:value="enter_value"
@keyup.enter="enterHandler"
placeholder="请输入值之后,按Enter键完成操作!"
/>
<input
type="text"
v-model:value="f2_value"
@keyup.f2="f2Handler"
placeholder="请输入值之后,按F2键完成操作!"
/>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<!--引入vue.js-->
<script>
// 自定义全局按键修饰符
Vue.config.keyCodes.f2 = 113;
new Vue({
el: "#app",
data: {
enter_value: "",
f2_value: "",
},
methods: {
enterHandler: function () {
alert("hello " + this.enter_value);
},
f2Handler: function () {
alert("hello " + this.f2_value);
},
},
});
</script>
</html>
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
# 6,样式绑定
# 1. class 属性绑定
# 1.1 数组形式
样式名称数组(此时的样式名称是 boolean 类型)
<div v-bind:class="['active', 'danger']"></div>
或者
数组中使用三元表达式对样式名称计算
<div v-bind:class="[isActive?'active':'',!'danger']"></div>
或者
数组中使用对象
<div v-bind:class="[!'danger',{active:isActive}]"></div>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>learn vue</title>
</head>
<body>
<div id="app">
<!-- 样式名称数组,此时的样式名称是boolean类型 -->
<div v-bind:class="['active','danger']"></div>
<br /><br />
<!-- 数组中使用三元表达式对样式名称计算 -->
<div v-bind:class="[isActive?'active':'',!'danger']"></div>
<br /><br />
<!-- 数组中使用对象 -->
<div v-bind:class="[!'danger',{active:isActive}]"></div>
<br /><br />
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<!--引入vue.js-->
<script>
// 自定义全局按键修饰符
Vue.config.keyCodes.f2 = 113;
new Vue({
el: "#app",
data: {
isActive: true,
},
});
</script>
<style>
.active {
width: 100px;
height: 100px;
background-color: green;
}
.danger {
background-color: red;
}
</style>
</html>
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
# 1.2 对象形式
<div v-bind:class="{ key: isActive,danger: false }"></div>
或者
<div v-bind:class="classObj"></div>
案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<style>
.active {
width: 100px;
height: 100px;
background: green;
}
.danger {
background: red;
}
</style>
</head>
<body>
<div id="vue-app">
<!--
v-bind:class的值是一个对象,可以是对象实例,也可以是对象的名称(model的key)
-->
<!-- { active: isActive,danger: false }是一个对象,对象的key对应的值可以是model的key,也可以是boolean值 -->
<div v-bind:class="{ active: isActive,danger: false }"></div>
<br /><br />
<!-- classObj是对象的名称(model的key) -->
<div v-bind:class="classObj"></div>
</div>
<script>
new Vue({
el: "#vue-app",
data: {
isActive: true,
classObj: { active: true, danger: true },
},
});
</script>
</body>
</html>
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
# 2. style(内联样式)属性绑定
- 在:style 中通过 key 引用 data 中的样式对象
<h1 :style="styleObj1">这是一个h1</h1>
- 在:style 中通过数组,引用多个 data 上的样式对象
<h1 :style="[ styleObj1, styleObj2 ]">这是一个h1</h1>
案例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="app">
<!-- 在:style中通过key引用data中的样式对象 -->
<h1 :style="styleObj1">这是一个h1</h1>
<br /><br />
<!-- 在:style中通过数组,引用多个data上的样式对象 -->
<h1 :style="[ styleObj1, styleObj2 ]">这是一个h1</h1>
</div>
<script>
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: "#app",
data: {
styleObj1: { color: "red", "font-weight": 200 },
styleObj2: { "font-style": "oblique" },
},
methods: {},
});
</script>
</body>
</html>
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
# 7,条件句式
# 1,v-for
与大多数编程语言的循环语句用法都差不多,Vue 中使用反而更加简单。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>learn vue</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<!--引入vue.js-->
</head>
<body>
<div id="app">
<!-- 1,遍历数字 -->
<!-- v-for可以遍历数组,对象数组,对象,以及数字(数字将会从1开始) -->
<!-- 每遍历一次就会生成一个v-for绑定的元素 -->
<p v-for="count in 10">这是第 {{ count }} 次循环</p>
<!-- 2,遍历普通数组 -->
<!-- 数组下标从0开始 -->
<p>{{list[0]}}</p>
<p>{{list[1]}}</p>
<p v-for="(item,i) in list">索引为{{ i }}的值为{{ item }}</p>
<!-- 3,遍历对象,跟普通数组差不多,每个对象为一个元素,元素有下标,对象有键值对 -->
<p v-for="(val,key,i) in user">键是:{{key}}值是:{{val}}索引为:{{i}}</p>
<p v-for="(user,i) in users">
Id: {{user.id}} 名字: {{user.name}} 索引:{{i}}
</p>
</div>
</body>
<script>
// 自定义全局按键修饰符
Vue.config.keyCodes.f2 = 113;
new Vue({
el: "#app",
data: {
list: [1, 2, 3, 4, 5],
user: {
id: 1,
name: "eryajf",
gender: "man",
},
users: [
{ id: 1, name: "test1" },
{ id: 2, name: "test2" },
{ id: 3, name: "test3" },
],
},
methods: {},
});
</script>
</html>
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
# 2,v-if
v-if 指令将根据表达式的值(true 或 false )来决定是否插入绑定的元素。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>learn vue</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<!--引入vue.js-->
</head>
<body>
<div id="app">
<p v-if="flag1">p1</p>
<p v-if="flag2">p2</p>
</div>
</body>
<script>
// 自定义全局按键修饰符
Vue.config.keyCodes.f2 = 113;
new Vue({
el: "#app",
data: {
flag1: true,
flag2: false,
},
methods: {},
});
</script>
<style>
p {
width: 100px;
height: 100px;
text-align: center;
line-height: 100px;
background-color: red;
}
</style>
</html>
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
当然在实际使用当中,可能还会遇上更加复杂的判断,到时候在根据实际场景进行活用。
# 3,v-if、v-else、v-else-if
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>learn vue</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<!--引入vue.js-->
</head>
<body>
<div id="app">
<div v-if="type === 'A'">A</div>
<div v-else-if="type === 'B'">B</div>
<div v-else-if="type === 'C'">C</div>
<div v-else>Not A/B/C</div>
</div>
</body>
<script>
// 自定义全局按键修饰符
Vue.config.keyCodes.f2 = 113;
new Vue({
el: "#app",
data: {
type: "A",
},
methods: {},
});
</script>
</html>
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
# 4,v-show
根据条件展示或者隐藏元素,而不是像 v-if 那样插入或者删除元素
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>learn vue</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<!--引入vue.js-->
</head>
<body>
<div id="app">
<p v-show="flag1">p1</p>
<p v-show="flag2">p2</p>
</div>
</body>
<script>
// 自定义全局按键修饰符
Vue.config.keyCodes.f2 = 113;
new Vue({
el: "#app",
data: {
flag1: true,
flag2: false,
},
methods: {},
});
</script>
<style>
p {
width: 100px;
height: 100px;
text-align: center;
line-height: 100px;
background-color: red;
}
</style>
</html>
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
# 5,v-if 和 v-show 的区别
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>v-if和v-show</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="app">
<!-- 需求:通过点击修改flag的值。 -->
<!--
v-if 的特点:每次都会重新删除或创建元素。有较高的切换性能消耗。
v-show 的特点: 每次不会重新进行DOM的删除和创建操作,只是切换了元素的 display:none 样式。有较高的初始渲染消耗
选择:
如果元素涉及到频繁的切换,最好不要使用 v-if, 而是推荐使用 v-show。
如果元素可能永远也不会被显示出来被用户看到,则推荐使用 v-if。
-->
<input type="button" value="toggle" @click="flag=!flag" />
<h3 v-if="flag">这是用v-if控制的元素</h3>
<h3 v-show="flag">这是用v-show控制的元素</h3>
</div>
<script>
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: "#app",
data: {
flag: false,
},
});
</script>
</body>
</html>
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
# 8,其他一些概念
# 1,过滤器
概念:Vue.js 允许自定义过滤器,可被用作一些常见的文本格式化。过滤器可以用在两个地方:插值表达式和 v-bind 表达式。过滤器应该被添加在 JavaScript 表达式的尾部,由**“管道”**符指示。
过滤器调用的格式:
{{ name | 过滤器的名称(实参列表) }}
过滤器的定义语法:
- 全局过滤器
Vue.filter('过滤器的名称', function(过滤器的参数列表){
//过滤器做的处理
})
2
3
- 私有(局部)过滤器
filters: {
过滤器的名称: function (过滤器的参数列表) {
//过滤器做的处理
}
}
2
3
4
5
第一个参数是管道前的内容,第二个之后的参数是过滤器调用方法的实参列表。
概念:Vue.js 允许自定义过滤器,可被用作一些常见的文本格式化。过滤器可以用在两个地方:插值表达式和 v-bind 表达式。过滤器应该被添加在 JavaScript 表达式的尾部,由**“管道”**符指示。
过滤器调用的格式:
{{ name | 过滤器的名称(实参列表) }}
过滤器的定义语法:
- 全局过滤器
Vue.filter('过滤器的名称', function(过滤器的参数列表){
//过滤器做的处理
})
2
3
- 私有(局部)过滤器
filters: {
过滤器的名称: function (过滤器的参数列表) {
//过滤器做的处理
}
}
2
3
4
5
第一个参数是管道前的内容,第二个之后的参数是过滤器调用方法的实参列表。
# 1, 全局过滤器
对所有VM
对象所控制的 View
区域都起作用。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="app1">
<h1>app1</h1>
<p>过滤前的内容:{{ msg}}</p>
<p>经全局过滤器处理后: {{ msg | globalFormat('global', 'filter')}}</p>
</div>
<div id="app2">
<h1>app2</h1>
<p>过滤前的内容:{{ msg}}</p>
<p>经全局过滤器处理后: {{ msg | globalFormat('global', 'filter')}}</p>
</div>
<script>
//定义全局过滤器(对所有VM对象所控制的View区域都起作用。)
Vue.filter("globalFormat", function (msg, arg, arg2) {
//定义一个 Vue 全局的过滤器,名字叫做 localFormat,第一个参数是管道前的内容,其余参数是localFormat()过滤器方法的实参
//过滤器做的处理
return msg.replace(/vue/g, arg + " " + arg2); //字符串的 replace 方法,第一个参数,除了可写一个 字符串之外,还可以定义一个正则
});
var vm1 = new Vue({
el: "#app1",
data: {
msg: "hello vue1",
},
});
var vm2 = new Vue({
el: "#app2",
data: {
msg: "hello vue2",
},
});
</script>
</body>
</html>
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
# 2,私有过滤器
私有(局部)过滤器。只能在当前 VM 对象所控制的 View 区域起作用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="app1">
<h1>app1</h1>
<p>过滤前的内容:{{ msg}}</p>
<p>经全局过滤器处理后: {{ msg | localFormat('local', 'filter')}}</p>
</div>
<div id="app2">
<h1>app2</h1>
<p>过滤前的内容:{{ msg}}</p>
<p>经全局过滤器处理后: {{ msg | localFormat('local', 'filter')}}</p>
</div>
<script>
var vm1 = new Vue({
el: "#app1",
data: {
msg: "hello vue1",
},
filters: {
//定义私有(局部)过滤器。只能在 当前 VM 对象所控制的 View 区域起作用
localFormat: function (msg, arg, arg2) {
//默认将管道前的内容当作localFormat()过滤器方法的第一个实参,其余参数是localFormat()过滤器方法的实参
//过滤器做的处理
return msg.replace(/vue/g, arg + " " + arg2); //字符串的 replace 方法,第一个参数,除了可写一个 字符串之外,还可以定义一个正则
},
},
});
var vm2 = new Vue({
el: "#app2",
data: {
msg: "hello vue2",
},
});
</script>
</body>
</html>
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
# 2,自定义指令
除了核心功能默认内置的指令 (v-model
和 v-show
),Vue
也允许注册自定义指令。
实现自定义指令可以是全局的,也可以是局部的。全局指的是所有vue
对象的控制区域,局部指的是当前定义指令所在vue
对象的控制区域。
案例:用指令来实现开页面后还没点击过任何内容,输入框就处于聚焦状态,并且要求用指令实现输入的内容颜色为可变实参。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="app">
<!-- 如果需要给自定义指令传参,那么需要在双引号里使用单引号把实参包含住,否则会报错 -->
<input type="text" v-focus v-color="'green'" />
</div>
<script>
/*注册全局自定义指令 v-focus*/
/*
使用 Vue.directive() 定义全局的指令 v-focus
其中:
参数1 : 指令的名称,注意,在定义的时候,指令的名称前面,不需要加 v- 前缀, 但是: 在调用的时候,必须 在指令名称前 加上 v- 前缀来进行调用
参数2: 是一个对象,这个对象身上,有一些指令相关的函数,这些函数可以在特定的阶段,执行相关的操作。常用的有三个方法:1.bind() 2.inserted() 3.updated()。一般动作指令在inserted()中调用,而样式等在bind()中调用。
*/
Vue.directive("focus", {
bind: function (el) {
// 每当指令绑定到元素上的时候,会立即执行这个 bind 函数,只执行一次
// 注意: 在每个 函数中,第一个参数,永远是 el ,表示 被绑定了指令的那个元素,这个 el 参数,是一个原生的JS对象
// 在元素 刚绑定了指令的时候,还没有 插入到 DOM中去,这时候,调用 focus 方法没有作用
// 因为,一个元素,只有插入DOM之后,才能获取焦点
// el.focus()
},
// 当被绑定的元素插入到 DOM 中时……
inserted: function (el) {
// 聚焦元素
el.focus();
},
updated: function (el) {
// 当VNode更新的时候,会执行 updated, 可能会触发多次
},
});
/*注册全局指令v-color*/
Vue.directive("color", {
bind: function (el, binding) {
el.style.color = binding.value;
},
});
new Vue({
el: "#app",
/*注册局部自定义指令 v-focus,如果全局和局部自定义指令的名称相同,那么vue会采取就近原则。*/
directives: {
focus: {
// 指令的定义
inserted: function (el) {
el.focus();
},
},
color: function (el, binding) {
el.style.color = binding.value;
},
},
});
</script>
</body>
</html>
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
# 9,生命周期
# 1. 概念
- 什么是生命周期:从 Vue 实例创建、运行、到销毁期间,总是伴随着各种各样的事件,这些事件,统称为生命周期!
- 生命周期钩子 (opens new window):就是生命周期事件的别名;
- 生命周期钩子 = 生命周期函数 = 生命周期事件
# 2. 生命周期函数分类
创建期间的生命周期函数
- (1)beforeCreate //实例刚在内存中被创建出来,此时,还没有初始化好 data 和 methods 属性
- (2)created //实例已经在内存中创建 OK,此时 data 和 methods 已经创建 OK,此时还没有开始 编译模板
- (3)beforeMount //此时已经完成了模板的编译,但是还没有挂载到页面中
- (4)mounted //此时,已经将编译好的模板,挂载到了页面指定的容器中显示
运行期间的生命周期函数
- (1)beforeUpdate //状态更新之前执行此函数, 此时 data 中的状态值是最新的,但是界面上显示的 数据还是旧的,因为此时还没有开始重新渲染 DOM 节点
- (2)updated //实例更新完毕之后调用此函数,此时 data 中的状态值 和 界面上显示的数据,都已经完成了更新,界面已经被重新渲染好了!
销毁期间的生命周期函数
- 1.beforeDestroy //实例销毁之前调用。在这一步,实例仍然完全可用。
- 2.destroyed //Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。