重看Vue文档第二天(深入组件总结)

本文详细介绍了Vue.js组件的注册、属性、事件、插槽、依赖注入以及动态和异步组件的使用。强调了单向数据绑定、属性验证、自定义事件和插槽的作用,还提到了如何利用`<keep-alive>`优化性能,以及通过`provide/inject`实现跨层级的数据传递。同时,讨论了手动强制更新组件和代码分割优化的策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

组件注册
  • 全局注册往往是不够理想的,如果你使用像webpack的构建系统,全局注册所有的组件意味着即便你已经不再使用其中一个组件了,它仍然会被包含在最终的构建结果中。
Props
  • 你可以以对象形式列出prop,这些property的名称和值分别是prop各自的名称和类型;
  • 即便传入的数字、布尔值、数组、对象是静态的情况下,我们仍需要通过v-bind来告诉Vue这是一个js表达式而不是一个字符串;
  • 所有的prop都使得其父子prop之间形成了一个单向下行绑定;
  • 父级prop的更新会向下流动到子组件中,但是反过来则不行;
  • 这样会防止从子组件意外变更父级组件的状态,从而导致你的应用的数据流向难以理解;
  • 作为一个通用规则,应该避免修改任何prop,包括对象和数组,这种做法无视了单向数据绑定;
  • type可以是下列原生构造函数中的一个:StringNumberBooleanArrayObjectDateFunctionSymbol
非Prop的Attribute
  • 当组件返回单个根节点时,非prop的attribute将自动添加到根节点的attribute中;
  • 当一个具有change事件的HTML元素作为date-picker的根元素时,change事件监听器将从父组件传递到子组件,它将在原生<select>change事件上触发;
  • 如果你不希望组件的根元素继承attribute,可以在组件的选项中设置inheritAttrs: false
  • 禁用attribute继承的常见场景是需要将attribute应用于根节点之外的其他元素;
app.component('date-picker', {
  inheritAttrs: false,
  template: `
    <div class="date-picker">
      <input type="datetime-local" v-bind="$attrs" />
    </div>
  `
})
  • 具有多个根节点的组件不具有自动attribute隐式贯穿行为,如果未显式绑定$attrs,将发出运行时警告。
自定义事件
  • 当在emits选项中定义了原生事件(如click)时,将使用组件中的事件替代原生事件侦听器。
插槽
  • 如果<todo-button>的template中没有一个<slot>元素,则该组件起始标签和结束标签之间的任何内容都会被抛弃;
  • 父级模板里的所有内容都是在父级作用域中编译的,子模版的所有内容都是在子作用域中编译的;
  • <slot>元素有一个特殊的attribute:name,通过它可以为不同的插槽分配独立的ID,也就能够以此来决定内容应该渲染到什么地方;
  • 一个不带name<slot>出口会带有隐含的名字”default“;
  • 在向具名插槽提供内容的时候,我们可以在一个<template>元素上使用v-slot指令,并以v-slot的参数的形式提供其名称;
  • 只要出现多个插槽,请始终为所有的插槽使用完整的基于<template>的语法;
  • 作用域插槽的内部工作原理是将你的插槽内容包括在一个传入参数的函数里;
  • 缩写:v-slot:header可以被重写为#header
Provide/Inject
  • 无论组件层次结构有多深,父组件都可以作为其所有子组件的依赖提供者;
  • 父组件有一个provide选项来提供数据,子组件有一个inject选项来开始使用这些数据;
  • 如果需要访问组件实例property,我们需要将provide转换为返回对象的函数;
  • 实际上,你可以将依赖注入看作是”长距离的prop“,除了:

① 父组件不需要知道哪些子组件使用了它provide的property;
② 子组件不需要知道inject的property来自哪里。

  • 在默认情况下,provide/inject绑定并不是响应式的;
  • 我们可以通过传递一个refproperty或reactive对象给provide来改变这种行为;
app.component('todo-list', {
  // ...
  provide() {
    return {
      todoLength: Vue.computed(() => this.todos.length)
    }
  }
})

app.component('todo-list-statistics', {
  inject: ['todoLength'],
  created() {
    console.log(`Injected property: ${this.todoLength.value}`) // > 注入的 property: 5
  }
})
  • 在这种情况下,任何对todos.length的改变都会被正确地反映在注入todoLength的组件中。
动态组件&异步组件
  • 当在这些组件之间切换的时候,你有时候会想保持这些组件的状态,以避免反复渲染导致的性能问题;
  • 如果我们更希望那些标签的组件实例能够被在它们第一次被创建的时候缓存下来,可以用一个<keep-alive>元素将其动态组件包裹起来;
<!-- 失活的组件将会被缓存!-->
<keep-alive>
  <component :is="currentTabComponent"></component>
</keep-alive>
  • 在大型应用中,我们可能需要将应用分割成小一些的代码块,并且只在需要的时候才从服务器加载一个模块;
  • 为了实现这个效果,Vue有一个defineAsyncComponent方法;
  • 把webpack2及以上版本和ES2015语法相结合后,我们就可以这样使用动态地导入:
import { defineAsyncComponent } from 'vue'

const AsyncComp = defineAsyncComponent(() =>
  import('./components/AsyncComponent.vue')
)

app.component('async-component', AsyncComp)
模板引用
  • 有时候你可能仍然需要在js中直接访问子组件,可以使用refattribute为子组件或HTML元素指定引用ID;
<input ref="input" />
  • 注意:$refs只会在组件渲染完成之后生效。这仅作为一个用于直接操作子元素的”逃生舱“—你应该避免在模板或计算属性中访问$refs
处理边界情况
  • 得益于其响应性系统,Vue总是知道何时更新;
  • 但是,在某些边缘情况下,你可能希望强制更新(尽管事实上没有任何响应式数据发生更改);
  • 排除使用错误的情况,如果必须手动强制更新,可以使用$forceUpdate(不建议经常使用);
  • 通过向根元素添加v-once指令来确保之对其求值一次,然后进行缓存(不建议经常使用)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值