一、单文件组件
1. 组件定义
- 组件允许我们将 UI 划分为独立的、可重用的部分,并且可以对每个部分进行单独的思考。在实际应用中,组件常常被组织成层层嵌套的树状结构
1 | <div id="box"> |
2. 单文件组件 SFC
- Vue 的单文件组件(即
*.vue
文件)是一种特殊的文件格式,可以将一个 Vue 组件的模板、逻辑与样式封装在单个文件中
(1) 创建项目
1 | $ npm create vue@latest |
(2) 项目目录介绍
node_modules
:依赖的命令、环境等package.json
:启动入口
1 | "scripts": { |
index.html
:主页面,会被注入 JS 脚本
1 | <body> |
vite.config.js
:Vue 相关配置,如代理(改完需要重启服务)
1 | devServer: { |
main.js
:项目入口
1 | import {createApp} from 'vue' // 从node_modules中找 |
App.vue
:根组件
1 | <template> |
二、组件基础
1. 父传子(props)
props
遵循单向绑定原则:每次父组件更新后,所有的子组件中的 props 都会被更新到最新值,但不会逆向传递(避免了子组件意外修改父组件的状态)
1 | <!-- 父组件 --> |
- 属性透传:指传递给一个组件,却没有被该组件声明为 props 或 emits 的 attribute 或者 v-on 事件监听器。最常见的例子就是 class、style 和 id
- 当一个组件以单个元素为根作渲染时,透传的 attribute 会自动被添加到根元素上
1 | <!-- 父组件 --> |
2. 子传父($emit)
1 | <!-- 父组件 --> |
3. 父组件强权($refs)
ref
如果绑定在 DOM 节点上,拿到的就是原生 DOM 节点ref
如果绑定在组件上,拿到的就是组件对象,可以实现通信功能
1 | <!-- 父组件 --> |
4. 子组件强权($parent、$root)
- 在子组件中通过
$parent
访问父组件,通过$root
访问根组件
1 | <!-- 子组件 --> |
5. 跨级通信(provide、inject)
1 | <!-- 父组件 --> |
6. 订阅发布
1 | <!-- store.js --> |
7. 动态组件与 KeepAlive
1 | <!-- 不活跃的组件将会被缓存(不使用KeepAlive会被重新加载) --> |
8. 组件中的 v-model
- v-model 原理:
1 | <!-- 模板编译器会对v-model进行展开: --> |
9. 异步组件
- Vue 提供了
defineAsyncComponent
方法实现需要时再从服务器加载相关组件
1 | <script> |
三、组件插槽
1. 基本使用
<slot>
元素是一个插槽出口,标识了父元素提供的插槽内容将在哪里被渲染- 插槽内容可以访问到父组件的数据作用域,因为插槽内容本身是在父组件模板中定义的
1 | <!-- 父组件 --> |
2. 具名插槽
- 渲染到指定名字的插槽
1 | <!-- 父组件 --> |
3. 作用域插槽
- 让子组件在渲染时将一部分数据提供给插槽
1 | <!-- 父组件:重新渲染数据 --> |
四、生命周期
- 每个 Vue 组件实例在创建时都需要经历一系列的初始化步骤,比如设置好数据侦听,编译模板,挂载实例到 DOM,以及在数据改变时更新 DOM。在此过程中,它也会运行被称为生命周期钩子的函数,让开发者有机会在特定阶段运行自己的代码
beforeCreate()
会在实例初始化完成、props
解析之后、data()
和computed
等选项处理之前立即调用created()
被调用时,以下内容已经设置完成:响应式数据、计算属性、方法和侦听器。然而,此时挂载阶段还未开始,因此$el
属性仍不可用beforeMount()
被调用时,组件已经完成了其响应式状态的设置,但还没有创建 DOM 节点。它即将首次执行 DOM 渲染过程mounted()
所有同步子组件都已经被挂载,其自身的 DOM 树已经创建完成并插入了父容器中。这个钩子通常用于执行需要访问组件所渲染的 DOM 树相关的副作用beforeUpdate()
用来在 Vue 更新 DOM 之前访问 DOM 状态。在这个钩子中更改状态也是安全的updated()
会在组件的任意 DOM 更新后被调用,这些更新可能是由不同的状态变更导致的。如果需要在某个特定的状态更改后访问更新后的 DOM,请使用 nextTick() 作为替代beforeUnmount()
被调用时,组件实例依然还保有全部的功能unmounted()
所有子组件都已经被卸载,所有相关的响应式作用都已经停止。可以在这个钩子中手动清理一些副作用,例如计时器、DOM 事件监听器或者与服务器的连接
1 | <script> |
五、其他
1. 自定义指令
- 除了 Vue 内置的一系列指令(比如 v-model 或 v-show),Vue 还允许注册自定义指令。自定义指令主要是为了重用涉及普通元素的底层 DOM 访问的逻辑
1 | // 全局指令 |
- 自定义指令的生命周期:
1 | const myDirective = { |
- 对于自定义指令来说,一个很常见的情况是需要在
mounted
和updated
上实现相同的行为,并且不需要其他钩子。这种情况下可以直接用一个函数来定义指令:
1 | app.directive('color', (el, binding) => {...}) |
2. 过渡效果
- Vue 提供了两个内置组件,可以帮助制作基于状态变化的过渡和动画
Transition
会在一个元素或组件进入和离开 DOM 时应用动画TransitionGroup
会在一个 v-for 列表中的元素或组件被插入、移动或移除时应用动画
1 | <!-- 基本使用 --> |
3. 其他
1 | // es6 第一种导入导出 |