VUE3 Hooks的面向对象实现方式

news2024/12/26 22:46:09

本文会以三种形式实现一个组件,该组件实现以下功能:

1.显示一个数字(可从prop给初始值)和一个添加按钮;

2.点击添加按钮数字增加;

3.当数字大于5时,数字颜色变红,并提交error事件。

 第一种,逻辑直接写在组件内部

<template>
  <div :class="{error:isError}">{{ count }}</div>
  <button @click="addCount">add</button>
</template>

<script setup lang="ts">
import {defineEmits, defineProps, ref, watch} from "vue";

// -----props-----
interface PropModel {
  initCount?: number
}

const prop = defineProps<PropModel>()

// -----emits----
interface EmitModel {
  /**
   * 上报异常
   * @param e
   * @param count 异常值
   */
  (e: 'error', count: number): void
}

const emit = defineEmits<EmitModel>()


// 数量
const count = ref(prop.initCount?? 0)
// 监听prop变化
watch(() => prop.initCount, (value) => {
  count.value = value ?? 0
})

// 异常阈值
const ERROR_COUNT = 5
// 是否异常 大于5就异常
const isError = ref(false)
// 监听是否异常
watch(count, (value) => {
  if (value > ERROR_COUNT) {
    isError.value=true
    emit('error',value)
  }
})

// 添加值
function addCount(){
  count.value++
}

</script>

<style scoped>
.error{
  color: red;
}
</style>

第二种,通过Hooks方式将业务抽离

同目录下创建 【NumPanelHooks.ts】文件

import {ref, watch} from "vue";

interface EmitModel {
    /**
     * 上报异常
     * @param e
     * @param count 异常值
     */
    (e: 'error', count: number): void
}

export default function (prop: { initCount?: number }, emit: EmitModel) {
    // 数量
    const count = ref(prop.initCount ?? 0)
    // 监听prop变化
    watch(() => prop.initCount, (value) => {
        count.value = value ?? 0
    })

    // 异常阈值
    const ERROR_COUNT = 5
    // 是否异常 大于5就异常
    const isError = ref(false)
    // 监听是否异常
    watch(count, (value) => {
        if (value > ERROR_COUNT) {
            isError.value = true
            emit('error', value)
        }
    })

    // 添加值
    function addCount() {
        count.value++
    }

    return {
        count,
        isError,
        addCount
    }
}

组件页面

<template>
  <div :class="{error:isError}">{{ count }}</div>
  <button @click="addCount">add</button>
</template>

<script setup lang="ts">
import {defineEmits, defineProps} from "vue";
import useNumPanelHoos from './NumPanelHooks'

// -----props-----
interface PropModel {
  initCount?: number
}

const prop = defineProps<PropModel>()

// -----emits----
interface EmitModel {
  /**
   * 上报异常
   * @param e
   * @param count 异常值
   */
  (e: 'error', count: number): void
}

const emit = defineEmits<EmitModel>()

const {
  count,
  isError,
  addCount
} = useNumPanelHoos(prop, emit)
</script>

<style scoped>
.error {
  color: red;
}
</style>

此种方式,已经实现业务的抽离,组件内部也很清洁。

第三种,面向对象Hooks

创建【NumPanelObjHooks.ts】文件

import {ref, watch} from "vue";

interface EmitModel {
    /**
     * 上报异常
     * @param e
     * @param count 异常值
     */
    (e: 'error', count: number): void
}

export default class NumPanelObjHooks {
    prop = undefined
    emit = undefined

    // 数量
    count = ref(0)

    constructor(prop: { initCount?: number }, emit: EmitModel) {
        this.prop = prop
        this.emit = emit
        this.count.value = this.prop?.initCount ?? 0
    }

    addWatch = () => {
        // 监听prop变化
        watch(() => this.prop.initCount, (value) => {
            this.count.value = value ?? 0
        })

        // 监听是否异常
        watch(this.count, (value) => {
            if (value > this.ERROR_COUNT) {
                this.isError.value = true
                this.emit('error', value)
            }
        })

    }

    // 异常阈值
    ERROR_COUNT = 5
    // 是否异常 大于5就异常
    isError = ref(false)

    // 添加值
    addCount = () => {
        this.count.value++
    }
}

组件页面

<template>
  <div :class="{error:isError}">{{ count }}</div>
  <button @click="addCount">add</button>
</template>

<script setup lang="ts">
import {defineEmits, defineProps} from "vue";
import NumPanelObjHooks from "./NumPanelObjHooks";

// -----props-----
interface PropModel {
  initCount?: number
}

const prop = defineProps<PropModel>()

// -----emits----
interface EmitModel {
  /**
   * 上报异常
   * @param e
   * @param count 异常值
   */
  (e: 'error', count: number): void
}

const emit = defineEmits<EmitModel>()

const {
  count,
  isError,
  addCount,
  addWatch
} = new NumPanelObjHooks(prop, emit)

addWatch()
</script>

<style scoped>
.error {
  color: red;
}
</style>

第二种就能实现业务的抽离,为什么采取要使用第三种方式?

我们公司的公共组件与结构是在一个分支上,各项目都是从这个分支拉出的各项目的分支。各项目由于业务不同可能会有改动组件,这样再维护公共组件,就会造成冲突。把组件单独提出,作为各项目的私有组件,那么修改公共组件问题,私有组件又无法更新。于是想通过继承的方式来创建私有组件,这样公共的组件修改问题时,由于继承关系私有组件也会同时更新。

举个例子:现在把增加的方法变为自增为2

创建【MyNumPanelHooks.ts】

import NumPanelObjHooks from "../NumPanel/NumPanelObjHooks";

export default class MyNumPanelHooks extends NumPanelObjHooks{
    addCount=()=>{
        this.count.value+=2
    }
}

创建【MyNumPanel.vue】

<template>
  <div :class="{error:isError}">{{ count }}</div>
  <button @click="addCount">add</button>
</template>

<script setup lang="ts">
import {defineEmits, defineProps} from "vue";
import MyNumPanelHooks from "./MyNumPanelHooks";

// -----props-----
interface PropModel {
  initCount?: number
}

const prop = defineProps<PropModel>()

// -----emits----
interface EmitModel {
  /**
   * 上报异常
   * @param e
   * @param count 异常值
   */
  (e: 'error', count: number): void
}

const emit = defineEmits<EmitModel>()

const {
  count,
  isError,
  addCount,
  addWatch
} = new MyNumPanelHooks(prop, emit)

addWatch()
</script>

<style scoped>
.error {
  color: red;
}
</style>

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Redis持久化——RDB快照

介绍 我们知道Redis是运行在内存中的数据库&#xff0c;那么当我们关闭Redis服务器后&#xff0c;内存中的数据会不会丢失&#xff1f; 当然是不会&#xff01;因为Redis有持久化机制&#xff0c;所谓持久化&#xff0c;就是将内存中的数据保存到磁盘文件上&#xff0c;以此来…

Zookeeper进阶篇 - Paxos协议算法、ZBA协议算法原理、Leader选举原理

Zookeeper底层原理篇&#xff0c;​让学习绚丽多彩起来&#xff01;&#xff01;&#xff01;

Eigen 的简单使用 与 轨迹拟合代码的理解

工作中遇到一个问题&#xff0c;发到hmi的车辆引导线为斜的&#xff0c;有一说一&#xff0c;仔细看下这段代码&#xff0c;发现用到了Eigen库用来多项式曲线拟合&#xff0c;线性回归&#xff0c;矩阵向量计算等。 #include <iostream> #include <vector> #inclu…

001-Nacos 服务注册

目录 Nacos介绍注册中心架构面临问题源码分析实例注册-接口实例注册-入口实例注册-创建一个(Nacos)Service实例注册-注册(Nacos)Service Nacos 介绍 Dynamic Naming and Configuration Service 动态的命名和配置服务 反正可以实现注册中心的功能 注册中心架构 服务提供者 …

做好需求分析的4大关键认知

探索如何正确的需求分析&#xff1f;本文详细介绍了4大关键点&#xff0c;帮助您明确用户与产品需求、深入挖掘用户动机&#xff0c;并为产品经理提供筛选需求的实用建议。 一、什么是需求分析以及重要性 需求分析指的是在建立一个新的或改变一个现存的产品时&#xff0c;确定新…

人工智能在网络安全中的应用: 分析人工智能、机器学习和深度学习等技术在预测、检测和应对网络攻击中的作用

第一章&#xff1a;引言 随着信息技术的迅猛发展&#xff0c;网络安全已成为当今社会不容忽视的重要议题。网络攻击手法日益复杂&#xff0c;传统的防御方法已经不再足够。在这一背景下&#xff0c;人工智能&#xff08;AI&#xff09;技术正逐渐崭露头角&#xff0c;为网络安…

vue3学习笔记(一)

一、API风格 Vue 的组件可以按两种不同的风格书写&#xff1a;选项式 API 和组合式 API。 二、组合式API 1.&#xff08;组合式 API 的核心思想是直接在函数作用域内定义响应式状态变量&#xff0c;并将从多个函数中得到的状态组合起来处理复杂问题。这种形式更加自由&#x…

SummaryWriter

SummaryWriter tb_writer SummaryWriter("swin_transformer_loss_acc") 第一个参数 log_dir : 用以保存summary的位置 add_scalar()函数的目的是添加一个标量数据&#xff08;scalar data&#xff09;到summary中 重要的常用的其实就是前三个参数&#xff1a; &…

【C++】模拟实现unordered_map和unordered_set

哈希表封装 前言正式开始模型修改Insert修改迭代器运算符重载 Findoperator[ ] 前言 本篇以前一篇模拟实现哈希表为基础进行改造&#xff0c;如果没看过前一篇的先看一下&#xff1a;【C】模拟实现哈希&#xff08;闭散列和开散列两种方式&#xff09;。 由于本篇代码基于上篇…

编译工具:CMake(五) | 静态库与动态库构建

编译工具&#xff1a;CMake&#xff08;五&#xff09; | 静态库与动态库构建 建立共享库编译共享库指令 ADD_LIBRARY 添加静态库动态库版本号安装共享库和头文件 建立共享库 在Compilation_tool/cmake路径下建立test3目录 在 t3 目录下建立 CMakeLists.txt&#xff0c;内容如…

88-基于stm32单片机空调温湿度控制系统Proteus仿真+源码

资料编号&#xff1a;088 一&#xff1a;功能介绍&#xff1a; 1、采用stm32单片机OLED显示屏DHT11温湿度电机按键&#xff0c;制作一个温湿度采集&#xff0c;OLED显示相关数据&#xff0c;自动制冷制热空调&#xff1b; 2、通过按键设置温度值和工作模式&#xff08;制冷/制热…

MLC LLM:将LLMs部署到消费类硬件的优势、挑战以及解决方案

一、前言 随着生成人工智能&#xff08;AI&#xff09;和大语言模型&#xff08;LLM&#xff09;的快速发展&#xff0c;基于LLM的应用越来越普及。然而&#xff0c;大规模的模型需要密集计算和庞大的资源&#xff0c;使得许多公司无法承担从头开始训练模型的成本。目前&#…

计算机控制技术|17/8|16:27

目录 1. 什么是“纹波”现象&#xff1f;原因为何&#xff1f; 2. 如何解决最小拍控制器的“纹波”问题&#xff1f; 3. 解释“阻尼因子法”&#xff1f; 4. 大林算法控制器设计时&#xff0c;给定闭环系统传递函数模型离散化时为何要加入零阶保持器&#xff1f; 5. 何为“…

86-基于stm32单片机智能家居温湿度监测自动加湿器散热器Proteus仿真+源码

资料编号&#xff1a;086 一&#xff1a;功能介绍&#xff1a; 1、采用stm32单片机OLED显示屏DHT11温湿度电机按键蜂鸣器&#xff0c;制作一个温湿度采集、OLED显示相关数据&#xff0c; 2、通过按键设置温度上限、湿度下限、 3、当采集温度大于设置温度&#xff0c;开启散热电…

【广州华锐视点】VR线上教学资源平台提供定制化虚拟现实学习内容

虚拟现实&#xff08;VR&#xff09;技术的出现为我们提供了一种全新的在线教学方式。由广州华锐视点开发的VR线上教学资源平台&#xff0c;作为一个综合性的学习工具&#xff0c;正在教育领域迅速发展&#xff0c;并被越来越多的教育机构和学生所接受。那么&#xff0c;VR线上…

XDR解决方案成为了新的安全趋势

和当今指数倍增长的安全数据相比&#xff0c;安全人才的短缺带来了潜在的风险。几乎所有的公司&#xff0c;无论规模大小&#xff0c;在安全资源能力上都有限&#xff0c;需要过滤各种告警才能将分析量保持在可接受范围。但这样一来&#xff0c;潜在的威胁线索就可能被埋没&…

在一小时内构建您的深度学习应用程序

一、说明 我已经做了将近十年的数据分析。有时&#xff0c;我使用机器学习技术从数据中获取见解&#xff0c;并且我习惯于使用经典 ML。 虽然我已经通过了神经网络和深度学习的一些MOOC&#xff0c;但我从未在我的工作中使用过它们&#xff0c;这个领域对我来说似乎很有挑战性。…

爬虫的代理IP池写哪里了?

亲爱的程序员小伙伴们&#xff0c;想要提高爬虫效率和稳定性&#xff0c;组建一个强大的代理IP池是非常重要的一步&#xff01;今天我就来和你分享一下&#xff0c;代理IP池到底应该写在哪里&#xff0c;以及如何打造一个令人瞩目的代理IP池&#xff01;准备好了吗&#xff1f;…

【最新可用】VMware中ubuntu与主机window之间使用共享文件夹传输大文件

一、VMware设置共享文件夹 &#xff08;1&#xff09;虚拟机关机情况下&#xff0c;创建一个共享文件夹 &#xff08;2&#xff09;ubuntu中挂载共享文件夹 1、如果之前已经挂载 hgfs&#xff0c;先取消挂载 sudo umount /mnt/hgfs2、重新使用以下命令挂载 sudo /usr/bin/vmh…

11、BigKey

BigKey 阿里广告平台&#xff0c;海量数据里查询某一固定前缀的key 小红书&#xff0c;你如何生产上限制keys */flushdb/flushall等危险命令以防止误删误用&#xff1f; 美团&#xff0c;MEMORY USAGE 命令你用过吗&#xff1f; BigKey问题&#xff0c;多大算big&#xff1f;你…