A project to study the vue3.
config:配置目录,包括端口号等,可以默认 node_modules:npm加载的项目依赖模块。 src:这里是我们要开发的目录, assets:放置一些图片,如,logo components:目录里放置了一个组件文件,可以不用 App.vue:项目的入口文件,我们可以将组件写这里,不使用components main.js:项目的核心文件 static:静态资源目录,如图片字体等 test:初始测试文件可以删除 .xxxx:配置文件 index.html:首页入口文件, package:项目配置文件
在文本插值:{{}}
中可以使用Javascript表达式
每个文本插值的绑定仅支持单一表达式,也就是一段能够被求值的JavaScript代码。一个简单的判断方法是是否可以写在return后面。
条件判断语句也不可以,必须是单一表达式,可以使用三目表达式。
双大括号会将数据插值为纯文本,而不是HTML,若想插入HTML,使用v-html
指令
双大括号不能在HTML attributes 中使用,想要响应式的绑定一个attribute,应该使用v-bind
指令
<div v-bind:class="msg">测试</div>
文本值的绑定是通过双花括号,属性的绑定通过v-bind
:
v-bind
指令指示Vue将元素的id attribute 与组件的dynamicID属性保持一致,如果绑定的值是null或
undefined,那么该attribute将会从渲染的元素上移除
简写:<div :class="msg"></div>
布尔型attribute 依据 true/false 值来决定 attribute 是否应该存在于该元素上,disabled是常见例子
可以通过JavaScript对象来动态绑定多个attribute
在Vue中,提供了条件渲染,这类似于JS中的条件语句:
·v-if ·v-else ·v-else-if ·v-show
v-if
指令用于条件性的渲染一块内容,这块内容只会在指令的表达式返回真值时才会被渲染
v-if
vs v-show
v-if
是"真实的"按条件渲染,因为它确保了在切换时,条件区块内的事件监听器和子组件都会被销毁与重建。
v-if
也是惰性的:如果在初次渲染时条件值为false,则不会做任何事。条件区块只有当条件首次变为true时才被渲染。
相比之下,v-show
简单许多,元素无论初始条件如何,始终会被渲染,只有CSS display属性会被切换。
总的来说,v-if
.有更高的切换开销,而v-show
有更高的初始渲染开销。
因此,如果需要频繁切换,则使用v-show
较好;如果在运行时绑定条件很少改变,则v-if
会更合适。
可以使用v-for
指令基于一个数组来渲染一个列表,v-for
指令的值需要使用item in items
的语法
其中items是元数据的数组,而item是迭代项的别名
v-for
也可以支持使用可选的第二个参数表示当前项的位置索引。
也可以使用of替代in作为分隔符,更接近JS的语法
v-for
可以遍历一个对象的所有属性
通过key管理状态
Vue默认按照"就地更新"的策略来更新通过v-for
渲染的元素列表。当数据项的顺序改变时,
Vue不会随之移动DOM元素的顺序,而是就地更新每个元素,确保它们在原本指定的索引位置上渲染。
为了给Vue一个提示,以便它可以跟踪每个节点的标识,从而重用和重新排序现有的元素,
你需要为每个元素对应的块提供一个唯一的key attribute
提示
key在这里是一个通过v-bind
绑定的特殊attribute
推荐在任何可行的时候为v-for
提供一个key attribute
key绑定的值期望是一个基础类型的值,例如字符串或number类型
我们可以使用v-on
指令(简写为@
)来监听DOM事件,并在事件触发时执行对应的JavaScript。
用法:
v-on:click="methodName"
@click="handler"
事件处理器的值可以是
- 内联事件处理器:事件被触发时执行的内联JavaScript语句(与onclick类似)
- 方法事件处理器:一个指向组件上定义的方法的属性名或是路径
事件参数可以获取event对象和通过事件传递数据
事件修饰符
在处理事件时调用 even.preventDefault()
或 event.stopPropagation()
是很常见的。
尽管我们可以直接在方法内调用,但如果方法能更专注于数据逻辑而不用去处理 DOM 事件的细节
会更好为解决这一问题,Vue 为 v-on
提供了事件修饰符,常用有以下几个:
.stop
.prevent
.once
.enter
具体参考地址:https://cn.vuejs.org/guide/essentials/event-handling.html#event-modifiers
变更方法:Vue 能够侦听响应式数组的变更方法,并在它们被调用时触发相关的更新。这些变更方法包括:
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
替换一个数组:变更方法,顾名思义,就是会对调用它们的原数组进行变更。 相对地,也有一些不可变 (immutable)方法,例如
filter()
concat()
slice()
这些都不会更改原数组,而总是返回一个新数组。当遇到的是非变更方法时,我们需要将旧的数组替换为新的
模板中的表达式虽然方便,但也只能用来做简单的操作。如果在模板中写太多逻辑,会让模板变得臃肿,难以维护。 因此我们推荐使用计算属性来描述依赖响应式状态的复杂逻辑.
计算属性缓存 vs 方法
你可能注意到我们在表达式中像这样调用一个函数也会获得和计算属性相同的结果
重点区别:
- 计算属性:计算属性值会基于其响应式依赖被缓存。一个计算属性仅会在其响应式依赖更新时才重新计算
- 方法:方法调用总是会在重渲染发生时再次执行函数
数据绑定的一个常见需求场景是操纵元素的 CSS class 列表,因为 class
是 attribute,
我们可以和其他attribute 一样使用 v-bind
将它们和动态的字符串绑定。
但是,在处理比较复杂的绑定时,通过拼接生成字符串是麻烦且易出错的。
因此,Vue 专门为 class
的 v-bind
用法提供了特殊的功能增强。
除了字符串外,表达式的值也可以是对象或数组
数组和对象嵌套过程中,只能是数组嵌套对象,不能反其道而行
数据绑定的一个常见需求场景是操纵元素的 CSS style列表,
因为style
是 attribute,我们可以和其他attribute一样使用 v-bind
将它们和动态的字符串绑定。
但是,在处理比较复杂的绑定时,通过拼接生成字符串是麻烦且易出错的。
因此,Vue 专门为style
的 v-bind
用法提供了特殊的功能增强。
除了字符串外,表达式的值也可以是对象或数组
我们可以使用 watch
选项在每次响应式属性发生变化时触发一个函数
在前端处理表单时,我们常常需要将表单输入框的内容同步给JavaScript 中相应的变量。
手动连接值绑定和更改事件监听器可能会很麻烦,v-model
指令帮我们简化了这一步骤。
v-model
也提供了修饰符:
.lazy
.number
.trim
默认情况下,v-mode
会在每次 input
事件后更新数据,添加.lazy
修饰符来改为在每次 change
事件后更新数据
虽然 Vue 的声明性渲染模型为你抽象了大部分对 DOM 的直接操作, 但在某些情况下,我们仍然需要直接访问底层 DOM 元素。
要实现这一点, 我们可以使用特殊的 ref
attribute
挂载结束后引用都会被暴露在this.$refs
之上
组件最大的优势就是可复用性
当使用构建步骤时,我们一般会将Vue组件定义在一个单独的.vue
文件中,这被叫做单文件组件(简称SFC)
组件组成结构
<template>
<div>承载标签</div>
</template>
<script>
export default {}
</script>
<style scoped>
</style>
组件引入
<template>
<!--第三步:显示组件-->
<MyComponent />
</template>
<script>
// 第一步:引入组件
import MyComponent from"./components/MyComponent.vue
export default {
//第二步:注入组件
components:{
MyComponent
}
}
</script>
scoped
:让当前样式只在当前组件中生效而不是全局生效
组件允许我们将 UI 划分为独立的、可重用的部分, 并且可以对每个部分进行单独地思考。在实际应用中,组件常常被组织成层层嵌套的树状结构 这和我们嵌套 HTML 元素的方式类似,Vue 实现了自己的组件模型, 使我们可以在每个组件内封装自定义内容与逻辑
一个 Vue 组件在使用前需要先被“注册”,这样 Vue 才能在渲染模板时找到其对应的实现。 组件注册有两种方式:全局注册和局部注册
全局注册
-
import {createApp }from 'vue
-
import App from'./App.vue'
-
import Globalcomponent from "./components/Globalcomponent.vue
-
const app =createApp(App);
-
app.component("Globalcomponent",Globalcomponent)app.mount('#app');
-
<template>
-
<h3>全局应用组件</h3>
-
</template>
全局注册虽然很方便,但有以下几个问题:
- 全局注册,但并没有被使用的组件无法在生产打包时被自动移除(也叫“tree-shaking")。 如果你全局注册了一个组件,即使它并没有被实际使用,它仍然会出现在打包后的JS 文件中
- 全局注册在大型项目中使项目的依赖关系变得不那么明确。 在父组件中使用子组件时, 不太容易定位子组件的实现。和使用过多的全局变量一样,这可能会影响应用长期地可维护性
局部注册需要使用components
选项
组件与组件之间不是完全独立的,而是有交集的,那就是组件与组件之间是可以传递数据的传递
数据的解决方案就是 props
传递数据 props
只能从父级传递到子级不能反其道而行
通过 props
传递数据,不仅可以传递字符串类型的数据,还可以是其他类型,
例如:数字、对象、数组等,但实际上任何类型的值都可以作为 props
的值被传递。
Vue 组件可以更细致的声明对传入的 props
的校验要求
props
是只读的,不能修改父元素传来的数据。
在组件的模板表达式中,可以直接使用$emit
方法触发自定义事件
触发自定义事件的目的是组件之间传递数据
如果是用户输入,我们希望在获取数据的同时发送数据配合 v-mode
来使用
我们之前讲解过了组件之间的数据传递,,props
和 自定义事件 两种方式
props
:父传子- 自定义事件:子传父
除了上述的方案,props
也可以实现子传父(通过函数进行数据传递)。
"透传 attribute"指的是传递给一个组件,却没有被该组件声明为 props
或 emits
的
attribute 或者 v-on
事件监听器。最常见的例子就是 class
、style
和 id
当一个组件以单个元素为根作渲染时,透传的 attribute 会自动被添加到根元素上
我们已经了解到组件能够接收任意类型的JavaScript 值作为 props,但组件要如何接收模板内容呢? 在某些场景中,我们可能想要为子组件传递一些模板片段,让子组件在它们的组件中渲染这些片段。
元素是一个插槽出口 (slot outlet),标示了父元素提供的插槽内容(slot content)将在哪里被渲染.
插槽内容可以访问到父组件的数据作用域,因为插槽内容本身是在父组件板中定义的.
在外部没有提供任何内容的情况下,可以为插槽指定默认内容
v-slot
有对应的简写#
,因此 <template v-slot:header
可以简写为 <template #header
。
其意思就是“将这部分模板片段传入子组件的 header
插槽中”
在某些场景下插槽的内容可能想要同时使用父组件域内和子组件域内的数据。要做到这一点, 我们需要一种方法来让子组件在渲染时将一部分数据提供给插槽, 我们可以像对组件传递 props 那样,向一个插槽的出口上传递 attributes
每个 Vue 组件实例在创建时都需要经历一系列的初始化步骤,比如设置好数据侦听,编译模板, 挂载实例到DOM,以及在数据改变时更新 DOM。在此过程中,它也会运行被称为生命周期钩子的函数, 让开发者有机会在特定阶段运行自己的代码。
生命周期函数
- 创建期:beforeCreate created
- 挂载期:beforeMount mounted
- 更新期:beforeUpdate updated
- 销毁期:beforeUnmount unmounted
组件的生命周期会随着我们对ve 的了解越多,也会越来越重要,这里我们先讲两个常用的应用常见
- 通过
ref
获取元素DOM结构 - 模拟网络请求渲染数据
有些场景会需要在两个组件间来回切换,比如 Tab 界面
当使用 <component :is=…">
来在多个组件间作切换时,被切换掉的组件将会被卸载。
我们可以通过<keep-alive>
组件强制被切换掉的组件仍然保持“存活”的状态。
在大型项目中,我们可能需要拆分应用为更小的块,并仅在需要时再从服务器加载相关组件。
Vue 提供了 defineAsyncComponent
方法来实现此功能。
通常情况下当我们需要从父组件向子组件传递数据时,会使用 props
。想象一下这样的结构:
有一些多层级嵌套的组件,形成了一颗巨大的组件树,而某个深层的子组件需要一个较远的祖先组件中的部分数据。
在这种情况下,如果仅使用 props 则必须将其沿着组件链逐级传递下去,这会非常麻烦
这一问题被称为 “prop 逐级透传'
provide
和 inject
可以帮助我们解决这一问题。
一个父组件相对于其所有的后代组件,会作为依赖提供者。任何后代的组件树,无论层级有多深,
都可以注入由父组件提供给整条链路的依赖。
provide
和 inject
只能由上到下的传递,不能反向传递
每个 Vue 应用都是通过 createApp
函数创建一个新的应用实例
我们传入createApp
的对象实际上是一个组件,每个应用都需要一个“根组件”,其他组件将作为其子组件。
应用实例必须在调用了 app.mount()
方法后才会渲染出来。该方法接收一个“容器"参数,可以是一个实际的 DOM元素或是一个 CSS 选择器字符串
在 src
目录下的 assets
文件夹的作用就是存放公共资源,例如:图片、公共CSS或者字体图标等
浏览器可执行文件:
- HTML
- CSS
- Javascript
- Image