vue3学习笔记

99 阅读3分钟

模板语法

vue 使用一种基于 HTML 的模板语法,使我们能够声明式地将其组件实例的数据绑定到呈现的 DOM 上。所有的 Vue 模板都是语法层面合法的 HTML,可以被符合规范的浏览器和 HTML 解析器解析。

v-bind:绑定属性(简写 :) :id='id'

DOM更新机制

当更新响应式状态时候,DOM自动更新.但是不是同步,Vue会缓存他们直到更新周期的"下一个时机",确保无论你进行了多少次状态更换,每个组件只更新一下.

若要等待一个状态改变后的 DOM 更新完成,你可以使用 nextTick() 这个全局 API

绑定对象class


<div :class="{ active: isActive ,'text-danger': hasError}"></div>

<div :class="[activeClass, errorClass]"></div>

<div :class="[{ active: isActive }, errorClass]"></div>等价与
<div :class="[isActive ? activeClass : '', errorClass]"></div>

如果你的组件有多个根元素,你将需要指定哪个根元素来接收这个 class。你可以通过组件的 $attrs 属性来实现指定

<!-- MyComponent 模板使用 $attrs 时 -->
<p :class="$attrs.class">Hi!</p>
<span>This is a child component</span>
<MyComponent class="baz" />

渲染为

<p class="baz">Hi!</p>
<span>This is a child component</span>

绑定内联样式

<div :style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>

v-if vs. v-show

v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要频繁切换,则使用 v-show 较好;如果在运行时绑定条件很少改变,则 v-if 会更合适

## v-for 与对象

遍历的顺序会基于对该对象调用 Object.keys() 的返回值来决定。

<li v-for="(value, key) in myObject"> {{ key }}: {{ value }} </li>

Vue 能够侦听响应式数组的变更方法,并在它们被调用时触发相关的更新 push(),pop(),shift(),unshift(),splice(),sort(),reverse()

以下方法filter(),concat(),slice()不会更改原数组,而是返回新数组

watch 监听

默认情况下,监听器的回调,在vue组件更新之前被调用,所以在监听器中调用DOM.是vue更新的状态, 如果想在侦听器回调中能访问被 Vue 更新之后的 DOM,你需要指明 flush: 'post' 选项

export default {
  // ...
  watch: {
    key: {
      handler() {},
      flush: 'post'
    }
  }
}

v-model 的自定义表单组件

v-modal的原理

<input v-model="searchText" />

等价于

<input :value="searchText" @input="searchText = $event.target.value" />

自定义


<!-- CustomInput.vue -->
<script>
export default {
  props: ['modelValue'],
  emits: ['update:modelValue']
}
</script>

<template>
  <input
    :value="modelValue"
    @input="$emit('update:modelValue', $event.target.value)"
  />
</template>
<CustomInput v-model="searchText" />

v-model 的参数

<!-- MyComponent.vue -->
<script>
export default {
  props: ['title'],
  emits: ['update:title']
}
</script>

<template>
  <input
    type="text"
    :value="title"
    @input="$emit('update:title', $event.target.value)"
  />
</template>
<MyComponent v-model:title="bookTitle" />

处理 v-model 修饰符

<MyComponent v-model.capitalize="myText" />
<script>
export default {
  props: {
    modelValue: String,
    modelModifiers: {
      default: () => ({})
    }
  },
  emits: ['update:modelValue'],
  methods: {
    emitValue(e) {
      let value = e.target.value
      if (this.modelModifiers.capitalize) {
        value = value.charAt(0).toUpperCase() + value.slice(1)
      }
      this.$emit('update:modelValue', value)
    }
  }
}
</script>

<template>
  <input type="text" :value="modelValue" @input="emitValue" />
</template>

插槽

具名插槽

父组件
<template v-slot:header> <!-- 插槽的内容放这里 --> </template>
//简写
<template #header> <!--插槽的内容放这里 --> </template>

子组件

<slot name="header"></slot>

动态插槽名

<template v-slot:[dynamicSlotName]> ... </template> 

<!-- 缩写为 -->
<template #[dynamicSlotName]> ... </template>

作用域插槽

插槽的内容无法访问到子组件的状态。 然而在某些场景下插槽的内容可能想要同时使用父组件域内和子组件域内的数据。要做到这一点,我们需要一种方法来让子组件在渲染时将一部分数据提供给插槽。 我们也确实有办法这么做!可以像对组件传递 props 那样,向一个插槽的出口上传递 attributes。

<!-- <MyComponent> 的模板 -->
<div>
  <slot :text="greetingMessage" :count="1"></slot>
</div>

<MyComponent v-slot="slotProps">
  {{ slotProps.text }} {{ slotProps.count }}
</MyComponent>

KeepAlive

内置组件,在多个组件之间动态切换缓存被移除的组件实例

include 和 exclude 控制组件是否被缓存,会根据组件的name进行缓存,值可以是:字符串,正则,数组

<!-- 以英文逗号分隔的字符串 -->
<KeepAlive include="222,3333">
  //组件
</KeepAlive>


注: vue3中,使用setup 单文件会根据文件名生成对应的name选项。

最大缓存实例数 max

<KeepAlive :max="10">
  //组件
</KeepAlive>

缓存实例的生命周期

当一个组件实例从 DOM 上移除但因为被 <KeepAlive> 缓存而仍作为组件树的一部分时,它将变为不活跃状态而不是被卸载。当一个组件实例作为缓存树的一部分插入到 DOM 中时,它将重新被激活

export default {
  activated() {
    // 在首次挂载、
    // 以及每次从缓存中被重新插入的时候调用
  },
  deactivated() {
    // 在从 DOM 上移除、进入缓存
    // 以及组件卸载时调用
  }
}

Teleport

内置组件,将一个组件内部一部分模板传送给该组件的DOM结构外层位置

to 用于指定传送目标,可以是css选择器字符,或者dom元素对象。

disabled 禁止传送

:必须确保目标元素已存在

Suspense

<Suspense> 是一个内置组件,用来在组件树中协调对异步依赖的处理。它让我们可以在组件树上层等待下层的多个嵌套异步依赖项解析完成,并可以在等待时渲染一个加载状态

<Suspense> 可以等待的异步依赖有两种:

  1. 带有异步 setup() 钩子的组件。这也包含了使用 <script setup> 时有顶层 await 表达式的组件。
  2. 异步组件

<Suspense> 组件有两个插槽:#default 和 #fallback。两个插槽都只允许一个直接子节点。在可能的时候都将显示默认槽中的节点。否则将显示后备槽中的节点。

<Suspense> 在等待新内容和异步依赖完成时,会展示之前 #default 插槽的内容。这个行为可以通过一个 timeout prop 进行配置:在等待渲染新内容耗时超过 timeout 之后,<Suspense> 将会切换为展示后备内容。若 timeout 值为 0 将导致在替换默认内容时立即显示后备内容。

事件

<Suspense> 组件会触发三个事件:pendingresolve 和 fallbackpending 事件是在进入挂起状态时触发。resolve 事件是在 default 插槽完成获取新内容时触发。fallback 事件则是在 fallback 插槽的内容显示时触发。

单文件组件

Single-File Component,简称 SFC