VUE3 Hooks的面向对象实现方式

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

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>

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

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

相关文章

Redis详解

Redis 简介 Redis&#xff08;Remote Dictionary Server&#xff09;是一个开源的高性能键值对存储数据库&#xff0c;最初由 Salvatore Sanfilippo 开发&#xff0c;它在内存中存储数据&#xff0c;并提供了持久化功能&#xff0c;可以将数据保存到磁盘中&#xff0c;是一种N…

如何利用 ChatGPT 进行自动数据清理和预处理

推荐&#xff1a;使用 NSDT场景编辑器助你快速搭建可二次编辑的3D应用场景 ChatGPT 已经成为一把可用于多种应用的瑞士军刀&#xff0c;并且有大量的空间将 ChatGPT 集成到数据科学工作流程中。 如果您曾经在真实数据集上训练过机器学习模型&#xff0c;您就会知道数据清理和预…

LabVIEW开发设计热稳定器

LabVIEW开发设计热稳定器 使用与PC控制单元接口的电子设备进行数据采集和控制已广泛用于不同的工业应用。精确的温度控制是一个巨大的挑战&#xff0c;这就是为什么一些工业应用需要使用适当的材料和设备比更好的温度精度。 ​ 为了追踪[-50至250C]之间的温度变化&#xff0c…

Kafka第一课概述与安装

生产经验 面试重点 Broker面试重点 代码,开发重点 67 章了解 如何记录行为数据 1. Kafka概述 1.产生原因 前端 传到日志 日志传到Flume 传到HADOOP 但是如果数据特比大&#xff0c;HADOOP就承受不住了 2.Kafka解决问题 控流消峰 Flume传给Kafka 存到Kafka Hadoop 从Kafka…

《cpolar内网穿透》外网SSH远程连接linux(CentOS)服务器

本次教程我们来实现如何在外公网环境下&#xff0c;SSH远程连接家里/公司的Linux CentOS服务器&#xff0c;无需公网IP&#xff0c;也不需要设置路由器。 视频教程 [video(video-jrpesBrv-1680147672481)(type-csdn)(url-CSDN直播https://live-file.csdnimg.cn/release/live/…

UI自动化环境的搭建(python+pycharm+selenium+chrome)

最近在做一些UI自动化的项目&#xff0c;为此从环境搭建来从0到1&#xff0c;希望能够帮助到你&#xff0c;同时也是自我的梳理。将按照如下进行开展&#xff1a; 1、python的下载、安装&#xff0c;python环境变量的配置。 2、pycharm开发工具的下载安装。 3、selenium的安装。…

[低端局][cx32L003] 移植U8G2

文章目录 一、简介&#xff08;1&#xff09;U8g2&#xff08;2&#xff09;U8x8 二、配置要求三、移植步骤&#xff08;1&#xff09;文件准备和添加&#xff08;2&#xff09;实现回调接口(I2C的读写函数)①软件I2C②硬件I2C &#xff08;3&#xff09;功能裁剪① u8g2_d_set…

也许你正处于《孤注一掷》中的“团队”,要留心了

看完这部电影&#xff0c;心情久久不能平静&#xff0c;想了很多&#xff0c;倒不是担心自己哪天也成为“消失的yaozi”&#xff0c;而是在想&#xff0c;我们每天所赖以生存的工作&#xff0c;跟电影里他们的工作比&#xff0c;差别在哪里呢&#xff1f; 目录 1. 产品的本质…

2023 年值得关注的 8 个最佳免费开发者工具

开发者工具对开发人员的重要性不言而喻&#xff0c;保持最新工具的更新可以显著提高你的工作效率并简化您的工作流程。随着技术的快速发展&#xff0c;新的开发工具不断被引入市场。今天&#xff0c;我们将分享 2023 年你值得关注的最新开发者工具。 1.Plaky Plaky 是一种基于…

SASS 学习笔记

SASS 学习笔记 总共会写两个练手项目&#xff0c;成品在 https://goldenaarcher.com/scss-study 可以看到&#xff0c;代码在 https://github.com/GoldenaArcher/scss-study。 什么是 SASS SASS 是 CSS 预处理&#xff0c;它提供了变量&#xff08;虽然现在 CSS 也提供了&am…

【rust/egui】(一)从编译运行template开始

说在前面 rust新手&#xff0c;egui没啥找到啥教程&#xff0c;这里自己记录下学习过程环境&#xff1a;windows11 22H2rust版本&#xff1a;rustc 1.71.1egui版本&#xff1a;0.22.0eframe版本&#xff1a;0.22.0rust windows安装参考&#xff1a;这里本文默认读者已安装相关环…

大语言模型之三 InstructGPT训练过程

大语言模型 GPT历史文章中简介的大语言模型的的发展史&#xff0c;并且简要介绍了大语言模型的训练过程&#xff0c;本篇文章详细阐述训练的细节和相关的算法。 2020年后全球互联网大厂、AI创业公司研发了不少AI超大模型&#xff08;百亿甚至千亿参数&#xff09;&#xff0c;…

使用dockerfile手动构建JDK11镜像运行容器并校验

Docker官方维护镜像的公共仓库网站 Docker Hub 国内无法访问了&#xff0c;大部分镜像无法下载&#xff0c;准备逐步构建自己的镜像库。【转载aliyun官方-容器镜像服务 ACR】Docker常见问题 阿里云容器镜像服务ACR&#xff08;Alibaba Cloud Container Registry&#xff09;是面…

ADIS16470和ADIS16500从到手到读出完整数据,附例程

由于保密原因&#xff0c;不能上传我这边的代码&#xff0c;我所用的开发环境是IAR&#xff0c; 下边转载别的博主的文章&#xff0c;他用的是MDK 下文的博主给了你一个很好的思路&#xff0c;特此提出表扬 最下方是我做的一些手册批注&#xff0c;方便大家了解这个东西 原文链…

MySQL 函数

mysql 函数语法 create function 函数名&#xff08;参数名 参数类型&#xff0c;。。。&#xff09; returns type —返回值类型 ----returns 有个 s [characteristics…] begin 函数体 ### 函数体中肯定有 return 语句 end 参数列表 指定参数为 IN | out | INOUT 只对存储过程…

【NAS群晖drive异地访问】使用cpolar远程访问内网Synology Drive「内网穿透」

文章目录 前言1.群晖Synology Drive套件的安装1.1 安装Synology Drive套件1.2 设置Synology Drive套件1.3 局域网内电脑测试和使用 2.使用cpolar远程访问内网Synology Drive2.1 Cpolar云端设置2.2 Cpolar本地设置2.3 测试和使用 3. 结语 前言 群晖作为专业的数据存储中心&…

空气IT

现代社会中&#xff0c;空气质量成为了人们关注的焦点之一。随着工业化的发展&#xff0c;汽车尾气、工厂排放和燃煤等行为导致城市空气污染日益严重&#xff0c;给人们的健康和生活质量带来了极大的威胁。 首先&#xff0c;空气污染对人体健康造成了严重的危害。空气中的颗粒…

分布式 - 消息队列Kafka:Kafka生产者架构和配置参数

文章目录 1. kafka 生产者发送消息整体架构2. Kafka 生产者重要参数配置01. acks02. 消息传递时间03. linger.ms04. buffer.memory05. batch.size06. max.in.flight.requests.per.connection07. compression.type08. max.request.size09. receive.buffer.bytes和 send.buffer.b…

解读2023年上半年财报:净利润达11.08亿元,东鹏做对了什么?

“累了、困了&#xff0c;喝东鹏特饮”&#xff0c;这句朗朗上口的广告词是很多人对于功能性饮料的第一印象。而这句经典广告词背后的公司便是如今发展如日中天的东鹏饮料。近些年&#xff0c;东鹏饮料凭借快准狠的营销、推广打法&#xff0c;迅速在功能性饮料市场攻城略地&…

Linux:shell脚本:基础使用(4)《正则表达式-grep工具》

正则表达式定义&#xff1a; 使用单个字符串来描述&#xff0c;匹配一系列符合某个句法规则的字符串 正则表达式的组成&#xff1a; 普通字符串: 大小写字母&#xff0c;数字&#xff0c;标点符号及一些其他符号 元字符&#xff1a;在正则表达式中具有特殊意义的专用字符 正则表…