vue3-基础知识(4)- 组件
迪丽瓦拉
2024-01-29 19:04:07
0

组件

通用型组件就是各大组件库的组件风格,包括按钮、表单、弹窗等通用功能。
业务型组件包含业务的交互逻辑,包括购物车、登录注册等,会和我们不同的业务强绑定。

特点

  1. 可通过具名导出在一个文件中导出多个组件
  2. 在 DOM 模板中,我们必须显式地写出关闭标签
  3. 限制
  • 某些 HTML 元素对于放在其中的元素类型有限制,例如
        , 和
    1. 一个可以通过其“name”选项递归渲染自己的组件,(如果使用单文件组件,则从文件名推断)
    2. 全局注册组件问题
    • 需要注册
    • 全局注册,但并没有被使用的组件无法在生产打包时被自动移除
    • 全局注册在大型项目中使项目的依赖关系变得不那么明确,定位不易,不好维护。
    1. 局部组件(推荐)
    • 无需注册,引入直接使用
    • 局部注册的组件需要在使用它的父组件中显式导入
    • 只能在该父组件中使用。
    • 使组件之间的依赖关系更加明确,并且对 tree-shaking 更加友好
    1. 格式-双驼峰(推荐)
    2. props
    • 为了和 HTML attribute 对齐
      • 一般将props传入写为kebab-case形式
      • 仅写上 prop 但不传值,会隐式转换为 true
    • 组件名-双驼峰(推荐)
    • 单向绑定、单向数据流
    • prop只读,组件内不可更新
    • prop更改场景
      • prop为初始值,后续作为组件内部变量使用。可使用ref(props.a)
      • 转换prop值。使用computed
    • 更改对象 / 数组类型的 props,可被更改但不推荐。推荐使用抛出事件来处理。
    • defineProps() 宏中的参数不可以访问
  • 另一种在组件内实现 v-model 的方式是使用一个可写的,同时具有 getter 和 setter 的计算属性。get 方法需返回 modelValue prop,而 set 方法需触发相应的事件
      
    
  1. 透传
  • 当一个组件以单个元素为根作渲染时,透传的 attribute 会自动被添加到根元素上
  • 如果一个子组件的根元素已经有了 class 或 style attribute,它会和从父组件上继承的值合并
  • 监听器同样式效果
  • 下一个组件会在根节点上渲染另一个组件,会透传。
  • 如果你不想要一个组件自动地继承 attribute,你可以在组件选项中设置inheritAttrs: false
  • 禁用透传的组件中
    • 直接用 $attrs 访问。
    • 使用v-bind="$attrs"将传递的数据进一步传给其他指定组件。
    • 访问:const attrs = useAttrs()
    • attrs不是响应式
    • 需要使用响应式attrs
      • 使用 prop
      • 使用 onUpdated() 使得在每次更新时结合最新的 attrs 执行副作用
  • 有着多个根节点的组件没有自动 attribute 透传行为,如果 $attrs 没有被显式绑定,将会抛出一个运行时警告。
  1. 插槽
  • 具名作用域插槽
    分两个点,名字和插槽数据传递
    子组件内插槽:
      
    父组件使用:
      {{ slotProps.text }} {{ slotProps.count }}
    
  • 高级列表组件示例
      
    
    使用:
      
  • 无渲染组件
    • 只包括了逻辑而不需要自己渲染内容,视图输出通过作用域插槽全权交给了消费者组件。我们将这种类型的组件称为无渲染组件。
    • 适用:作用域插槽在需要同时封装逻辑、组合视图界面时
  1. 依赖注入
  • 一个父组件相对于其所有的后代组件,会作为依赖提供者。任何后代的组件树,无论层级有多深,都可以注入由父组件提供给整条链路的依赖。
  • 用法:
    注入:
      
    
    调用:
      
    
  • 当提供 / 注入响应式的数据时,建议尽可能将任何对响应式状态的变更都保持在供给方组件中。这样可以确保所提供状态的声明和变更操作都内聚在同一个组件内,使其更容易维护。
  • 在注入方组件中更改数据,提供refAsetRefA两个函数。
  • 确保数据被注入方的组件更改:readonly()
  • 推荐在一个单独的文件中导出这些注入名 Symbol
  1. 异步组件
  • 用法:
  const AsyncComp = defineAsyncComponent(() =>import('./components/MyComponent.vue'))...const AsyncComp = defineAsyncComponent({// 加载函数loader: () => import('./Foo.vue'),// 加载异步组件时使用的组件loadingComponent: LoadingComponent,// 展示加载组件前的延迟时间,默认为 200msdelay: 200,// 加载失败后展示的组件errorComponent: ErrorComponent,// 如果提供了一个 timeout 时间限制,并超时了// 也会显示这里配置的报错组件,默认值是:Infinitytimeout: 3000})
  • 搭配内置组件 Suspense 使用

API用法

  1. defineProps,编译宏命令,不需要显示引入,可直接使用。
  2. defineEmits
    设置:
  definedEmits(['sendData'])

使用:

  emit('sendData', data)
  1. v-model
    设置:
  definedProps({modelValue: 'x'})const emit = definedEmits(['update:modelValue'])

使用:

  emit('update:modelValue')

相关内容