Vue学习笔记(四)

模板引用(获取 DOM 操作)

虽然 Vue 的声明性渲染模型为你抽象了大部分对 DOM 的直接操作,但在某些情况下,我们仍然需要直接访问底层 DOM 元素。要实现这一点,我们可以使用特殊的 refattribute。

挂载结束后引用都会被暴露在 this.$refs之上。

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
<script>
/**
* 内容改变:{{模板语法}}
* 属性改变:v-bind
* 事件改变:v-on
*/
export default {
data() {
return {
content: "内容"
}
},
methods: {
getElementHandle() {
console.log(this.$refs.container);
console.log(this.$refs.username.value);
}
}
}
</script>

<template>
<div ref="container" class="container">{{ content }}</div>
<input type="text" ref="username">
<button @click="getElementHandle">获取元素</button>
</template>

组件组成

组件最大的优势就是可复用性

当使用构建步骤时,我们一般会将 Vue 组件定义在一个单独的 .vue文件中,这被叫做单文件组件(简称 SFC)

组件组成结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<script>
export default {
data() {
return {
message: "基础组件组成"
}
}
}
</script>

<template>
<div class="container">{{ message }}</div>
</template>

<!-- scoped 限定样式只在当前组件生效 -->
<style scoped>
.container {
width: 100%;
height: 100%;
color: red;
}
</style>

组件引用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<script>
//1.引入组件
import Mycomponent from './components/Mycomponent.vue'
// 2.注入组件
export default {
components: {
Mycomponent
}
}
</script>

<template>
<!-- 3.使用组件 -->
<Mycomponent />
</template>

<style>

</style>

setup 可以省略注入组件步骤

组件的嵌套关系

20241027134619

组件允许我们将 UI 划分为独立的、可重用的部分,并且可以对每个部分进行单独的思考。在实际应用中,组件常常被组织成层层嵌套的树状结构。

这和我们嵌套 HTML 元素的方式类似,Vue 实现了自己的组件模型,使我们可以在每个组件内封装自定义内容与逻辑。

创建组件及引用关系

App.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<script>
import Header from './pages/Header.vue';
import Main from './pages/Main.vue';
import Aside from './pages/Aside.vue';

export default {
name: 'App',
components: {
Header,
Main,
Aside
}
}
</script>

<template>
<Header />
<Main />
<Aside />
</template>

<style>

</style>

Header.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<template>
<h3>Header</h3>
</template>

<style scoped>
h3 {
width: 100%;
height: 100px;
border: 5px solid #999;
text-align: center;
line-height: 100px;
box-sizing: border-box;
}
</style>

Main.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
<script>
import Artice from './Artice.vue';
export default {
components: {
Artice
}
}
</script>

<template>
<div class="main">
<h3>Main</h3>
<Artice />
<Artice />
</div>
</template>

<style scoped>
.main {
float: left;
width: 70%;
height: 400px;
border: 5px solid #999;
box-sizing: border-box;
}
</style>

Aside.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
<script>
import item from './item.vue';
export default {
components: {
item
}
}
</script>

<template>
<div class="aside">
<h3>Aside</h3>
<item />
<item />
</div>
</template>

<style scoped>
.aside {
float: right;
width: 30%;
height: 400px;
border: 5px solid #999;
box-sizing: border-box;
}
</style>

Article.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<script>
export default {

}
</script>

<template>
<h3>Article</h3>
</template>

<style scoped>
h3 {
width: 80%;
margin: 0 auto;
text-align: center;
line-height: 100px;
box-sizing: border-box;
margin-top: 50px;
background: #999;
}
</style>

Item.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<template>
<h3>Item</h3>
</template>

<style scoped>
h3 {
width: 80%;
margin: 0 auto;
text-align: center;
line-height: 100px;
box-sizing: border-box;
margin-top: 10px;
background: #999;
}
</style>

效果展示

20241027142246

组件注册方式

一个 Vue 组件在使用前需要先被“注册”,这样 Vue 才能在渲染模板时找到其对应的实现。组件注册有两种方式:

  1. 全局注册
  2. 局部注册

全局注册

main.js

1
2
3
4
5
6
7
8
import { createApp } from "vue";
import App from "./App.vue";
import Header from "./pages/Header.vue";

const app = createApp(App);
//在这里引入全局样式
app.component("Header", Header);
app.mount("#app");

App.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<script>
// import Header from './pages/Header.vue';
import Main from './pages/Main.vue';
import Aside from './pages/Aside.vue';

export default {
name: 'App',
components: {
// Header,
Main,
Aside
}
}
</script>

<template>
<Header />
<Main />
<Aside />
</template>

<style>

</style>

无需在其他 Vue 文件下注册引入,可以直接使用

坏处

  1. 全局注册,但并没有被使用的组件无法在生产打包时被自动移除(也叫”tree-shaking”)。如果你全局注册了一个组件,即使它并没有被实际使用,它仍然会出现在打包后的 JS 文件中。
  2. 全局注册在大型项目中使项目的依赖关系变得不那么明确。在父组件中使用子组件时,不太容易定位子组件的实现。和使用过多的全局变量一样,这可能会影响应用长期的可维护性。

局部注册(推荐)

局部注册需要使用 components选项

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
<script>
//1.引入组件
import item from './item.vue';
//2.注册组件
export default {
components: {
item
}
}
</script>

<template>
<div class="aside">
<h3>Aside</h3>
<!-- 3.使用组件 ---->
<item />
<item />
</div>
</template>

<style scoped>
.aside {
float: right;
width: 30%;
height: 400px;
border: 5px solid #999;
box-sizing: border-box;
}
</style>