大学生涯vueVue学习笔记(四)
Jie模板引用(获取 DOM 操作)
虽然 Vue 的声明性渲染模型为你抽象了大部分对 DOM 的直接操作,但在某些情况下,我们仍然需要直接访问底层 DOM 元素。要实现这一点,我们可以使用特殊的 ref
attribute。
挂载结束后引用都会被暴露在 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>
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>
import Mycomponent from './components/Mycomponent.vue'
export default { components: { Mycomponent } } </script>
<template> <Mycomponent /> </template>
<style>
</style>
|
setup 可以省略注入组件步骤
组件的嵌套关系
组件允许我们将 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>
|
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>
|
效果展示
组件注册方式
一个 Vue 组件在使用前需要先被“注册”,这样 Vue 才能在渲染模板时找到其对应的实现。组件注册有两种方式:
- 全局注册
- 局部注册
全局注册
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 Main from './pages/Main.vue'; import Aside from './pages/Aside.vue';
export default { name: 'App', components: { Main, Aside } } </script>
<template> <Header /> <Main /> <Aside /> </template>
<style>
</style>
|
无需在其他 Vue 文件下注册引入,可以直接使用
坏处
- 全局注册,但并没有被使用的组件无法在生产打包时被自动移除(也叫”tree-shaking”)。如果你全局注册了一个组件,即使它并没有被实际使用,它仍然会出现在打包后的 JS 文件中。
- 全局注册在大型项目中使项目的依赖关系变得不那么明确。在父组件中使用子组件时,不太容易定位子组件的实现。和使用过多的全局变量一样,这可能会影响应用长期的可维护性。
局部注册(推荐)
局部注册需要使用 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>
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>
|