Vue2.0学习笔记

本文最后更新于:2 年前

项目搭建

下载 Vue2.0 的两个版本:

Vue官方网站:

  • 开发版本:包含完整的警告和调试模式
  • 生产版本:删除了警告,进行了压缩

项目结构搭建

1.在根目录创建文件夹 assets 文件夹,并将 css 和 js 文件夹放入其中,然后将下载的两个 vue..js 和 vue.min.js 放到下 js 文件夹下 2.在根目录下创建实例文件夹 example,其中放入第一个实例文件 helloworld.html 3.根目录下创建入口文件 index.html
index.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vue.js实例</title>
</head>
<body>
<h1>Vue2.0实例</h1>
<hr />
<ol>
<li><a href="./example/helloworld.html">Hello World 实例</a></li>
</ol>
</body>
</html>

4.生成 package.json 配置文件
用 npm 进行初始化
npm init
根据提示写入 package name:项目名,version 版本号 ,description 描述,entry point 入口文件,author 作者等等

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
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help init` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (vue2.0) vue2.0
version: (1.0.0)
description: Vue demo
entry point: (index.js)
test command:
git repository:
keywords:
author: jackhoo
license: (ISC)
About to write to E:\web\vue\VUE2.0\package.json:

{
"name": "vue2.0",
"version": "1.0.0",
"description": "Vue demo",
"main": "index.js",
"directories": {
"example": "example"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "jackhoo",
"license": "ISC"


Is this OK? (yes)

5.live-server 使用
用 npm 进行全局安装
npm install live-server -g
在项目目录中打开
live-server
在 example\helloworld.html 编写第一个 HelloWorld 代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>HelloWord</title>
<script type="text/javascript" src="../assets/js/vue.js"></script>
</head>
<body>
<h1>HelloWorld</h1>
<hr />
<div id="app">{{message}}</div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
message: 'Hello World',
},
});
</script>
</body>
</html>

指令

v-if & v-else & v-show

1.v-if 的使用:

v-if:是 vue 的一个内部指令,指令用在我们的 html 中。
v-if 用来判断是否加载 html 的 DOM,比如我们模拟一个用户登录状态,在用户登录后现实用户名称。

在 index.html 文件中新增一行代码

1
2
3
<li>
<a href="./example/v-if.html">v-if&v-else&v-show</a>
</li>

新建文件 example\v-if.html 关键代码:

1
<div v-if="isLogin">你好</div>

v-if.html

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="../assets/js/vue.js"></script>
<title>v-if & v-show & v-else</title>
</head>
<body>
<h1>v-if 判断是否加载</h1>
<hr>
<div id="app">
<div v-if="isLogin">你好:JSPang</div>
<div v-else>请登录后操作</div>

</div>

<script type="text/javascript">
var app=new Vue({
el:'#app',
data:{
isLogin:false
}
})
</script>
</body>
</html>

这里我们在 vue 的 data 里定义了 isLogin 的值,当它为 true 时,网页就会显示:你好,如果为 false 时,就显示请登录后操作。

2.v-show 的使用:

调整 css 中 display 属性,DOM 已经加载,只是 CSS 控制没有显示出来。

1
<div v-show="isLogin">你好</div>

v-if 和 v-show 的区别:

v-if: 判断是否加载,可以减轻服务器的压力,在需要时加载。
v-show:调整 css dispaly 属性,可以使客户端操作更加流畅。

v-for

v-for 指令 :解决模板循环问题

v-for 指令是循环渲染一组 data 中的数组,v-for 指令需要以 item in items 形式的特殊语法,items 是源数据数组并且 item 是数组元素迭代的别名。

一、基本用法:模板写法

index.html中添加

1
2
3
<li>
<a href="./example/v-for.html">v-for 实例</a>
</li>

在 example 中新建v-for.html

1
<li v-for="item in items">{{ item }}</li>

js 写法

1
2
3
4
5
6
var app = new Vue({
el: '#app',
data: {
items: [20, 23, 18, 65, 32, 19, 54, 56, 41],
},
});

完整代码:

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="../assets/js/vue.js"></script>
<title>V-for 案例</title>
</head>
<body>
<h1>v-for指令用法</h1>
<hr>
<div id="app">
<ul>
<li v-for="item in items">
{{item}}
</li>
</ul>
</div>

<script type="text/javascript">
var app=new Vue({
el:'#app',
data:{
items:[20,23,18,65,32,19,54,56,41]
}
})
</script>
</body>
</html>

这是一个最基础的循环,先在 js 里定义了 items 数组,然后在模板中用 v-for 循环出来,需要注意的是,你需要那个 html 标签循环,v-for 就写在那个上边。

二、排序

我们已经顺利的输出了我们定义的数组,但是我需要在输出之前给数组排个序,那我们就用到了 Vue 的 computed:属性。

1
2
3
4
5
computed:{
sortItems:function(){
return this.items.sort();
}
}

我们在 computed 里新声明了一个对象 sortItems,如果不重新声明会污染原来的数据源,这是 Vue 不允许的,所以你要重新声明一个对象。

如果一切顺利的话,你已经看到了结果,但是这个小程序还是有个小 Bug 的,现在我把数组修改成这样。

1
items: [20, 23, 18, 65, 32, 19, 5, 56, 41];

我们把其中的 54 修改成了 5,我们再看一下结果,发现排序结果并不是我们想要的。

我们可以自己编写一个方法 sortNumber,然后传给我们的 sort 函数解决这个 Bug。

1
2
3
function sortNumber(a, b) {
return a - b;
}

用法

1
2
3
4
5
computed:{
sortItems:function(){
return this.items.sort(sortNumber);
}
}

经过一番折腾,我们终于实现了真正的数字排序,这是在工作中非常常用的,一定要学好,记住。

三、对象循环输出

我们上边循环的都是数组,那我们来看一个对象类型的循环是如何输出的。

我们先定义个数组,数组里边是对象数据

1
2
3
4
5
6
students: [
{ name: 'jspang', age: 32 },
{ name: 'Panda', age: 30 },
{ name: 'PanPaN', age: 21 },
{ name: 'King', age: 45 },
];

在模板中输出

1
2
3
4
5
<ul>
<li v-for="student in students">
{{student.name}} - {{student.age}}
</li>
</ul>

加入索引序号:

1
2
3
4
5
6
7
8
//数组对象方法排序:
function sortByKey(array, key) {
return array.sort(function (a, b) {
var x = a[key];
var y = b[key];
return x < y ? -1 : x > y ? 1 : 0;
});
}

有了数组的排序方法,在 computed 中进行调用排序

1
2
3
sortStudent:function(){
return sortByKey(this.students,'age');
}

注意:vue 低版本中 data 里面的 items 和 computed 里面可以一样,但是高版本,是不允许相同名称。有很多小伙伴踩到了这个坑,这里提醒学习的小伙伴,根据自己版本的不同,请修改代码。
v-for.html

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>v-for</title>
<script type="text/javascript" src="../assets/js/vue.js"></script>
</head>
<body>
<h1>v-for</h1>
<hr />
<div id="app">
<ul>
<li v-for="item in sortItems">{{item}}</li>
</ul>
<ul>
<li v-for="(student,index) in students">
{{index+1}}: {{student.name}} -- {{student.age}}
</li>
</ul>
</div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
items: [20, 23, 7, 18, 65, 32, 19, 54, 56, 41],
students: [
{ name: 'jspang', age: 32 },
{ name: 'Panda', age: 30 },
{ name: 'PanPaN', age: 21 },
{ name: 'King', age: 45 },
],
},
computed: {
sortItems: function () {
return this.items.sort(sortNumber);
},

sortStudent: function () {
return sortByKey(this.students, 'age');
},
},
});
function sortNumber(a, b) {
return a - b;
}
//数组对象方法排序:
function sortByKey(array, key) {
return array.sort(function (a, b) {
var x = a[key];
var y = b[key];
return x < y ? -1 : x > y ? 1 : 0;
});
}
</script>
</body>
</html>

v-text & v-html

我们已经会在 html 中输出 data 中的值了,我们已经用的是,这种情况是有弊端的,就是当我们网速很慢或者 javascript 出错时,会暴露我们的。Vue 给我们提供的 v-text,就是解决这个问题的。
在 index.html 中添加代码

1
2
3
<li>
<a href="./example/v-text.html">v-text & v-html 实例</a>
</li>

在 example 中新建 v-text.html
关键代码:

1
<span>{{ message }}</span>=<span v-text="message"></span><br/>

如果在 javascript 中写有 html 标签,用 v-text 是输出不出来的,这时候我们就需要用 v-html 标签了。

1
<span v-html="msgHtml"></span>

双大括号会将数据解释为纯文本,而非 HTML。为了输出真正的 HTML,你就需要使用 v-html 指令。 需要注意的是:在生产环境中动态渲染 HTML 是非常危险的,因为容易导致 XSS 攻击。所以只能在可信的内容上使用 v-html,永远不要在用户提交和可操作的网页上使用。 完整代码:

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="../assets/js/vue.js"></script>
<title>v-text & v-html 案例</title>
</head>
<body>
<h1>v-text & v-html 案例</h1>
<hr>
<div id="app">
<span>{{ message }}</span>=<span v-text="message"></span><br/>
<span v-html="msgHtml"></span>
</div>

<script type="text/javascript">
var app=new Vue({
el:'#app',
data:{
message:'hello Vue!',
msgHtml:'<h2>hello Vue!</h2>'
}
})
</script>
</body>
</html>

v-on:绑定事件监听器

v-on 就是监听事件,可以用 v-on 指令监听 DOM 事件来触发一些 javascript 代码。

一、使用绑定事件监听器,编写一个加分减分的程序。

在 index.html 中添加

1
2
3
<li>
<a href="./example/v-on.html">v-on 实例</a>
</li>

在 example 中新建 v-on.html
我们的 v-on 还有一种简单的写法,就是用@代替。

1
<button @click="jianfen">减分</button>

我们除了绑定 click 之外,我们还可以绑定其它事件,比如键盘回车事件 v-on:keyup.enter,现在我们增加一个输入框,然后绑定回车事件,回车后把文本框里的值加到我们的 count 上。 绑定事件写法:

1
<input type="text" v-on:keyup.enter="onEnter" v-model="secondCount">

javascript 代码:

1
2
3
onEnter:function(){
this.count=this.count+parseInt(this.secondCount);
}

因为文本框的数字会默认转变成字符串,所以我们需要用 parseInt()函数进行整数转换。

你也可以根据键值表来定义键盘事件:
v-on.html

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<script type="text/javascript" src="../assets/js/vue.js"></script>
<title>v-on事件监听器</title>
</head>
<body>
<h1>v-on 事件监听器</h1>
<hr />
<div id="app">
本场比赛得分: {{count}}


<button v-on:click="jiafen">加分</button>
<button @click="jianfen">减分</button>
<hr />
<input type="text" v-on:keyup.enter="onEnter" v-model="secondCount" />
</div>

<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
count: 1,
secondCount: 1,
},
methods: {
jiafen: function () {
this.count++;
},
jianfen: function () {
this.count--;
},
onEnter: function () {
this.count = this.count + parseInt(this.secondCount);
},
},
});
</script>
</body>
</html>

v-model 指令

v-model 指令,我理解为绑定数据源。就是把数据绑定在特定的表单元素上,可以很容易的实现双向数据绑定。
在 index.html 中添加代码

1
2
3
<li>
<a href="./example/v-model.html">v-model 实例</a>
</li>

在 example 中新建 v-model.html

一、我们来看一个最简单的双向数据绑定代码:

html 文件

1
2
3
4
5
<div id="app">
<p>原始文本信息:{{message}}</p>
<h3>文本框</h3>
<p>v-model:<input type="text" v-model="message"></p>
</div>

javascript 代码:

1
2
3
4
5
6
var app = new Vue({
el: '#app',
data: {
message: 'hello Vue!',
},
});

二、修饰符

  • .lazy:取代 imput 监听 change 事件。
  • .number:输入字符串转为数字。
  • .trim:输入去掉首尾空格。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<h3>文本框</h3>
<p><input type="text" v-on:keyup.enter="onEnter" v-model="message" /></p>

<p>
v-model:
<input type="text" v-on:keyup.enter="onEnter" v-model="message" />
</p>
<p>
v-model.lazy:
<input type="text" v-on:keyup.enter="onEnter" v-model.lazy="message" />
</p>
<p>
v-model.number:
<input type="text" v-on:keyup.enter="onEnter" v-model.number="message" />
</p>
<p>
v-model.trim:
<input type="text" v-on:keyup.enter="onEnter" v-model.trim="message" />
</p>

三、文本区域加入数据绑定

1
<textarea  < cols="30" rows="10" v-model="message"></textarea>

四、多选按钮绑定一个值

注意**v-model**绑定的值要在**data:{}**中声明

1
2
3
<h3>多选按钮绑定一个值</h3>
<input type="checkbox" id="isTrue" v-model="isTrue">
<label for='isTrue'>{{isTrue}}</label>

五、多选绑定一个数组

1
2
3
4
5
6
7
8
9
10
<h3>多选绑定一个数组</h3>
<p>
<input type="checkbox" id="JSPang" value="JSPang" v-model="web_Names">
<label for="JSPang">JSPang</label><br/>
<input type="checkbox" id="Panda" value="Panda" v-model="web_Names">
<label for="JSPang">Panda</label><br/>
<input type="checkbox" id="PanPan" value="PanPan" v-model="web_Names">
<label for="JSPang">PanPan</label>
<p>{{web_Names}}</p>
</p>

六、单选按钮绑定数据

1
2
3
4
5
6
<h3>单选按钮绑定</h3>
<input type="radio" id="one" value="男" v-model="sex">
<label for="one">男</label>
<input type="radio" id="two" value="女" v-model="sex">
<label for="one">女</label>
<p>{{sex}}</p>

v-model.html

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<script type="text/javascript" src="../assets/js/vue.js"></script>
<title>v-model 数据源绑定</title>
</head>
<body>
<h1>v-model 数据原绑定</h1>
<hr />
<div id="app">
<p>原始文本数据:{{message}}</p>
<hr />
<h3>文本框</h3>
<p><input type="text" v-on:keyup.enter="onEnter" v-model="message" /></p>

<p>
v-model:
<input type="text" v-on:keyup.enter="onEnter" v-model="message" />
</p>
<p>
v-model.lazy:
<input type="text" v-on:keyup.enter="onEnter" v-model.lazy="message" />
</p>
<p>
v-model.number:
<input type="text" v-on:keyup.enter="onEnter" v-model.number="message" />
</p>
<p>
v-model.trim:
<input type="text" v-on:keyup.enter="onEnter" v-model.trim="message" />
</p>
<hr />
<h3>文本域</h3>
<textarea cols="30" rows="10"></textarea>
<hr />
<h3>多选框绑定一个值</h3>
<p>
<input type="checkbox" id="isTrue" v-model="isTrue" />
<label for="isTrue">{{isTrue}}</label>
</p>
<h3>多选框绑定数组</h3>
<p>
<input type="checkbox" id="jack1" value="jack1" v-model="web_names" />
<label for="isTrue">jack1</label>
<input type="checkbox" id="jack2" value="jack2" v-model="web_names" />
<label for="isTrue">jack2</label>
<input type="checkbox" id="jack3" value="jack3" v-model="web_names" />
<label for="isTrue">jack3</label>
</p>
<p>{{web_names}}</p>
<hr />
<h3>单选框绑定数组</h3>
<p>
<input type="radio" id="one" value="男" v-model="sex" />
<label for="one"></label>
<input type="radio" id="two" value="女" v-model="sex" />
<label for="two"></label>
<p>你选择的性别是:{{sex}}</p>
</p>
</div>

<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
message: 'hello world',
isTrue: true,
web_names: [],
sex: '男',
},
});
</script>
</body>
</html>

v-bind:指令

v-bind 是处理 HTML 中的标签属性的,就是一个标签,我们绑定上的 src 进行动态赋值。
在 index.html 中添加

1
2
3
<li>
<a href="./example/v-bind.html">v-bind 案例</a>
</li>

在 example 中新建 v-bind.html
html 文件:

1
<img v-bind:src="imgSrc" width="200px" />

在 html 中我们用 v-bind:src=”imgSrc”的动态绑定了 src 的值,这个值是在 vue 构造器里的 data 属性中找到的。
js 文件:

1
2
3
4
5
6
var app = new Vue({
el: '#app',
data: {
imgSrc: './1.jpeg',
},
});

我们在 data 对象在中增加了 imgSrc 属性来供 html 调用。

v-bind 缩写

1
2
3
4
<!-- 完整语法 -->
<a v-bind:href="url"></a>
<!-- 缩写 -->
<a :href="url"></a>

绑定 CSS 样式

在工作中我们经常使用 v-bind 来绑定 css 样式:
在绑定 CSS 样式是,绑定的值必须在 vue 中的 data 属性中进行声明。

1、直接绑定 class 样式

1
<div :class="className">1、绑定classA</div>

2、绑定 classA 并进行判断,在 isOK 为 true 时显示样式,在 isOk 为 false 时不显示样式。

1
<div :class="{classA:isOk}">2、绑定class中的判断</div>

3、绑定 class 中的数组

1
<div :class="[classA,classB]">3、绑定class中的数组</div>

4、绑定 class 中使用三元表达式判断

1
<div :class="isOk?classA:classB">4、绑定class中的三元表达式判断</div>

5、绑定 style

1
<div :style="{color:red,fontSize:font}">5、绑定style</div>

6、用对象绑定 style 样式

1
<div :style="styleObject">6、用对象绑定style样式</div>

v-bind.html

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>v-bind案例</title>
<script type="text/javascript" src="../assets/js/vue.js"></script>
</head>
<body>
<h1>v-bind案例</h1>
<hr />
<div id="app">
<img v-bind:src="imgSrc" width="200px" />


<a :href="jspang" target="_blank">技术胖</a>
<hr />
<div :class="className">1、绑定classA</div>
<div :class="{classA:isOk}">2、绑定class中的判断</div>
<div :class="[classA,classB]">3、绑定class中的数组</div>
<div :class="isOk?classA:classB">4、绑定class中的三元表达式判断</div>
<hr />
<input type="checkbox" id="isTrue" v-model="isOk" />
<label for="isTrue">isOk={{isOk}}</label>
<hr />
<div :style="{color:red,fontSize:font}">5、绑定style</div>
<div :style="styleObject">6、用对象绑定style样式</div>
</div>
<style>
.classA {
color: red;
}
.classB {
font-size: 150%;
}
</style>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
imgSrc: './1.jpeg',
jspang: 'http://jspang.com',
className: 'classA',
isOk: false,
classA: 'classA',
classB: 'classB',
red: 'red',
font: '30px',
styleObject: {
fontSize: '24px',
color: 'green',
},
},
});
</script>
</body>
</html>

其他内部指令(v-pre & v-cloak & v-once)

在 index.html 中添加

1
2
3
<li>
<a href="./example/other.html">v-bind 案例</a>
</li>

在 example 中新建 other.html

v-pre 指令

在模板中跳过 vue 的编译,直接输出原始值。就是在标签中加入 v-pre 就不会输出 vue 中的 data 值了。

1
<div v-pre>{{ message }}--原样输出不渲染</div>

这时并不会输出我们的 message 值,而是直接在网页中显示

v-cloak 指令

在 vue 渲染完指定的整个 DOM 后才进行显示。它必须和 CSS 样式一起使用,

1
[v-cloak] {   display: none; }
1
div v-cloak>   {{ message }} </div>

v-once 指令

在第一次 DOM 时进行渲染,渲染完成后视为静态内容,跳出以后的渲染过程。

1
2
<div v-once>第一次绑定的值:{{message}}</div>
<div><input type="text" v-model="message"></div>

other.html

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>v-pre & v-cloak &v-once 案例</title>
<script type="text/javascript" src="../assets/js/vue.js"></script>
</head>
<body>
<h1>v-pre & v-cloak &v-once 案例</h1>
<hr />
<div id="app">
<div v-pre>{{message}}--原样输出不渲染</div>
<div v-cloak>渲染完成才显示</div>
<div v-once>{{message}}--只渲染一次</div>
<div><input type="text" v-model="message" /></div>
<div>{{message}}</div>
</div>
<style>
[v-cloak] {
display: none;
}
</style>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
message: 'Hello World',
},
});
</script>
</body>
</html>

全局 API

Vue.directive 自定义指令

一、什么是全局 API?

全局 API 并不在构造器里,而是先声明全局变量或者直接在 Vue 上定义一些新功能,Vue 内置了一些全局 API,比如我们今天要学习的指令 Vue.directive。说的简单些就是,在构造器外部用 Vue 提供给我们的 API 函数来定义新的功能。

二、Vue.directive 自定义指令

我们也可以定义一些属于自己的指令,比如我们要定义一个 v-jspang 的指令,作用就是让文字变成绿色。在自定义指令前我们写一个小功能,在页面上有一个数字为 10,数字的下面有一个按钮,我们每点击一次按钮后,数字加 1.
在 index.html 中添加代码

1
2
3
<li>
<a href="./example/vue.directive.html">directive 自定义指令</a>
</li>

在 example 中添加 vue.directive.html 文件
我们这里使用 Vue.directive( );

1
2
3
Vue.directive('jspang', function (el, binding, vnode) {
el.style = 'color:' + binding.value;
});
1
2
3
4
5
6
7
var app = new Vue({
el: '#app',
data: {
num: 10,
color: 'red',
},
});

可以看到数字已经变成了红色,说明自定义指令起到了作用。可能您看这个代码还是有些不明白的,比如传入的三个参数到底是什么。

三、自定义指令中传递的三个参数

  • el: 指令所绑定的元素,可以用来直接操作 DOM。
  • binding: 一个对象,包含指令的很多信息。
  • vnode: Vue 编译生成的虚拟节点。

四、自定义指令的生命周期

自定义指令有五个生命周期(也叫钩子函数),分别是 bind,inserted,update,componentUpdated,unbind

  1. bind:只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个绑定时执行一次的初始化动作。
  2. inserted:被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于 document 中)。
  3. update:被绑定于元素所在的模板更新时调用,而无论绑定值是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新。
  4. componentUpdated:被绑定元素所在模板完成一次更新周期时调用。
  5. unbind:只调用一次,指令与元素解绑时调用。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
bind:function(){//被绑定
console.log('1 - bind');
},
inserted:function(){//绑定到节点
console.log('2 - inserted');
},
update:function(){//组件更新
console.log('3 - update');
},
componentUpdated:function(){//组件更新完成
console.log('4 - componentUpdated');
},
unbind:function(){//解绑
console.log('5- unbind');
}

vue.directive.html

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>vue.directive 自定义指令</title>
<script type="text/javascript" src="../assets/js/vue.js"></script>
</head>
<body>
<h1>vue.directive 自定义指令</h1>
<hr />
<div id="app">
<div v-jspang="color">{{num}}</div>
<p>
<button @click="add">ADD</button>
</p>
</div>
<p>
<button onclick="unbind()">解绑</button>
</p>
<script type="text/javascript">
// Vue.directive('jspang', function (el, binding) {
// console.log(el);
// console.log(binding);
// el.style = 'color:' + binding.value;
// });

function unbind() {
app.$destroy();
}
Vue.directive('jspang', {
bind: function (el, binding) {
//被绑定
console.log('1 - bind');
el.style = 'color:' + binding.value;
},
inserted: function () {
//绑定到节点
console.log('2 - inserted');
},
update: function () {
//组件更新
console.log('3 - update');
},
componentUpdated: function () {
//组件更新完成
console.log('4 - componentUpdated');
},
unbind: function () {
//解绑
console.log('5 - unbind');
},
});

var app = new Vue({
el: '#app',
data: {
num: 10,
color: 'red',
},
methods: {
add: function () {
this.num++;
},
},
});
</script>
</body>
</html>

Vue.extend 构造器的延伸

一、什么是 Vue.extend

Vue.extend 返回的是一个“扩展实例构造器”,也就是预设了部分选项的 Vue 实例构造器。经常服务于 Vue.component 用来生成组件,可以简单理解为当在模板中遇到该组件名称作为标签的自定义元素时,会自动调用“扩展实例构造器”来生产组件实例,并挂载到自定义元素上。
由于我们还没有学习 Vue 的自定义组件,所以我们先看跟组件无关的用途。

二、自定义无参数标签

我们想象一个需求,需求是这样的,要在博客页面多处显示作者的网名,并在网名上直接有链接地址。我们希望在 html 中只需要写,这和自定义组件很像,但是他没有传递任何参数,只是个静态标签。
在 index.html 中添加代码

1
2
3
<li>
<a href="./example/vue.extend.html">directive 自定义指令</a>
</li>

在 example 中添加 vue.extend.html 文件
我们的 Vue.extend 该登场了,我们先用它来编写一个扩展实例构造器。代码如下:

1
2
3
4
5
6
7
8
9
var authorExtend = Vue.extend({
template: "<p><a :href='authorUrl'>{{authorName}}</a></p>",
data: function () {
return {
authorName: 'JSPang',
authorUrl: 'http://www.jspang.com',
};
},
});

这时 html 中的标签还是不起作用的,因为扩展实例构造器是需要挂载的,我们再进行一次挂载。

1
new authorExtend().$mount('author');

这时我们在 html 写就是管用的。

三、挂载到普通标签上

还可以通过 HTML 标签上的 id 或者 class 来生成扩展实例构造器,Vue.extend 里的代码是一样的,只是在挂载的时候,我们用类似 jquery 的选择器的方法,来进行挂载就可以了。

1
new authorExtend().$mount('#author');

vue.extend.html

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>vue.extend 扩展实例构造器</title>
<script type="text/javascript" src="../assets/js/vue.js"></script>
</head>
<body>
<h1>vue.extend 扩展实例构造器</h1>
<hr />
<div id="author"></div>
<author></author>
<script type="text/javascript">
var authorExtend = Vue.extend({
template: "<p><a :href='authorURL'>{{authorName}}</a></p>",
data: function () {
return {
authorName: 'JSP',
authorURL: 'http://jspang.com',
};
},
});
new authorExtend().$mount('#author');
new authorExtend().$mount('author');
</script>
</body>
</html>

Vue.set 全局操作

Vue.set 的作用就是在构造器外部操作构造器内部的数据、属性或者方法。比如在 vue 构造器内部定义了一个 count 为 1 的数据,我们在构造器外部定义了一个方法,要每次点击按钮给值加 1.就需要用到 Vue.set。
在 index.html 中添加代码

1
2
3
<li>
<a href="./example/vue.set.html">vue.set 全局操作</a>
</li>

在 example 中添加 vue.set.html 文件

一、引用构造器外部数据:

什么是外部数据,就是不在 Vue 构造器里里的 data 处声明,而是在构造器外部声明,然后在 data 处引用就可以了。外部数据的加入让程序更加灵活,我们可以在外部获取任何想要的数据形式,然后让 data 引用。 看一个简单的代码:

1
2
3
4
5
6
7
8
9
10
//在构造器外部声明数据
var outData = {
count: 1,
goodName: 'car',
};
var app = new Vue({
el: '#app',
//引用外部数据
data: outData,
});

二、在外部改变数据的三种方法:

1、用 Vue.set 改变

1
2
3
function add() {
Vue.set(outData, 'count', 4);
}

2、用 Vue 对象的方法添加

1
app.count++;

3、直接操作外部数据

1
outData.count++;

其实这三种方式都可以操作外部的数据,Vue 也给我们增加了一种操作外部数据的方法。

三、为什么要有 Vue.set 的存在?

由于 Javascript 的限制,Vue 不能自动检测以下变动的数组。

  • 当你利用索引直接设置一个项时,vue 不会为我们自动更新。
  • 当你修改数组的长度时,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
28
29
30
31
32
33
34
35
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="../assets/js/vue.js"></script>
<title>Vue.set 全局操作</title>
</head>
<body>
<h1>Vue.set 全局操作</h1>
<hr>
<div id="app">
<ul>
<li v-for=" aa in arr">{{aa}}</li>
</ul>

</div>
<button onclick="add()">外部添加</button>

<script type="text/javascript">

function add(){
console.log("我已经执行了");
app.arr[1]='ddd';
//Vue.set(app.arr,1,'ddd');
}
var outData={
arr:['aaa','bbb','ccc']
};
var app=new Vue({
el:'#app',
data:outData
})
</script>
</body>
</html>

这时我们的界面是不会自动跟新数组的,我们需要用 Vue.set(app.arr,1,’ddd’)来设置改变,vue 才会给我们自动更新,这就是 Vue.set 存在的意义。
vue.set.html

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>vue.set 全局操作</title>
<script type="text/javascript" src="../assets/js/vue.js"></script>
</head>
<body>
<h1>vue.set 全局操作</h1>
<hr />
<div id="app">
{{count}}
<ul>
<li v-for="item in arr">{{item}}</li>
</ul>
</div>
<p>
<button onclick="add()">add</button>
</p>

<script type="text/javascript">
function add() {
// Vue.set(outData, 'count', 2);
// app.count++;
// outData.count++;
// app.arr[1] = 'ddd';
Vue.set(app.arr, 1, 'dd');
}
</script>

<script type="text/javascript">
var outData = {
count: 1,
// goods: 'car',
arr: ['aaa', 'bbb', 'ccc'],
};
var app = new Vue({
el: '#app',
data: outData,
});
</script>
</body>
</html>

Vue 的生命周期(钩子函数)

Vue 一共有 10 个生命周期函数,我们可以利用这些函数在 vue 的每个阶段都进行操作数据或者改变内容。

在 index.html 中添加代码

1
2
3
<li>
<a href="./example/vue.lifeCycle.html">vue的生命周期</a>
</li>

在 example 中添加 vue.lifeCycle.html 文件
vue.lifeCycle.html

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>vue.lifeCycle 生命周期</title>
<script type="text/javascript" src="../assets/js/vue.js"></script>
</head>
<body>
<h1>vue.lifeCycle 生命周期</h1>
<hr />
<div id="app">
{{count}}
<p>
<button @click="add">add</button>
</p>
</div>
<button onclick="app.$destroy()">销毁</button>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
count: 1,
},
methods: {
add: function () {
this.count++;
},
},
beforeCreate: function () {
console.log('1-beforeCreate 初始化之前');
},
created: function () {
console.log('2-created 创建完成');
},
beforeMount: function () {
console.log('3-beforeMount 挂载之前');
},
mounted: function () {
console.log('4-mounted 被挂载之后');
},
beforeUpdate: function () {
console.log('5-beforeUpdate 数据更新前');
},
updated: function () {
console.log('6-updated 被更新后');
},
activated: function () {
console.log('7-activated');
},
deactivated: function () {
console.log('8-deactivated');
},
beforeDestroy: function () {
console.log('9-beforeDestroy 销毁之前');
},
destroyed: function () {
console.log('10-destroyed 销毁之后');
},
});
</script>
</body>
</html>

Tempate 制作模板

在 index.html 中添加代码

1
2
3
<li>
<a href="./example/template.html">template制作模板</a>
</li>

在 example 中添加 template.html 文件

一、直接写在选项里的模板

直接在构造器里的 template 选项后边编写。这种写法比较直观,但是如果模板 html 代码太多,不建议这么写。
javascript 代码:

1
2
3
4
5
6
7
8
9
var app = new Vue({
el: '#app',
data: {
message: 'hello Vue!',
},
template: `
<h1 style="color:red">我是选项模板</h1>
`,
});

这里需要注意的是模板的标识不是单引号和双引号,而是,就是 Tab 上面的键。

二、写在 template 标签里的模板

这种写法更像是在写 HTML 代码,就算不会写 Vue 的人,也可以制作页面。

1
2
3
4
5
6
7
8
9
10
11
12
13
<template id="demo2">
<h2 style="color:red">我是template标签模板</h2>
</template>

<script type="text/javascript">
var app=new Vue({
el:'#app',
data:{
message:'hello Vue!'
},
template:'#demo2'
})
</script>

三、写在 script 标签里的模板

这种写模板的方法,可以让模板文件从外部引入。
<

1
2
3
4
5
6
7
8
9
10
11
12
13
<script type="x-template" id="demo3">
<h2 style="color:red">我是script标签模板</h2>
</script>

<script type="text/javascript">
var app=new Vue({
el:'#app',
data:{
message:'hello Vue!'
},
template:'#demo3'
})
</script>

我们学习了 Template 的三种写法,以后学习到 vue-cli 的时候还会学到一种 xxx.vue 的写法。
template.html

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Template三种写法</title>
<script type="text/javascript" src="../assets/js/vue.js"></script>
</head>
<body>
<h1>Template三种写法</h1>
<hr />
<div id="app">{{message}}</div>

<template id="dd2">
<h2 style="color: red">我是Template标签模板</h2>
</template>

<script type="x-template" id="dd3">
<h2 style="color: red">script标签模板</h2>
</script>

<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
message: 'Hello World',
},
template: '#dd3',
// template: `<h2 style='color:red'>我是选项模板</h2>`,
});
</script>
</body>
</html>

Component 初识组件

component 组件是 Vue 学习的重点、重点、重点,重要的事情说三遍。所以你必须学好 Vue component。其实组件就是制作自定义的标签,这些标签在 HTML 中是没有的。
在 index.html 中添加代码

1
2
3
<li>
<a href="./example/component-1.html">component-1组件</a>
</li>

在 example 中添加 component-1.html 文件

一、全局化注册组件

全局化就是在构造器的外部用 Vue.component 来注册,我们注册现在就注册一个的组件来体验一下。

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="../assets/js/vue.js"></script>
<title>component-1</title>
</head>
<body>
<h1>component-1</h1>
<hr>
<div id="app">
<jspang></jspang>
</div>

<script type="text/javascript">
//注册全局组件
Vue.component('jspang',{
template:`<div style="color:red;">全局化注册的jspang标签</div>`
})
var app=new Vue({
el:'#app',
data:{
}
})
</script>
</body>
</html>

我们在 javascript 里注册了一个组件,在 HTML 中调用了他。这就是最简单的一个组件的编写方法,并且它可以放到多个构造器的作用域里。

二、局部注册组件局部

局部注册组件局部注册组件和全局注册组件是向对应的,局部注册的组件只能在组件注册的作用域里进行使用,其他作用域使用无效。

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="../assets/js/vue.js"></script>
<title>component-1</title>
</head>
<body>
<h1>component-1</h1>
<hr>
<div id="app">
<panda></panda>
</div>

<script type="text/javascript">
var app=new Vue({
el:'#app',
components:{
"panda":{
template:`<div style="color:red;">局部注册的panda标签</div>`
}
}
})
</script>
</body>
</html>

从代码中你可以看出局部注册其实就是写在构造器里,但是你需要注意的是,构造器里的 components 是加 s 的,而全局注册是不加 s 的。

三、组件和指令的区别

组件注册的是一个标签,而指令注册的是已有标签里的一个属性。在实际开发中我们还是用组件比较多,指令用的比较少。因为指令看起来封装的没那么好,这只是个人观点。
component.html

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>component-1</title>
<script type="text/javascript" src="../assets/js/vue.js"></script>
</head>
<body>
<h1>component-1</h1>
<hr />
<div id="app">
<jspang></jspang>
<panda></panda>
</div>

<script type="text/javascript">
Vue.component('jspang', {
template: `<div style='color:red'>我是全局的jspang组件</div>`,
});
var app = new Vue({
el: '#app',
components: {
panda: {
template: `<div style='color:green'>我是局部的panda组件</div>`,
},
},
});
</script>
</body>
</html>

Component 组件 props 属性设置

props 选项就是设置和获取标签上的属性值的,例如我们有一个自定义的组件,这时我们想给他加个标签属性写成 意思就是熊猫来自中国,当然这里的 China 可以换成任何值。定义属性的选项是 props。
在 index.html 中添加代码

1
2
3
<li>
<a href="./example/component-2.html">component-2组件props属性设置</a>
</li>

在 example 中添加 component-2.html 文件

一、定义属性并获取属性值

定义属性我们需要用 props 选项,加上数组形式的属性名称,例如:props:[‘here’]。在组件的模板里读出属性值只需要用插值的形式,例如.

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="../assets/js/vue.js"></script>
<title>component-2</title>
</head>
<body>
<h1>component-2</h1>
<hr>
<div id="app">
<panda here="China"></panda>
</div>

<script type="text/javascript">
var app=new Vue({
el:'#app',
components:{
"panda":{
template:`<div style="color:red;">Panda from {{ here }}.</div>`,
props:['here']
}
}
})
</script>
</body>
</html>

上面的代码定义了 panda 的组件,并用 props 设置了 here 的属性值,在 here 属性值里传递了 China 给组件。 最后输出的结果是红色字体的 Panda from China.

二、属性中带’-‘的处理方式

我们在写属性时经常会加入’-‘来进行分词,比如:,那这时我们在 props 里如果写成 props:[‘form-here’]是错误的,我们必须用小驼峰式写法 props:[‘formHere’]。
html 文件:

1
<panda from-here="China"></panda>

javascript 文件:

1
2
3
4
5
6
7
8
9
var app = new Vue({
el: '#app',
components: {
panda: {
template: `<div style="color:red;">Panda from {{ here }}.</div>`,
props: ['fromHere'],
},
},
});

PS:因为这里有坑,所以还是少用-为好

三、在构造器里向组件中传值

把构造器中 data 的值传递给组件,我们只要进行绑定就可以了。就是我们第一季学的 v-bind:xxx.
我们直接看代码:
html 文件:

1
<panda v-bind:here="message"></panda>

javascript 文件:

1
2
3
4
5
6
7
8
9
10
11
12
var app = new Vue({
el: '#app',
data: {
message: 'SiChuan',
},
components: {
panda: {
template: `<div style="color:red;">Panda from {{ here }}.</div>`,
props: ['here'],
},
},
});

component-2.html

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>component-2组件props属性设置</title>
<script type="text/javascript" src="../assets/js/vue.js"></script>
</head>
<body>
<h1>component-2props属性设置</h1>
<hr />
<div id="app">
<panda :here="message"></panda>
</div>

<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
message: 'China',
},
components: {
panda: {
template: `<div style='color:green'>Panda from {{here}}</div>`,
props: ['here'],
},
},
});
</script>
</body>
</html>

Component 父子组件关系

在实际开发中我们经常会遇到在一个自定义组件中要使用其他自定义组件,这就需要一个父子组件关系。
在 index.html 中添加代码

1
2
3
<li>
<a href="./example/component-3.html">component-3父子组件关系</a>
</li>

在 example 中添加 component-3.html 文件

一、构造器外部写局部注册组件

上面我们都把局部组件的编写放到了构造器内部,如果组件代码量很大,会影响构造器的可读性,造成拖拉和错误。
我们把组件编写的代码放到构造器外部或者说单独文件。
我们需要先声明一个对象,对象里就是组件的内容。

1
2
3
var jspang = {
template: `<div>Panda from China!</div>`,
};

声明好对象后在构造器里引用就可以了。

1
2
3
components:{
"jspang":jspang
}

html 中引用

1
<jspang></jspang>

二、父子组件的嵌套

我们先声明一个父组件,比如叫 jspang,然后里边我们加入一个 city 组件,我们来看这样的代码如何写。
component-3.html

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>component-3父子组件关系</title>
<script type="text/javascript" src="../assets/js/vue.js"></script>
</head>
<body>
<h1>component-3父子组件关系</h1>
<hr />
<div id="app">
<panda></panda>
</div>

<script type="text/javascript">
var city = {
template: `<div style="color:green">siChuan of China</div>`,
};
var pandaComponent = {
template: `<div>
<p>Panda from China</p>
<city></city>
</div>`,
components: {
city: city,
},
};

var app = new Vue({
el: '#app',
components: {
panda: pandaComponent,
},
});
</script>
</body>
</html>

Component 标签

标签是 Vue 框架自定义的标签,它的用途就是可以动态绑定我们的组件,根据数据的不同更换不同的组件。
在 index.html 中添加代码

1
2
3
<li>
<a href="./example/component-4.html">component-4标签</a>
</li>

在 example 中添加 component-4.html 文件

1.我们先在构造器外部定义三个不同的组件,分别是 componentA,componentB 和 componentC.

1
2
3
4
5
6
7
8
9
var componentA = {
template: `<div>I'm componentA</div>`,
};
var componentB = {
template: `<div>I'm componentB</div>`,
};
var componentC = {
template: `<div>I'm componentC</div>`,
};

2.我们在构造器的 components 选项里加入这三个组件。

1
2
3
4
5
components:{
"componentA":componentA,
"componentB":componentB,
"componentC":componentC,
}

3.我们在 html 里插入 component 标签,并绑定 who 数据,根据 who 的值不同,调用不同的组件。

1
<component v-bind:is="who"></component>

这就是我们的组件标签的基本用法。
我们提高一下,给页面加个按钮,每点以下更换一个组件。
component-4.html

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>component-4标签</title>
<script type="text/javascript" src="../assets/js/vue.js"></script>
</head>
<body>
<h1>component-4标签</h1>
<hr />
<div id="app">
<component v-bind:is="who"></component>
<button @click="changeComponent">changeComponent</button>
</div>

<script type="text/javascript">
var componentA = {
template: '<div style="color:red">I’m componentA</div>',
};
var componentB = {
template: '<div style="color:green">I’m componentB</div>',
};
var componentC = {
template: '<div style="color:pink">I’m componentC</div>',
};
</script>

<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
who: componentB,
},
components: {
componentA: componentA,
componentB: componentB,
componentC: componentC,
},
methods: {
changeComponent: function () {
if (this.who === 'componentA') {
this.who = 'componentB';
} else if (this.who == 'componentB') {
this.who = 'componentC';
} else {
this.who = 'componentA';
}
},
},
});
</script>
</body>
</html>

构造器里的选项

propsData Option 全局扩展的数据传递

propsData 不是和属性有关,他用在全局扩展时进行传递数据。先回顾一下全局扩展的知识,作一个的扩展标签出来。实际我们并比推荐用全局扩展的方式作自定义标签,我们学了组件,完全可以使用组件来做,这里只是为了演示 propsData 的用法。

在 index.html 中添加代码

1
2
3
<li>
<a href="./example/propsData.html">propsData Option</a>
</li>

在 example 中添加 propsData.html 文件

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="../assets/js/vue.js"></script>
<title>PropsData Option Demo</title>
</head>
<body>
<h1>PropsData Option Demo</h1>
<hr>
<header></header>

<script type="text/javascript">
var header_a = Vue.extend({
template:`<p>{{message}}</p>`,
data:function(){
return {
message:'Hello,I am Header'
}
}
});
new header_a().$mount('header');
</script>
</body>
</html>

扩展标签已经做好了,这时我们要在挂载时传递一个数字过去,我们就用到了 propsData。 我们用 propsData 三步解决传值: 1.在全局扩展里加入 props 进行接收。propsData:{a:1} 2.传递时用 propsData 进行传递。props:[‘a’] 3.用插值的形式写入模板。 完整代码:

1
2
3
4
5
6
7
8
9
10
var header_a = Vue.extend({
template: `<p>{{message}}-{{a}}</p>`,
data: function () {
return {
message: 'Hello,I am Header',
};
},
props: ['a'],
});
new header_a({ propsData: { a: 1 } }).$mount('header');

总结:propsData 在实际开发中我们使用的并不多,我们在后边会学到 Vuex 的应用,他的作用就是在单页应用中保持状态和数据的。

computed Option 计算选项

computed 的作用主要是对原数据进行改造输出。改造输出:包括格式的编辑,大小写转换,顺序重排,添加符号……。

1、computed 是计算属性,也就是依赖某个值或者 props 通过计算得来得数据;
2、 computed 的值是在 getter 执行之后进行缓存的,只有在它依赖的数据发生变化,会重新调用 getter 来计算;
3、 不支持异步,当 computed 内有异步操作时无效,无法监听数据的变化

在 index.html 中添加代码

1
2
3
<li>
<a href="./example/computed.html">computed Option</a>
</li>

在 example 中添加 computed 加.html 文件

一、格式化输出结果:

我们先来做个读出价格的例子:我们读书的原始数据是 price:100 但是我们输出给用户的样子是(¥ 100 元)。 主要的 javascript 代码:

1
2
3
4
5
computed:{
newPrice:function(){
return this.price='¥' + this.price + '元';
}
}

全部代码:

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="../assets/js/vue.js"></script>
<title>Computed Option 计算选项</title>
</head>
<body>
<h1>Computed Option 计算选项</h1>
<hr>
<div id="app">
{{newPrice}}
</div>

<script type="text/javascript">
var app=new Vue({
el:'#app',
data:{
price:100
},
computed:{
newPrice:function(){
return this.price='¥' + this.price + '元';
}
}
})
</script>
</body>
</html>

现在输出的结果就是:¥ 100 元。

二、用计算属性反转数组

例如:我们得到了一个新闻列表的数组,它的顺序是安装新闻时间的顺序正序排列的,也就是早反生的新闻排在前面。这是反人类的,我们需要给他反转。这时我们就可以用到我们的计算属性了。
没有排序的新闻列表,是安装日期正序排列的。

1
2
3
4
5
6
var newsList = [
{ title: '香港或就“装甲车被扣”事件追责 起诉涉事运输公司', date: '2017/3/10' },
{ title: '日本第二大准航母服役 外媒:针对中国潜艇', date: '2017/3/12' },
{ title: '中国北方将有明显雨雪降温天气 南方阴雨持续', date: '2017/3/13' },
{ title: '起底“最短命副市长”:不到40天落马,全家被查', date: '2017/3/23' },
];

我们希望输出的结果:

  • 起底“最短命副市长”:不到 40 天落马,全家被查-2017/3/23
  • 中国北方将有明显雨雪降温天气 南方阴雨持续-2017/3/13
  • 日本第二大准航母服役 外媒:针对中国潜艇-2017/3/12
  • 香港或就“装甲车被扣”事件追责 起诉涉事运输公司-2017/3/10

我们的在 computed 里的 javascript 代码:我们用 js 原生方法给数组作了反转。

1
2
3
4
5
computed:{
reverseNews:function(){
return this.newsList.reverse();
}
}

总结:computed 属性是非常有用,在输出数据前可以轻松的改变数据。所以说这节课的代码必须要多敲几遍,加深印象

Methods Option 方法选项

在以前的学习中,已经大量的使用了构造器里的 methods 选项,但是并没有仔细和系统的讲解过
在 index.html 中添加代码

1
2
3
<li>
<a href="./example/methods.html">methods Option</a>
</li>

在 example 中添加 methods.html 文件
我们还是复习一下最简单的使用方法,一个数字,每点击一下按钮加 1.

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="../assets/js/vue.js"></script>
<title>methods Option</title>
</head>
<body>
<h1>methods Option</h1>
<hr>
<div id="app">
{{ a }}
<p><button @click="add">add</button></p>
</div>

<script type="text/javascript">
var app=new Vue({
el:'#app',
data:{
a:1
},
methods:{
add:function(){
this.a++
}
}
})
</script>
</body>
</html>

一、methods 中参数的传递

使用方法和正常的 javascript 传递参数的方法一样,分为两部:

  • 在 methods 的方法中进行声明,比如我们给 add 方法加上一个 num 参数,就要写出add:function(num){}.
  • 调用方法时直接传递,比如我们要传递 2 这个参数,我们在 button 上就直接可以写。<button @click=”add(2)”></button>

现在知道了加参数的方法,看一段完整的代码,代码中给 add 添加了 num 参数,并在按钮上调用传递了。

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="../assets/js/vue.js"></script>
<title>methods Option</title>
</head>
<body>
<h1>methods Option</h1>
<hr>
<div id="app">
{{ a }}
<p><button @click="add(2)">add</button></p>
</div>

<script type="text/javascript">
var app=new Vue({
el:'#app',
data:{
a:1
},
methods:{
add:function(num){
if(num!=''){this.a+=num}
else{this.a++}
}
}
})
</script>
</body>
</html>

这时,再点击按钮是每次加 2 个数字。

二、methods 中的$event 参数

传递的$event 参数都是关于你点击鼠标的一些事件和属性。我们先看看传递的方法。
传递:

1
<button @click=”add(2,$event)”>add</button>

我们这时候可以打印一下,看看 event 到底是个怎样的对象。你会发现,它包含了大部分鼠标事件的属性。

三、native 给组件绑定构造器里的原生事件。

在实际开发中经常需要把某个按钮封装成组件,然后反复使用,如何让组件调用构造器里的方法,而不是组件里的方法。就需要用到我们的.native修饰器了。
现在我们把我们的 add 按钮封装成组件:
声明 btn 对象:

1
2
3
var btn = {
template: `<button>组件Add</button>`,
};

在构造器里声明:

1
2
3
components:{
"btn":btn
}

用.native 修饰器来调用构造器里的 add 方法

1
<p><btn @click.native="add(3)"></btn></p>

四、作用域外部调用构造器里的方法

这种不经常使用,如果你出现了这种情况,说明你的代码组织不够好。

1
<button onclick="app.add(4)">外部调用构造器里的方法</button>

methods.html

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>methods Option</title>
<script type="text/javascript" src="../assets/js/vue.js"></script>
</head>
<body>
<h1>methods Option</h1>
<hr />
<div id="app">
{{a}}
<p>
<button @click="add(2)">add</button>
</p>
<p><btn @click.native="add(2)"></btn></p>
<p>
<button onclick="app.add(2)">外部ADD</button>
</p>
</div>
<script type="text/javascript">
var btn = {
template: `<button>组件ADD</button>`,
};
var app = new Vue({
el: '#app',
data: {
a: 1,
},
components: {
btn: btn,
},
methods: {
add: function (num) {
if (num != '') {
this.a += num;
} else {
this.a++;
}
},
},
});
</script>
</body>
</html>

Watch 选项 监控数据

数据变化的监控经常使用,我们可以先来看一个简单的数据变化监控的例子。例如天气预报的穿衣指数,它主要是根据温度来进行提示的,当然还有其它的,咱们就不考虑了。
1、watch 是监听器,可以监听某一个数据,然后执行相应的操作;
2、不支持缓存,数据变直接会触发相应的操作;
3、监听的函数接收两个参数,第一个参数是最新的值;第二个参数是输入之前的值;
4、支持异步操作;
在 index.html 中添加代码

1
2
3
<li>
<a href="./example/watch.html">watch Option</a>
</li>

在 example 中添加 watch.html 文件

一、看一个监控变化的案例

温度大于 26 度时,我们建议穿 T 恤短袖,温度小于 26 度大于 0 度时,我们建议穿夹克长裙,温度小于 0 度时我们建议穿棉衣羽绒服。
先来模拟一个温度变化的情况:我们使用按钮来加减温度。
wacth.html

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>watch option</title>
<script type="text/javascript" src="../assets/js/vue.js"></script>
</head>
<body>
<h1>watch option</h1>
<hr />
<div id="app">
<p>今日温度:{{temperature}}°C</p>
<p>穿衣建议:{{suggestion}}</p>
<p>
<button @click="add">添加温度</button>
<button @click="reduce">减少温度</button>
</p>
</div>
<script type="text/javascript">
var suggestion = ['T恤短袖', '夹克长裙', '棉衣羽绒服'];
var app = new Vue({
el: '#app',
data: {
temperature: 14,
suggestion: '夹克长裙',
},
methods: {
add: function () {
this.temperature += 5;
},
reduce: function () {
this.temperature -= 5;
},
},
watch: {
temperature: function (newVal, oldVal) {
if (newVla >= 26) {
this.suggestion = suggestion[0];
} else if (newVal < 26 && newVal > 0) {
this.suggestion = suggestion[1];
} else {
this.suggestion = suggestion[2];
}
},
},
});
// app.$watch('temprtature', function (newVal, oldVal) {
// if (newVla >= 26) {
// this.suggestion = suggestion[0];
// } else if (newVal < 26 && newVal > 0) {
// this.suggestion = suggestion[1];
// } else {
// this.suggestion = suggestion[2];
// }
// });
</script>
</body>
</html>

二、用实例属性写 watch 监控

有些时候我们会用实例属性的形式来写 watch 监控。也就是把我们 watch 卸载构造器的外部,这样的好处就是降低我们程序的耦合度,使程序变的灵活。

1
app.$watch('xxx', function () {});

还是上边的案例我们改成实例方法的模式。

1
2
3
4
5
6
7
8
9
app.$watch('temperature', function (newVal, oldVal) {
if (newVal >= 26) {
this.suggestion = suggestion[0];
} else if (newVal < 26 && newVal >= 0) {
this.suggestion = suggestion[1];
} else {
this.suggestion = suggestion[2];
}
});

效果和上面是一样的。

Mixins 混入选项操作

Mixins 一般有两种用途:

  1. 在你已经写好了构造器后,需要增加方法或者临时的活动时使用的方法,这时用混入会减少源代码的污染。
  2. 很多地方都会用到的公用方法,用混入的方法可以减少代码量,实现代码重用。

在 index.html 中添加代码

1
2
3
<li>
<a href="./example/mixins.html">mixins Option</a>
</li>

在 example 中添加 mixins.html 文件

一、Mixins 的基本用法

我们现在有个数字点击递增的程序,假设已经完成了,这时我们希望每次数据变化时都能够在控制台打印出提示:“数据发生变化”.
代码实现过程:

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="../assets/js/vue.js"></script>
<title>Mixins Option Demo</title>
</head>
<body>
<h1>Mixins Option Demo</h1>
<hr>
<div id="app">
<p>num:{{ num }}</p>
<P><button @click="add">增加数量</button></P>
</div>

<script type="text/javascript">
//额外临时加入时,用于显示日志
var addLog={
updated:function(){
console.log("数据放生变化,变化成"+this.num+".");
}
}
var app=new Vue({
el:'#app',
data:{
num:1
},
methods:{
add:function(){
this.num++;
}
},
mixins:[addLog]//混入
})
</script>
</body>
</html>

二、mixins 的调用顺序

从执行的先后顺序来说,都是混入的先执行,然后构造器里的再执行,需要注意的是,这并不是方法的覆盖,而是被执行了两边。
在上边的代码的构造器里我们也加入了 updated 的钩子函数:

1
2
3
updated:function(){
console.log("构造器里的updated方法。")
},

这时控制台输出的顺序是:

1
2
mixins数据放生变化,变化成2.
构造器里的updated方法。

PS:当混入方法和构造器的方法重名时,混入的方法无法展现,也就是不起作用。

三、全局 API 混入方式

我们也可以定义全局的混入,这样在需要这段代码的地方直接引入 js,就可以拥有这个功能了。我们来看一下全局混入的方法:

1
2
3
4
5
Vue.mixin({
updated: function () {
console.log('我是全局被混入的');
},
});

PS:全局混入的执行顺序要前于混入和构造器里的方法。
mixins.html

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>mixins Option</title>
<script type="text/javascript" src="../assets/js/vue.js"></script>
</head>
<body>
<h1>mixins Option</h1>
<hr />
<div id="app">
{{num}}
<p><button @click="add">add</button></p>
</div>
<script type="text/javascript">
var addConsole = {
updated: function () {
console.log('数据发生了变化,变成了' + this.num);
},
};
Vue.mixin({
updated() {
console.log('我是全局的混入');
},
});
var app = new Vue({
el: '#app',
data: {
num: 1,
},
methods: {
add: function () {
this.num++;
},
},
updated() {
console.log('我是原生的updata');
},
mixins: [addConsole],
});
</script>
</body>
</html>

Extends Option 扩展选项

通过外部增加对象的形式,对构造器进行扩展,和混入非常的类似。
在 index.html 中添加代码

1
2
3
<li>
<a href="./example/extends.html">extends Option</a>
</li>

在 example 中添加 extends.html 文件

一、extends 我们来看一个扩展的实例。

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="../assets/js/vue.js"></script>
<title>Extends Optin Demo</title>
</head>
<body>
<h1>Extends Optin Demo</h1>
<hr>
<div id="app">
{{message}}
<p><button @click="add">add</button></p>
</div>

<script type="text/javascript">
var bbb={
created:function(){
console.log("我是被扩展出来的");
},
methods:{
add:function(){
console.log('我是被扩展出来的方法!');
}
}
};
var app=new Vue({
el:'#app',
data:{
message:'hello Vue!'
},
methods:{
add:function(){
console.log('我是原生方法');
}
},
extends:bbb
})
</script>
</body>
</html>

二、delimiters 选项

delimiters 的作用是改变我们插值的符号。Vue 默认的插值是双大括号{{ }}。但有时我们会有需求更改这个插值的形式。

1
delimiters: ['${', '}'];

现在我们的插值形式就变成了${}

实例和内置组件

实例就是在构造器外部操作构造器内部的属性选项或者方法,就叫做实例?实例的作用就是给原生的或者其他 javascript 框架一个融合的接口或者说是机会,让 Vue 和其他框架一起使用。

实例入门-实例属性

一、Vue 和 Jquery.js 一起使用

在 index.html 中添加代码

1
2
3
<li>
<a href="./example/example01.html">example methods</a>
</li>

在 example 中添加 example01.html 文件

1、下载并引入 jquery 框架

下载可以去官网进行下载,我这里使用的版本是 3.1.1,下载好后在需要的页面引入就可以了。当然你还有很多其它的方法引入 jquery,只要可以顺利引入就可以了。

1
<script < type="text/javascript" src="../assets/js/jquery-3.1.1.min.js"></script>

试着作一个案例,在 DOM 被挂载后修改里边的内容。

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="../assets/js/vue.js"></script>
<script type="text/javascript" src="../assets/js/jquery-3.1.1.min.js"></script>
<title>Early Examples Demo</title>
</head>
<body>
<h1>Early Examples Demo</h1>
<hr>
<div id="app">
{{message}}
</div>

<script type="text/javascript">
var app=new Vue({
el:'#app',
data:{
message:'hello Vue!'
},
//在Vue中使用jQuery
mounted:function(){
$('#app').html('我是jQuery!');
}
})
</script>
</body>
</html>

现在页面显示是:我是 jQuery,而不是 hello Vue 了。

二、实例调用自定义方法

在 Vue 的构造器里我们写一个 add 方法,然后我们用实例的方法调用它。
构造器里的 add 方法:

1
2
3
4
5
methods:{
add:function(){
console.log("调用了Add方法");
}
}

实例调用:

1
app.add();

PS:我们有可能把 app.add()的括号忘记或省略,这时候我们得到的就是方法的字符串,但是并没有执行,所以必须要加上括号。
作业:利用 console.log 把 app 打印出来,看看里边到底包含了哪些属性和方法。因为里边的属性很多,这里只是简单的介绍。
example01.html

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>example methods Demo</title>
<script type="text/javascript" src="../assets/js/vue.js"></script>
<script type="text/javascript" src="../assets/js/jquery-3.1.1.min.js"></script>
</head>
<body>
<h1>example methods Demo</h1>
<hr />
<div id="app">{{message}}</div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
message: 'Hello World',
},
mounted() {
$('#app').html('我是jQuery');
},
methods: {
add: function () {
console.log('调用了构造器内部的ADD方法');
},
},
});
app.add();
</script>
</body>
</html>

实例方法

在 index.html 中添加代码

1
2
3
<li>
<a href="./example/example02.html">example02 methods</a>
</li>

在 example 中添加 example02.html 文件

一、$mount 方法

$mount方法是用来挂载我们的扩展的,我们先来复习一下扩展的写法。
这里我们作了jspang的扩展,然后用$mount 的方法把 jspang 挂载到 DOM 上,我们也生成了一个 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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="../assets/js/vue.js"></script>
<title>Examples Method Demo</title>
</head>
<body>
<h1>Examples Method Demo</h1>
<hr>
<div id="app">
{{message}}
</div>

<script type="text/javascript">
var jspang = Vue.extend({
template:`<p>{{message}}</p>`,
data:function(){
return {
message:'Hello ,I am JSPang'
}
}
})
var vm = new jspang().$mount("#app")
</script>
</body>
</html>

二、$destroy() 卸载方法

用$destroy()进行卸载。
我写了一个 button 按钮,点击后卸载整个挂载。
html:

1
2
3
<p>
<button onclick="destroy()">卸载</button>
</p>

javascript

1
2
3
function destroy() {
vm.$destroy();
}

PS:$destroy()后边必须要有括号,没有括号是无用的。

三、$forceUpdate() 更新方法

1
vm.$forceUpdate();

四、$nextTick() 数据修改方法

当 Vue 构造器里的 data 值被修改完成后会调用这个方法,也相当于一个钩子函数吧,和构造器里的 updated 生命周期很像。

1
2
3
4
5
6
function tick() {
vm.message = 'update message info ';
vm.$nextTick(function () {
console.log('message更新完后我被调用了');
});
}

安装 Vue 的控制台调试工具。

每个人的安装方法不同。

实例事件

实例事件就是在构造器外部写一个调用构造器内部的方法。这样写的好处是可以通过这种写法在构造器外部调用构造器内部的数据。
在 index.html 中添加代码

1
2
3
<li>
<a href="./example/example03.html">example03 methods</a>
</li>

在 example 中添加 example03.html 文件
我们还是写一个点击按钮,持续加 1 的例子。

一、$on 在构造器外部添加事件。

1
2
3
4
app.$on('reduce', function () {
console.log('执行了reduce()');
this.num--;
});

$on接收两个参数,第一个参数是调用时的事件名称,第二个参数是一个匿名方法。
如果按钮在作用域外部,可以利用$emit 来执行。

1
2
3
4
//外部调用内部事件
function reduce() {
app.$emit('reduce');
}

二、$once 执行一次的事件

1
2
3
4
app.$once('reduceOnce', function () {
console.log('只执行一次的方法');
this.num--;
});

三、$off 关闭事件

1
2
3
4
//关闭事件
function off() {
app.$off('reduce');
}

example03.html

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>example03 methods Demo</title>
<script type="text/javascript" src="../assets/js/vue.js"></script>
</head>
<body>
<h1>example03 methods Demo</h1>
<hr />
<div id="app">
{{num}}
<p><button @click="add">add</button></p>
</div>
<p><button onclick="reduce()">reduce</button></p>
<p><button onclick="reduceOnce()">reduceOnce</button></p>
<p><button onclick="off()">off</button></p>

<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
num: 1,
},
methods: {
add: function () {
this.num++;
},
},
});
app.$on('reduce', function () {
console.log('执行了reduce方法');
this.num--;
});
app.$once('reduceOnce', function () {
console.log('只执行一次的方法');
this.num--;
});
function reduce() {
app.$emit('reduce');
}
function reduceOnce() {
app.$emit('reduceOnce');
}
function off() {
app.$emit('reduce');
}
</script>
</body>
</html>

内置组件 -slot 讲解

slot 是标签的内容扩展,也就是说你用 slot 就可以在自定义组件时传递给组件内容,组件接收内容并输出。
在 index.html 中添加代码

1
2
3
<li>
<a href="./example/slot.html">slot</a>
</li>

在 example 中添加 slot.html 文件
先来定义一个的组件,这个组件用来显示博主的一些信息。
我们在 Vue 构造器里的 data 中给出了信息,信息如下:(博客地址,网名,使用技能)

1
2
3
4
5
6
7
data:{
jspangData:{
bolgUrl:'http://jspang.com',
netName:'技术胖',
skill:'Web前端'
}
},

我们用标签的方式定义了组件:

1
2
3
4
5
6
7
<template id="tmp">
<div>
<p>博客地址:</p>
<p>网名:</p>
<p>技术类型:</p>
</div>
</template>

我们现在就可以用 slot 功能让组件接收传递过来的值,并在模板中接收显示。

slot 的使用需要两步:

1、在 HTML 的组件中用 slot 属性传递值。

1
2
3
4
5
<jspang>
<span slot="bolgUrl">{{jspangData.bolgUrl}}</span>
<span slot="netName">{{jspangData.netName}}</span>
<span slot="skill">{{jspangData.skill}}</span>
</jspang>

2、在组件模板中用标签接收值。

1
2
3
4
5
6
7
8
9
10
11
12
13
<template id="tmp">
<div>
<p>
博客地址:<slot name="bolgUrl"></slot>
</p>
<p>
网名:<slot name="netName"></slot>
</p>
<p>
技术类型:<slot name="skill"></slot>
</p>
</div>
</template>

slot.html

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Slot content extend Demo</title>
<script type="text/javascript" src="../assets/js/vue.js"></script>
</head>
<body>
<h1>Slot content extend Demo</h1>
<hr />
<div id="app">
<jsp>
<span slot="blogUrl">{{jspData.blogUrl}}</span>
<span slot="netName">{{jspData.netName}}</span>

<span slot="skill">{{jspData.skill}}</span>
</jsp>
</div>

<template id="tep">
<div>
<p>
博客地址:
<slot name="blogUrl"></slot>
</p>
<p>
网名:
<slot name="netName"></slot>
</p>

<p>
技术类型:
<slot name="skill"></slot>
</p>
</div>
</template>

<script type="text/javascript">
var jsp = {
template: '#tep',
};
var app = new Vue({
el: '#app',
data: {
jspData: { blogUrl: 'http://jspang.com', netName: 'jsp', skill: 'web前端' },
},
components: {
jsp: jsp,
},
});
</script>
</body>
</html>


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!