首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >掌握这些容易被忽略的Vue组件细节,提升开发效率,事半功倍!

掌握这些容易被忽略的Vue组件细节,提升开发效率,事半功倍!

作者头像
奋飛
发布2023-07-10 11:38:10
发布2023-07-10 11:38:10
6720
举报
文章被收录于专栏:Super 前端Super 前端

组件允许我们将 UI 划分为独立的、可重用的部分,并且可以对每个部分进行单独的思考。

组件在日常开发的重要性不言而喻,掌握下述细则,可以让你在开发中事半功倍!

Props

defineProps() 宏中的参数不可以访问 <script setup> 中定义的其他变量,因为在编译时整个表达式都会被移到外部的函数中。

  • Boolean 外的未传递的可选 prop 将会有一个默认值 undefined
  • Boolean 类型的未传递 prop 将被转换为 false。这可以通过为它设置 default 来更改——例如:设置为 default: undefined 将与非布尔类型的 prop 的行为保持一致。

事件

组件触发的事件没有冒泡机制。只能监听直接子组件触发的事件。平级组件或是跨越多层嵌套的组件间通信,应使用一个外部的事件总线,或是使用一个全局状态管理方案

我们在 <template> 中使用的 $emit 方法不能在组件的 <script setup> 部分中使用,需要通过 defineEmits()

代码语言:javascript
复制
<script setup>
const emit = defineEmits(['inFocus', 'submit'])

function buttonClick() {
  emit('submit')
}
</script>

注意:defineEmits()不能在子函数中使用。必须直接放置在 <script setup> 的顶级作用域下。

事件校验

可以通过返回一个布尔值,来表明事件是否合法。

代码语言:javascript
复制
<script setup>
const emit = defineEmits({
  // 没有校验
  click: null,

  // 校验 submit 事件
  submit: ({ email, password }) => {
    if (email && password) {
      return true
    } else {
      console.warn('Invalid submit event payload!')
      return false
    }
  }
})

function submitForm(email, password) {
  emit('submit', { email, password })
}
</script>

v-model

单个组件上,需要创建多个双向绑定值时,我们可以采用多个 v-model

代码语言:javascript
复制
<CustomInput v-model:title="title" v-model:msg="msg" />
代码语言:javascript
复制
<!-- CustomInput.vue -->
<script setup>
import { computed } from 'vue'

const props = defineProps(['title', 'msg'])
const emit = defineEmits(['update:title', 'update:msg'])

const titleValue = computed({
  get() {
    return props.title
  },
  set(value) {
    emit('update:title', value)
  }
})
const msgValue = computed({})
</script>

<template>
  <input v-model="titleValue" />
</template>

注意,子组件 v-model 不能直接绑定 title/msg。

v-model cannot be used on a prop, because local prop bindings are not writable.

透传 Attributes

透传Attributes,是指由父组件传入,且没有被子组件声明为 props 或是组件自定义事件的 attributes 和事件处理函数。

代码语言:javascript
复制
<MyButton class="large" @click="onClick"/>

想要所有像 classv-on 监听器这样的透传 attribute 都应用在内部的 <button> 上而不是外层的 <div> 上。使用 inheritAttrs: false 来禁用 attribute 继承。

代码语言:javascript
复制
<!-- MyButton -->
<div class="btn-wrapper">
  <button class="btn" v-bind="$attrs">click me</button>
</div>

<script>
// 使用普通的 <script> 来声明选项
export default {
  inheritAttrs: false
}
</script>

需要注意的是,虽然这里的 attrs 对象总是反映为最新的透传 attribute,但它并不是响应式的 (考虑到性能因素)。你不能通过侦听器去监听它的变化。如果你需要响应性,可以使用 prop。

作用域插槽

场景:数据源自子组件,样式等希望父组件自己控制。

代码语言:javascript
复制
<!-- FancyList -->
<ul>
  <li v-for="item in items">
    <slot name="item" v-bind="item"></slot>
  </li>
</ul>

<FancyList> 封装一些加载远端数据的逻辑、使用数据进行列表渲染、或者是像分页或无限滚动这样更进阶的功能

注意,我们这里使用了 v-bind 来传递插槽的 props。

代码语言:javascript
复制
<FancyList :api-url="url" :per-page="10">
  <template #item="{ body, username, likes }">
    <div class="item">
      <p>{{ body }}</p>
      <p>by {{ username }} | {{ likes }} likes</p>
    </div>
  </template>
</FancyList>

对单个列表元素内容和样式的控制权留给使用它的父组件。

依赖注入

  • 使用 Symbol 作注入名以避免潜在的冲突(推荐在一个单独的文件中导出这些注入名 Symbol);
  • 任何对响应式状态的变更都保持在供给方组件中;
  • 为确保提供的数据不能被注入方的组件更改,可以使用 readonly() 来包装提供的值
代码语言:javascript
复制
// keys.js
export const location = Symbol()
代码语言:javascript
复制
<!-- 在供给方组件内 -->
<script setup>
import { provide, ref } from 'vue'
import { location } from './keys.js'

const locationRef = ref('North Pole')

function updateLocation() {
  locationRef.value = 'South Pole'
}

provide(location, {
  // 确保注入方不可以更改 
  readonly(location),
  updateLocation
})
</script>
代码语言:javascript
复制
<!-- 在注入方组件 -->
<script setup>
import { inject } from 'vue'
import { location } from './keys.js'  

const { locationRef, updateLocation } = inject(location)
</script>

<template>
  <button @click="updateLocation">{{ locationRef }}</button>
</template>
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-06-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Props
  • 事件
    • 事件校验
  • v-model
  • 透传 Attributes
  • 作用域插槽
  • 依赖注入
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档