首页 > 其他分享 >vue3进阶——组件基础

vue3进阶——组件基础

时间:2023-06-13 17:45:40浏览次数:41  
标签:Vue 进阶 title vue3 props 组件 ref emit

组件允许我们将 UI 划分为独立的、可重用的部分,并且可以对每个部分进行单独的思考。在实际应用中,组件常常被组织成层层嵌套的树状结构,这和我们嵌套 HTML 元素的方式类似,Vue 实现了自己的组件模型,使我们可以在每个组件内封装自定义内容与逻辑。
image

定义组件

当使用构建步骤时,我们一般会将 Vue 组件定义在一个单独的 .vue 文件中,这被叫做单文件组件 (简称 SFC):

<script setup>
import { ref } from 'vue'

const count = ref(0)
</script>

<template>
  <button @click="count++">You clicked me {{ count }} times.</button>
</template>

当不使用构建步骤时,一个 Vue 组件以一个包含 Vue 特定选项的 JavaScript 对象来定义:

import { ref } from 'vue'

export default {
  setup() {
    const count = ref(0)
    return { count }
  },
  template: `
    <button @click="count++">
      You clicked me {{ count }} times.
    </button>`
  // 或者 `template: '#my-template-element'`
}

这里的模板是一个内联的 JavaScript 字符串,Vue 将会在运行时编译它。你也可以使用 ID 选择器来指向一个元素 (通常是原生的 <template> 元素),Vue 将会使用其内容作为模板来源。
上面的例子中定义了一个组件,并在一个 .js 文件里默认导出了它自己,但你也可以通过具名导出在一个文件中导出多个组件。

使用组件

要使用一个子组件,我们需要在父组件中导入它。假设我们把计数器组件放在了一个叫做 ButtonCounter.vue 的文件中,这个组件将会以默认导出的形式被暴露给外部。当然,你也可以全局地注册一个组件,使得它在当前应用中的任何组件上都可以使用,而不需要额外再导入。

<script setup>
import ButtonCounter from './ButtonCounter.vue'
</script>

<template>
  <h1>Here is a child component!</h1>
  <ButtonCounter />
</template>

在单文件组件中,推荐为子组件使用 PascalCase 的标签名,以此来和原生的 HTML 元素作区分。虽然原生 HTML 标签名是不区分大小写的,但 Vue 单文件组件是可以在编译中区分大小写的。我们也可以使用 /> 来关闭一个标签。

属性传递

如果我们正在构建一个博客,我们可能需要一个表示博客文章的组件。我们希望所有的博客文章分享相同的视觉布局,但有不同的内容。要实现这样的效果自然必须向组件中传递数据,例如每篇文章标题和内容,这就会使用到 props
Props 是一种特别的属性,你可以在组件上声明注册。要传递给博客文章组件一个标题,我们必须在组件的 props 列表上声明它。这里要用到 defineProps 宏:

<!-- BlogPost.vue -->
<script setup>
defineProps(['title'])
</script>

<template>
  <h4>{{ title }}</h4>
</template>

defineProps 是一个仅 <script setup> 中可用的编译宏命令,并不需要显式地导入。声明的 props 会自动暴露给模板。defineProps 会返回一个对象,其中包含了可以传递给组件的所有 props

const props = defineProps(['title'])
console.log(props.title)

如果你没有使用 <script setup>props 必须以 props 选项的方式声明,props 对象会作为 setup() 函数的第一个参数被传入:

export default {
  props: ['title'],
  setup(props) {
    console.log(props.title)
  }
}

监听事件

让我们继续关注我们的 <BlogPost> 组件。我们会发现有时候它需要与父组件进行交互。例如,要在此处将博客文章的文字能够放大,而页面的其余部分仍使用默认字号。
在父组件中,我们可以添加一个 postFontSize ref 来实现这个效果:

<script setup>
const posts = ref([
  /* ... */
])

const postFontSize = ref(1)
</script>

// 在模板中用它来控制所有博客文章的字体大小:
<template>
  <div :style="{ fontSize: postFontSize + 'em' }">
    <BlogPost
      v-for="post in posts"
      :key="post.id"
      :title="post.title"
      @enlarge-text="postFontSize += 0.1"
     />
  </div>
</template>

子组件可以通过调用内置的 $emit 方法,通过传入事件名称来抛出一个事件:

<!-- BlogPost.vue, 省略了 <script> -->
<template>
  <div class="blog-post">
    <h4>{{ title }}</h4>
    <button @click="$emit('enlarge-text')">Enlarge text</button>
  </div>
</template>

因为有了 @enlarge-text="postFontSize += 0.1" 的监听,父组件会接收这一事件,从而更新 postFontSize 的值。

我们可以通过 defineEmits 宏来声明需要抛出的事件:
这声明了一个组件可能触发的所有事件,还可以对事件的参数进行验证。同时,这还可以让 Vue 避免将它们作为原生事件监听器隐式地应用于子组件的根元素。
defineProps 类似,defineEmits 仅可用于 <script setup> 之中,并且不需要导入,它返回一个等同于 $emit 方法的 emit 函数。它可以被用于在组件的 <script setup> 中抛出事件,因为此处无法直接访问 $emit

<script setup>
const emit = defineEmits(['enlarge-text'])

emit('enlarge-text')
</script>

如果你没有在使用 <script setup>,你可以通过 emits 选项定义组件会抛出的事件。你可以从 setup() 函数的第二个参数,即 setup 上下文对象上访问到 emit 函数:

export default {
  emits: ['enlarge-text'],
  setup(props, ctx) {
    ctx.emit('enlarge-text')
  }
}

插槽

一些情况下我们会希望能和 HTML 元素一样向组件中传递内容,可以通过 Vue 的自定义 <slot> 元素来实现。我们使用 <slot> 作为一个占位符,父组件传递进来的内容就会渲染在这里。

<template>
  <div class="alert-box">
    <strong>This is an Error for Demo Purposes</strong>
    <slot />
  </div>
</template>

<style scoped>
.alert-box {
  /* ... */
}
</style>

动态组件

有些场景会需要在两个组件间来回切换,比如 Tab 界面,可以通过 Vue 的 <component> 元素和特殊的 is 属性实现。

<!-- currentTab 改变时组件也改变 -->
<component :is="tabs[currentTab]"></component>

在上面的例子中,被传给 :is 的值可以是以下几种:

  • 被注册的组件名
  • 导入的组件对象
    也可以使用 is 来创建一般的 HTML 元素。
    当使用 <component :is="..."> 来在多个组件间作切换时,被切换掉的组件会被卸载。我们可以通过 <KeepAlive> 组件强制被切换掉的组件仍然保持“存活”的状态。

标签:Vue,进阶,title,vue3,props,组件,ref,emit
From: https://www.cnblogs.com/cxy-orange/p/17478329.html

相关文章

  • RDIFramework.NET敏捷开发框架 ━ 工作流程组件介绍
    RDIFramework.NET,基于全新.NETFramework与.NETCore的快速信息化系统敏捷开发、整合框架,给用户和开发者最佳的.Net框架部署方案。为企业快速构建垮平台、企业级的应用提供了强大支持。1、RDIFramework.NET敏捷开发框架介绍RDIFramework.NET敏捷开发框架,是我司重磅推出的基于全新.N......
  • 自定义组件触发element-ui el-form 校验
    项目使用element-ui中的el-form进行表单校验,表单中含有上传组件,当校验时机设置change时,实际值已经改变,但没有触发校验。看一下el-select的源码是怎么写的,在watch监听里当value改变时,有这么一段代码this.dispatch('ElFormItem','el.form.change',val);可以引入dispatch函......
  • 直播软件app开发,vue里tab菜单横向展示,可分页功能组件实现
    直播软件app开发,vue里tab菜单横向展示,可分页功能组件实现子组件: <template><div>  <el-buttonv-if="move!=0&&!dataLen"size='small'icon="el-icon-arrow-left"@click="navPrev"></el-button>   <ulref......
  • vue3之setup
    一、Vue3中script的三种写法Vue3新增了一个叫做组合式api的东西,英文名叫CompositionAPI。因此Vue3的script现在支持三种写法。1)最基本的Vue2写法setup()属性<scriptsetup>无论是代码行数,还是代码的精简度,<scriptsetup>的方式是最简单的形式。如果......
  • 组件中的state和setState
        ......
  • 6.12 vue3的学习
    1.创建vue3项目:在cmd中首先找到需要保存的路径,输入vuecreate+vue项目的取名,和之前创建vue2是一样的进行如下选择 2.vite创建vue3的方式在cmd中首先输入npminitvue@latest 3.安装依赖和运行依赖#安装依赖npminstall##运行依赖npmrundev#4.vue2创建app实......
  • react组件
       ......
  • vue3
    目录一Vue3的变化1.性能的提升2、源码的升级3.拥抱TypeScript4.新的特性1.CompositionAPI(组合API)2.新的内置组件3.其他改变5组合式API和配置项API5.1OptionsAPI存在的问题5.2CompositionAPI的优势6项目分析分析文件目录main.jsVue2项目的main.js我们再来看看Vue3项目中......
  • Vue3基本功能实现
    vue3介绍#Vue3的变化#1.性能的提升 打包大小减少41%初次渲染快55%,更新渲染快133%内存减少54%#2.源码的升级 使用Proxy代替defineProperty实现响应式重写虚拟DOM的实现和Tree-Shaking#3.拥抱TypeScript Vue3可以更好的支持TypeScript......
  • 文件minio进阶 分页查询
    文章目录前言一、minio使用二、代码1.mino版本是最新的,那么pom中也要最新的2.部分代码总结前言就是现在通过minio管理文件,然后不需要其他信息,所以我也就没有用传统方式,在mysql中做文件记录,直接用minio做了文件存储,以及文件查询;一、minio使用1docker安装最新版minio.开......