Vue 3 快速入门

对于初学者来说,学习 Vue.js 最好是在一个单一的 HTML 页面中进行,因为只须用 <script> 标签引入一个 JS 文件,就能使用 Vue.js 了。

1
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>

Vue.js 把 应用 看作由 组件 组成的树状结构。每个组件都有 DOM 元素与之对应。一个应用至少包含一个根组件。由此可见,应用的初始化至少包含下列两个步骤:

  1. 调用 Vue.createApp() 创建一个应用实例,同时创建一个根组件。
  2. 调用应用实例的 mount() 方法,把应用实例(根组件)挂载到某个 DOM 元素。

绑定文本

这需要提供一个占位符(放在 {{}} 中)。

1
2
3
<div id="app">
<h1>{{ message }}</h1>
</div>

调用 Vue.createApp() 创建应用实例,再调用应用实例的 mount() 方法完成挂载。

1
2
3
4
5
6
7
8
9
10
11
12
13
<script>
const selector = '#app';
const property = {
data() {
return {
message: 'Hello, world!'
};
}
};

const app = Vue.createApp(property);
const vm = app.mount(selector);
</script>

应用实例的大多数方法都返回 this,但 mount() 方法返回的是根组件的实例。

{{ message }} 最终会被替换成 Hello, world!

1
2
3
<div id="app">
<h1>Hello, world!</h1>
</div>

传递给 Vue.createApp() 方法的对象包含了创建根组件所需的各种 组件选项

data() 方法必须返回一个对象,这个对象称为 数据对象。组件实例会代理数据对象的属性。也就是说,可以把数据对象的属性当作组件实例的属性来访问,组件选项中的函数也可以通过 this 访问数据对象的属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<script>
const selector = '#app';
const property = {
data() {
return {
message: 'Hello, world!'
};
},
mounted() {
console.log(this.message); // Hello, world!
}
};

const app = Vue.createApp(property);
const vm = app.mount(selector);

console.log(vm.message); // Hello, world!
</script>

mounted() 方法会在应用实例完成挂载后被调用。

也可以直接访问某些组件选项。但必须加上 $ 前缀。例如 $el 是组件对应的 DOM 元素。

1
2
3
4
5
6
7
<script>
...
const app = Vue.createApp(property);
const vm = app.mount(selector);

console.log(vm.$el); // <span>
</script>

生命周期钩子

mounted() 类似的组件选项称为生命周期钩子,常用的有:

  • created() 在挂载前(调用 app.mount() 前)调用,此时 $el 不可用。
  • mounted() 在挂载后(调用 app.mount() 后)调用。
  • beforeUnmount() 在卸载之前调用(调用 app.unmount() 前)。
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
<div id="app" v-cloak>
<p>{{ reversedText }}</p>
</div>

<script>
const property = {
data() {
return {
text: '123456'
};
},
computed: {
reversedText() {
console.log(2);
return this.text.split('').reverse().join('');
}
},
created() {
console.log(1);
},
mounted() {
console.log(3);
},
beforeUnmount() {
console.log(4);
}
};

const app = Vue.createApp(property);
app.mount('#app');
app.unmount();
// 1
// 2
// 3
// 4
</script>

绑定 HTML

给元素添加 v-html 属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<div id="app" v-cloak>
<span v-html="link"></span>
</div>

<script>
const property = {
data() {
return {
link: '<a href="/user/login">Login</a>'
};
}
};

Vue.createApp(property).mount('#app');
</script>

data.link 会被渲染成一个可以点击的 <a> 元素,插入 <span>

1
2
3
4
5
<div id="app">
<span>
<a href="/user/login">Login</a>
</span>
</div>

绑定属性

要让元素的 href 属性和变量 url 绑定,只须给元素添加 v-bind:href="url" 属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<div id="app">
<a v-bind:href="url">Login</a>
</div>

<script>
const property = {
data() {
return {
url: '/user/login'
};
}
};
...
</script>
1
2
3
<div id="app">
<a href="/user/login">跳转</a>
</div>

v-bind:xxx 可以简写为 :xxx

1
2
3
<div id="app">
<a :href="url">Login</a>
</div>

绑定事件

新增组件选项 methods,对象类型,元素应当是函数。这些函数被调用时,this 指向所在组件实例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script>
const property = {
data() {
return {
message: 'Hello, Vue.js!'
};
},
methods: {
foo() {
return this.message; // Hello, Vue.js!
}
}
};
...
</script>

这些函数可以直接在 HTML 中调用,结果就是函数的返回值。

1
2
3
<div id="app">
<p>{{ foo() }}</p>
</div>
1
2
3
<div id="app">
<p>Hello, Vue.js!</p>
</div>

除了作为普通函数调用外,还可以作为事件处理函数。为 HTML 标签绑定事件的方式是添加 v-on:xxx 属性,其中 xxx 就是事件名。

1
2
3
<div id="app">
<button v-on:click="onClick">点击</button>
</div>

上例为 <button> 标签绑定了一个点击事件,事件处理函数为 onClick()。这时就需要在 methods 中给出 onClick()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script>
const property = {
data() {
return {
message: 'Hello, Vue.js!'
};
},
methods: {
onClick() {
console.log(this.message); // Hello, Vue.js!
}
}
};
...
</script>

现在,只要触发 <button> 标签的点击事件,methods 中的 onClick() 就会被调用。

作为事件处理函数,可以在函数名后面跟上小括号,以传递参数。如果要使用 JavaScript 原生的事件对象,可以直接使用变量 $event

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<div id="app">
<button v-on:click="onClick(123, $event)">点击</button>
</div>

<script>
const property = {
data() {
return {
message: 'Hello, Vue.js!'
};
},
methods: {
onClick(a, b, c) {
console.log(a); // 123
console.log(b); // click { target: button, ...
console.log(c); // undefined
}
}
};
...
</script>

如果只写函数名,而函数的定义又带有形参,则第一个参数传入事件对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<div id="app">
<button v-on:click="onClick">点击</button>
</div>

<script>
const property = {
data() {
return {
message: 'Hello, Vue.js!'
};
},
methods: {
onClick(a, b, c) {
console.log(a); // click { target: button, ...
console.log(b); // undefined
console.log(c); // undefined
}
}
};
...
</script>

v-on:xxxx 可以简写为 @xxxx

1
2
3
<div id="app">
<button @click="onClick">点击</button>
</div>

计算属性

组件选项 computed 的用法 methods 相同,区别在于,调用 computed 中的函数,只写函数名,不写小括号。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<div id="app">
<p>{{ reversedText }}</p>
</div>

<script>
const property = {
data() {
return {
text: '123456'
};
},
computed: {
reversedText() {
return this.text.split('').reverse().join('');
}
}
};
...
</script>

reversedText 看起来像是 data 中的一员,而不像函数调用,因此被称为 计算属性