Vue命令式组件的编写与应用

目录

1.引言

2.传统的组件

3.命令式组件

4.命令式组件的应用场景


1.引言

大家好!今天我们来聊聊Vue.js中的一个有趣话题——命令式组件。你有没有觉得,有时候我们在Vue模板里写组件,就像是在玩搭积木,每个积木都有固定的形状和位置?虽然这样很直观,但有时候我们可能需要更多的自由度来发挥创意。

这就是命令式组件登场的时候了。它们就像是你的个人DJ,在你需要的时候播放你想要的音乐。不需要预先在模板中定义,你可以直接在JavaScript中调用它们就像是调用一个函数一样简单。这种方式不仅让组件的使用变得更加灵活,还能让你的代码看起来更加干净利落。

在这篇文章中,我会带你了解命令式组件的基本概念,并通过一些简单的示例来展示它们是如何工作的。我们将一起看看,如何用几行代码就能让组件听从你的指挥,以及这样做能为你的Vue项目带来哪些好处。

准备好了吗?让我们开始这段轻松愉快的学习旅程,探索Vue命令式组件的魅力吧!

2.传统的组件

(假设我们现在需要编写一个MessageBox组件)

在传统的组件定义中,我们通常需要这么几步:

  • 接收父组件的属性值
  • 接收自定义事件
  • 组件的结构布局,样式
  • 给组件绑定不要的事件

最后在使用组件的时候,我们还得在父组件中,在模板中渲染出来,如果有时候我们嘚控制子组件的显示与否,还得添加控制的字段,总之就是有一些情况下很麻烦。

下这样一个MessageBox组件

这是部分代码:

MessageBox.vue

<template>
  <div class="message-box" v-if="show">
    <div class="inner">
      <div :class="['header', type]">
        <h1>{{ title }}</h1>
      </div>
      <div class="content">
        <p>
          {{ content }}
        </p>
        <button @click="closeMessageBox" :class="['btn', type]">{{ btntext }}</button>
      </div>
    </div>
  </div>
</template>

<script setup>
const props = defineProps({
  title: {
    type: String,
    default: 'Title'
  },
  btntext: {
    type: String,
    default: '确定'
  },
  content: {
    type: String,
    default: 'Content'
  },
  show: {
    type: Boolean,
    default: false
  },
  type: {
    type: String,
    default: 'primary',
    validate: (val) => ['primary', 'success', 'warning', 'error'].includes(val)
  }
})

const emits = defineEmits(['handler-visible'])

const closeMessageBox = () => {
  emits('handler-visible', false)
}
</script>

<style lang="scss" scoped>
.message-box {
  width: 100vw;
  height: 100vh;
  position: fixed;
  top: 0;
  left: 0;
  background-color: rgba(0, 0, 0, .5);

  .inner {
    width: 300px;
    height: 200px;
    background-color: #fff;
    border-radius: 5px;
    position: absolute;
    top: 50%;
    left: 50%;
    overflow: hidden;
    transform: translate(-50%, -50%);

    .content {
      margin-top: 20px;

      .btn {
        //去除样式
        border: none;
        outline: none;
        padding: 6px 15px;
        border-radius: 5px;
        //靠右下角
        position: absolute;
        right: 10px;
        bottom: 10px;
      }
    }

    .header {
      height: 38px;
      line-height: 38px;
      padding: 0 10px;
    }

    .primary {
      background-color: skyblue;
      color: #fff;
    }

    .success {
      background-color: green;
      color: #fff;
    }

    .warning {
      background-color: yellow;
      color: #fff;
    }

    .error {
      background-color: red;
      color: #fff;
    }
  }
}
</style>

使用的时候得渲染出来

<template>
  <div>
    <MessageBox title="标题" type="primary" btntext="close" @handler-visible="setVisible" :show="isVisible">
      This is a messagebox
    </MessageBox>
    <button @click="setVisible">显示MessageBox</button>
  </div>
</template>

<script setup>
import { ref } from 'vue';
import MessageBox from '../components/MessageBox.vue';
const isVisible = ref(false);
const setVisible = () => {
  isVisible.value = true;
}
</script>

3.命令式组件

如果遇到很多这种组件,就会感觉很麻烦,又得定义属性,又得设置自定义事件的回调函数,子组件还得接收。

这时候命令式组件的优势就体现出来了,他能让我们像调用函数的api一样,很轻松的就能实现组件的渲染。

在父组件中的代码就可以精简成这样:

<template>
  <div>
    <button @click="setVisible">显示MessageBox</button>
  </div>
</template>

<script setup>
import MessageBox from '../components/MessageBox';
console.log(MessageBox);
const setVisible = () => {
  MessageBox.alert({
    title: '标题',
    type: 'primary',
    btntext: 'close',
    content: '这是主要的内容信息'
  }, () => {
    console.log('关闭了')
  })
}
</script>

我们的自定义事件也是没了,显示的控制开关也没了,那么子组件需要做出一些修改,接收一个函数回调,但不过是相当于接收props。

<template>
  <div class="message-box">
    <div class="inner">
      <div :class="['header', type]">
        <h1>{{ title }}</h1>
      </div>
      <div class="content">
        <p>
          {{ content }}
        </p>
        <button @click="close" :class="['btn', type]">{{ btntext }}</button>
      </div>
    </div>
  </div>
</template>

<script setup>
const props = defineProps({
  title: {
    type: String,
    default: 'Title'
  },
  btntext: {
    type: String,
    default: '确定'
  },
  content: {
    type: String,
    default: 'Content'
  },
  type: {
    type: String,
    default: 'primary',
    validate: (val) => ['primary', 'success', 'warning', 'error'].includes(val)
  },
  close: Function
})

// const emits = defineEmits(['handler-visible'])

// const closeMessageBox = () => {
//   emits('handler-visible', false)
// }
</script>

这时候我们需要新添加一个js文件,可以定义在同文件夹目录下,index.js,在组件中引入:import MessageBox from '../components/MessageBox';默认引入的是js文件喔。

index.js文件中,我们要知道,如果我们不在页面模板中使用组件,要将其渲染在页面上,那么肯定得创建一个html页面模板(也可以叫应用实例),将其添加到页面当中去。

在本例中的MessageBox是打开时会渲染到页面,关闭后,又会从页面中删除。

此时我们必须要用到的就是 Vue 中的:createApp这个API了,我们要创建一个应用实例,将其挂载到某个地方,使其成为Vue的应用实例,这样他才能享用关于Vue的一切,包括props等属性。

import MessageBox from './index.vue'
import { createApp } from 'vue'
MessageBox.alert = (props, callback) => {
  const container = document.createElement('div')

  const messageBox = createApp(MessageBox, { ...props, close })
  open()
  function open() {
    messageBox.mount(container)
    document.body.appendChild(container)
  }

  function close() {
    messageBox.unmount(container)
    document.body.removeChild(container)
    if (typeof callback === 'function') {
      callback()
    }
  }
}

export default MessageBox

在调用时创建应用实例挂载到body上,close函数调用后,卸载掉组件,从body中移除

现在就可以像这样子使用了

<template>
  <div>
    <button @click="setVisible">显示MessageBox</button>
  </div>
</template>

<script setup>
import MessageBox from '../components/MessageBox';
console.log(MessageBox);
const setVisible = () => {
  MessageBox.alert({
    title: '标题',
    type: 'primary',
    btntext: 'close',
    content: '这是主要的内容信息'
  }, () => {
    console.log('关闭了')
  })
}
</script>

在回调函数中,我们还可以进行一些其他的操作,无论是数据的获取,修改等等。

如果关闭了此dom就会从页面中移除并调用回调函数。

我们也可以多定义几个回调函数,具体看需求

4.命令式组件的应用场景

命令式组件在Vue中的使用场景主要体现在需要动态、程序化地控制组件实例的时候。以下是一些典型的使用场景:

  • 模态对话框(Modals): 命令式组件非常适合创建模态对话框,如确认框、警告框等。你可以动态地调用一个函数来显示模态框,并传入所需的参数和回调。

  • 弹出窗口(Popups): 无论是提示信息、下拉菜单还是其他类型的弹出窗口,命令式组件都允许你通过编程的方式控制它们的显示和隐藏。

  • 懒加载组件(Lazy-loaded components): 当组件需要根据某些条件或用户交互才加载时,命令式组件可以确保组件实例仅在需要时才被创建和挂载。

  • 全局通知(Global notifications): 全局通知系统,如Toast或Snackbar,通常需要在应用的任何地方通过一个函数调用来触发显示。

  • 导航守卫中的确认逻辑: 在Vue Router的导航守卫中,你可能需要在用户尝试导航离开一个页面之前确认他们未保存的更改。命令式组件可以用来创建一个确认对话框。

  • 异步操作的反馈: 当执行异步操作(如发送API请求)时,你可能需要显示一个加载指示器或反馈消息。命令式组件可以在异步操作的不同阶段被创建和销毁。

  • 条件渲染组件: 如果你的组件需要根据运行时的条件来决定是否渲染,命令式组件可以让你在条件满足时动态创建组件实例。

  • 动态组件库(Dynamic component libraries): 当你在开发一个组件库时,命令式组件可以让你的组件更容易地被集成到其他项目中,因为它们不需要在模板中预定义。

  • 测试和调试: 在自动化测试或调试时,命令式组件允许你更容易地控制组件的生命周期,从而进行更精确的测试和问题重现。

  • 组件编排(Component orchestration): 当你需要在父组件中精确控制多个子组件的交互和生命周期时,命令式组件提供了一种直接的方式来编程化地管理这些交互。

命令式组件的核心优势在于它们提供了更大的控制灵活性,允许开发者根据应用的具体需求和交互逻辑来动态地创建和销毁组件实例。这种方式特别适用于那些不适合在模板中静态声明的组件使用场景。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/462099.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

第二百零六回

文章目录 1. 概念介绍2. 思路与方法2.1 实现思路2.2 实现方法 3. 示例代码4. 内容总结 我们在上一章回中介绍了"给geolocator插件提交问题的结果"相关的内容&#xff0c;本章回中将介绍自定义标题栏.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我…

set与zset数据类型

set类型基础 redis集合(set)类型和list列表类型类似&#xff0c;都可以用来存储多个字符串元素的 集合。但是和list不同的是set集合当中不允许重复的元素。而且set集合当中元素是没有顺序的&#xff0c;不存在元素下标。 redis的set类型是使用哈希表构造的&#xff0c;因此复…

Java面向对象案例之描述专业和学生(4)

类的方法图 学生类&#xff1a; 属性&#xff1a;学号&#xff0c;姓名&#xff0c;年龄&#xff0c;所学习的专业方法&#xff1a;学习的方法&#xff0c;描述学习状态。描述内容包括姓名、学号、年龄、所学习的专业信息 专业类&#xff1a; 属性&#xff1a;专业编号&#xf…

阅读 - 二维码扫码登录原理

在日常生活中&#xff0c;二维码出现在很多场景&#xff0c;比如超市支付、系统登录、应用下载等等。了解二维码的原理&#xff0c;可以为技术人员在技术选型时提供新的思路。对于非技术人员呢&#xff0c;除了解惑&#xff0c;还可以引导他更好地辨别生活中遇到的各种二维码&a…

线性回归 quickstart

构建一元一次方程 100个&#xff08;X, y &#xff09;&#xff0c;大概是’y3x4’ import numpy as npnp.random.seed(42) # to make this code example reproducible m 100 # number of instances X 2 * np.random.rand(m, 1) # column vector y 4 3 * X np.random…

深度揭秘HW中的灰色技术(盗号,个人实时定位,远程监听)

xss漏洞&#xff1a;是数量最多的漏洞 cross-site scripting 跨站脚本攻击 1.反射型xss&#xff1a;代码存在于网址中&#xff0c;将存在恶意代码的链接发给用户&#xff0c;点击后才能攻击成功实施。 2.存储型xss&#xff1a;指Web应用程序会将用户输入的数据信息保持在服务…

2024批量下载微博内容导出excel,数据包含微博链接,内容,点赞数,转发数,评论数,话题等

以歌手李健这个号为例&#xff0c;共抓取727条微博&#xff0c;导出的excel微博数据包含微博链接,微博正文,原始图片链接,被转发微博原始图片链接,是否为原创微博,微博视频链接,发布位置,发布时间,发布工具,点赞数,转发数,评论数,话题等。 第一条微博发布于2010年5月31 。 再根…

电机参数辨识算法(2)——基于高频注入的磁链辨识策略

电机参数辨识算法&#xff08;1&#xff09;——基于高频注入的电感辨识策略-CSDN博客https://blog.csdn.net/m0_46903653/article/details/136722750?spm1001.2014.3001.5501上一期已经讲过了电感辨识方法。 今天这是参数辨识的第二期&#xff0c;今天来简单看看磁链的辨识。…

(六)Android布局类型(表格布局TableLayout)

表格布局&#xff08;TableLayout&#xff09;&#xff0c;呈现行列方式&#xff0c;无法设置列&#xff0c;可以设置行&#xff0c;行数由TableRow对象个数决定。下图中有两个TableRow元素&#xff0c;所以&#xff0c;说明表格布局中有两行。 将内容填充到行中 第一行中&…

【ollama】(7):使用Nvidia Jetson Nano设备,成功运行ollama,运行qwen:0.5b-chat,速度还可以,可以做创新项目了

1&#xff0c;视频地址 https://www.bilibili.com/video/BV1Pj421o7W5/ 【ollama】&#xff08;7&#xff09;&#xff1a;使用Nvidia Jetson Nano设备&#xff0c;成功运行ollama&#xff0c;运行qwen:0.5b-chat&#xff0c;速度还可以&#xff0c;可以做创新项目了 2&#x…

【NC223888】红色和紫色

题目 红色和紫色 博弈论&#xff0c;想得出来思路就简单&#xff0c;想不出来就难。一般使用猜测法。 思路 如果小红随意取一个格子涂色&#xff0c;那么小紫怎么涂色才是她的最优选择呢&#xff1f; 假设小紫只能选择小红涂色的格子的相邻格子或者是最近斜对角的一个格子涂色…

浅易理解:卷积神经网络(CNN)

浅易理解卷积神经网络流程 本文的目录&#xff1a; 1 什么卷积神经网络 2 输入层 3 卷积层 4 池化层 5 全连接层 传统的多层神经网络只有 输入层、隐藏层、输出层 卷积神经网络&#xff08;CNN)&#xff1a; 在多层神经网络的基础上&#xff0c;加入了更加有效的特征学习部分…

JavaScript 基础知识

一、初识 JavaScript 1、JS 初体验 JS 有3种书写位置&#xff0c;分别为行内、内部和外部。 示例&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"wid…

CASA模型在陆地生态系统碳循环研究中的应用探讨

植被&#xff0c;作为陆地生态系统的重要基石&#xff0c;对维护生态环境功能具有不可替代的作用。其中&#xff0c;植被净初级生产力&#xff08;NPP&#xff09;是衡量植被生态系统健康与功能的关键指标。它反映了单位面积上绿色植被通过光合作用生产的有机质总量在扣除自养呼…

软件测试面试都问了什么?中级软件测试岗面试(4面)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 一面&#xff08;…

瑞熙贝通实验室安全培训考试系统

一、系统概述 瑞熙贝通实验室安全培训考试系统是一种基于互联网和人工智能技术的在线考试平台&#xff0c;旨在旨在提供实验室安全教育和考核的全面解决方案。该系统可以帮助实现实验室安全培训考试的在线化、智能化和规范化&#xff0c;提高实验室安全意识和能力&#xff0c;…

Arduino平台软硬件原理及使用——色环电阻及贴片电阻的阻值识别

文章目录 一、四色环电阻及其阻值识别 二、五色环、六色环电阻及其阻值识别 三、三位数字及四位数字编码的贴片电阻及其阻值识别 四、E96编码的贴片电阻及其阻值识别 一、四色环电阻及其阻值识别 如上图为四色环电阻的实物图&#xff0c;图中左侧的三道环间距一致&#xff0c;第…

【List集合】List接口源码解读一(ArrayList)

目录 前言 1. List接口的基本信息 2. ArrayList 2.1.ArrayList 的基本信息 2.2. ArrayList 的构造方法 2.2.1 ArrayList 的构造方法一 2.2.2 ArrayList 的构造方法二 2.2.3 ArrayList 的构造方法三 2.3 ArrayList 的扩容方式 总结 前言 Java 语言由于其跨平台、社区良…

3.Redis命令

Redis命令 Redis 根据命令所操作对象的不同&#xff0c; 可以分为三大类&#xff1a; 对 Redis 进行基础性操作的命令&#xff0c;对 Key 的操作命令&#xff0c;对 Value 的操作命令。 1.1 Redis 首先通过 redis-cli 命令进入到 Redis 命令行客户端&#xff0c;然后再运行下…

Spring Web MVC入门(2)

学习Spring MVC Postman介绍 在软件工程中, 我们需要具有前后端分离的思想, 以降低耦合性. 但是在测试后端代码时,我们还得写前端代码测试,这是个令人头疼的问题. 那么我们如何测试自己的后端程序呢, 这就用到了一个工具: Postman. 界面介绍: 传参的介绍 1.普通传参, 也就…