ele-h5项目使用vue3+vite开发:第二节、search 搜索框组件开发

如何设计一个组件

 需求分析

 布局

  • content
    • left-icon
    • body
    • input-control
    • right-icon
  • action

功能

使用 defineEmits 定义组件的事件

在组件的script setup 里如何定义事件

  • 使用defineEmits()定义
  • 先声明事件接口
  • <script setup lang="ts">
    interface IProps {
      showAction?: boolean
      background?: string
      placeholder?: string
      shape?: string
      modelValue?: string | number
    }
    
    const props = defineProps<IProps>()
    
    // 声明事件接口
    interface IEmits {
      (e: 'search', v?: string | number): void
      (e: 'cancel'): void
      (e: 'clear'): void
      (e: 'update:modelValue', v?: string | number): void
    }
    
    // 定义事件变量
    const emits = defineEmits<IEmits>()
    
    const onKeyPress = (e: KeyboardEvent) => {
      const ENTER_CODE = 13
      if (ENTER_CODE === e.keyCode) {
        e.preventDefault()
    //使用定义事件里声明事件接口中的某个事件
        emits('search', props.modelValue)
      }
    }
    
    const onClear = () => {
    //使用定义事件里声明事件接口中的某个事件
      emits('clear')
    //使用定义事件里声明事件接口中的某个事件
      emits('update:modelValue', '')
    }
    </script>
    
    <template>
      <div class="op-search" :class="{ 'op-search--show-action': showAction }" :style="{ background }">
        <div class="op-search__content" :class="shape ? `op-search__content--${shape}` : ''">
          <div class="op-cell op-search__field">
            <div class="op-field__left-icon">
              <VanIcon name="search" />
            </div>
            <div class="op-cell__value">
              <div class="op-field__body">
                <input
                  type="search"
                  class="op-field__control"
                  :value="modelValue"
                  :placeholder="placeholder"
                  @keypress="onKeyPress"
    
                //使用定义事件里声明事件接口中的某个事件, 以及传递input输入框里的值
                  @input="(e) => emits('update:modelValue', (e.target as HTMLInputElement).value)"
                />
                <div v-if="$slots['right-icon']" class="op-field__right-icon">
                  <slot name="right-icon"></slot>
                </div>
                <VanIcon
                  v-else-if="modelValue"
                  name="clear"
                  class="op-field__clear-icon"
    //使用定义的函数事件,触发里面的定义事件里声明事件接口中的某个事件
                  @click="onClear"
                />
              </div>
            </div>
          </div>
        </div>
        <div v-if="showAction" class="op-search__action">
          <slot name="action">
    //定义事件里声明事件接口中的某个事件
            <div @click="emits('cancel')">取消</div>
          </slot>
        </div>
      </div>
    </template>

如何定义组件的 v-model

在组件的script setup 里如何定义 v-model 参数

  • 声明接口属性,定义v-model双向绑定的变量参数。
  • 使用定义的v-model双向绑定的变量参数
  • <script setup lang="ts">
    
    //声明变量参数的接口属性
    interface IProps {
      showAction?: boolean
      background?: string
      placeholder?: string
      shape?: string
      modelValue?: string | number
    }
    
    // 定义v-model双向绑定使用的变量参数
    const props = defineProps<IProps>()
    
    interface IEmits {
      (e: 'search', v?: string | number): void
      (e: 'cancel'): void
      (e: 'clear'): void
      (e: 'update:modelValue', v?: string | number): void
    }
    
    const emits = defineEmits<IEmits>()
    
    const onKeyPress = (e: KeyboardEvent) => {
      const ENTER_CODE = 13
      if (ENTER_CODE === e.keyCode) {
        e.preventDefault()
    
    //在script setup中使用定义v-model双向绑定使用的变量参数
        emits('search', props.modelValue)
      }
    }
    
    const onClear = () => {
      emits('clear')
      emits('update:modelValue', '')
    }
    </script>
    
    <template>
    //在template中使用定义v-model双向绑定使用的变量参数 showAction background shape
      <div class="op-search" :class="{ 'op-search--show-action': showAction }" :style="{ background }">
        <div class="op-search__content" :class="shape ? `op-search__content--${shape}` : ''">
          <div class="op-cell op-search__field">
            <div class="op-field__left-icon">
              <VanIcon name="search" />
            </div>
            <div class="op-cell__value">
              <div class="op-field__body">
    //在template中使用定义v-model双向绑定使用的变量参数 modelValue placeholder
                <input
                  type="search"
                  class="op-field__control"
                  :value="modelValue"
                  :placeholder="placeholder"
                  @keypress="onKeyPress"
                  @input="(e) => emits('update:modelValue', (e.target as HTMLInputElement).value)"
                />
                <div v-if="$slots['right-icon']" class="op-field__right-icon">
                  <slot name="right-icon"></slot>
                </div>
    //在template中使用定义v-model双向绑定使用的变量参数 modelValue 
    
                <VanIcon
                  v-else-if="modelValue"
                  name="clear"
                  class="op-field__clear-icon"
                  @click="onClear"
                />
              </div>
            </div>
          </div>
        </div>
    //在template中使用定义v-model双向绑定使用的变量参数 showAction
    
        <div v-if="showAction" class="op-search__action">
          <slot name="action">
            <div @click="emits('cancel')">取消</div>
          </slot>
        </div>
      </div>
    </template>
    

是的

如何使用 CSS 变量

定义css变量,使用var(--van-padding-xs)格式来书写vue3的css变量,可以在script setup中进行自定义css变量值

  • 在组件中使用css变量
  • 
    <template>
      <div class="op-search" :class="{ 'op-search--show-action': showAction }" :style="{ background }">
        <div class="op-search__content" :class="shape ? `op-search__content--${shape}` : ''">
          <div class="op-cell op-search__field">
            <div class="op-field__left-icon">
              <VanIcon name="search" />
            </div>
            <div class="op-cell__value">
              <div class="op-field__body">
                <input
                  type="search"
                  class="op-field__control"
                  :value="modelValue"
                  :placeholder="placeholder"
                  @keypress="onKeyPress"
                  @input="(e) => emits('update:modelValue', (e.target as HTMLInputElement).value)"
                />
                <div v-if="$slots['right-icon']" class="op-field__right-icon">
                  <slot name="right-icon"></slot>
                </div>
                <VanIcon
                  v-else-if="modelValue"
                  name="clear"
                  class="op-field__clear-icon"
                  @click="onClear"
                />
              </div>
            </div>
          </div>
        </div>
        <div v-if="showAction" class="op-search__action">
          <slot name="action">
            <div @click="emits('cancel')">取消</div>
          </slot>
        </div>
      </div>
    </template>
    
    <style lang="scss">
    :root {
    
    
    // 定义css变量var(变量格式),可以让引用组件的父组件自定义css值
    
    
      --op-search-padding: 10px var(--van-padding-sm);
      --op-search-background-color: var(--van-background-color-light);
      --op-search-content-background: var(--van-gray-1);
      --op-search-left-icon-color: var(--van-gray-6);
      --op-search-action-padding: 0 var(--van-padding-xs);
      --op-search-action-text-color: var(--van-text-color);
      --op-search-action-font-size: var(--van-font-size-md);
      --op-search-input-height: 34px;
    }
    
    .op-search {
      display: flex;
      align-items: center;
      box-sizing: border-box;
      padding: var(--op-search-padding);
      background: var(--op-search-background-color);
    
      &--show-action {
        padding-right: 0;
      }
    
      &__content {
        display: flex;
        flex: 1;
        padding-left: var(--van-padding-sm);
        background: var(--op-search-content-background);
        border-radius: var(--van-border-radius-sm);
        &--round {
          border-radius: var(--van-radius-max);
        }
      }
    
      &__action {
        padding: var(--op-search-action-padding);
        color: var(--op-search-action-text-color);
        font-size: var(--op-search-action-font-size);
        line-height: var(--op-search-input-height);
        cursor: pointer;
        user-select: none;
      }
    
      &__field {
        flex: 1;
        padding: 5px var(--van-padding-xs) 5px 0;
        background-color: transparent;
    
        .op-field__left-icon {
          color: var(--op-search-left-icon-color);
          margin-right: var(--van-padding-base);
          .van-icon {
            font-size: var(--van-field-icon-size);
          }
        }
      }
    }
    
    .op-cell {
      display: flex;
      box-sizing: border-box;
      width: 100%;
      color: var(--van-cell-text-color);
      font-size: var(--van-cell-font-size);
      line-height: var(--van-cell-line-height);
      &__value {
        flex: 1;
        color: var(--van-cell-text-color);
        vertical-align: middle;
        word-wrap: break-word;
      }
    }
    
    .op-field {
      &__control {
        display: block;
        box-sizing: border-box;
        width: 100%;
        min-width: 0;
        margin: 0;
        padding: 0;
        border: 0;
        color: var(--van-field-input-text-color);
        line-height: inherit;
        text-align: left;
        background-color: transparent;
        resize: none;
        user-select: none;
        &::placeholder {
          color: var(--van-field-placeholder-text-color);
        }
      }
      &__body {
        display: flex;
        align-items: center;
      }
      &__right-icon {
        color: var(--van-field-right-icon-color);
        padding: 0 var(--van-padding-xs);
        line-height: inherit;
        flex-shrink: 0;
      }
      &__clear {
        color: var(--van-field-clear-icon-color);
        font-size: var(--van-field-clear-icon-size) !important;
        cursor: pointer;
      }
    }
    input {
      &::-webkit-search-decoration,
      &::-webkit-search-cancel-button,
      &::-webkit-search-results-button,
      &::-webkit-search-results-decoration {
        display: none;
      }
    }
    </style>
    

BEM 命名规范

定义

  • Bem是块(block) 、元素(element) 、修饰符(modifier)的简写
  • - 中划线:仅作为连字符使用,表示某个块或者某个子元素的多单词之间的连接记号
  • __ 双下划线:双下划线用来连接块和块的子元素
  • -- 双中划线:双中划线用来描述一个块或者块的子元素的一种状态

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

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

相关文章

某赛通电子文档安全管理系统 UploadFileToCatalog SQL注入漏洞复现

0x01 产品简介 某赛通电子文档安全管理系统(简称:CDG)是一款电子文档安全加密软件,该系统利用驱动层透明加密技术,通过对电子文档的加密保护,防止内部员工泄密和外部人员非法窃取企业核心重要数据资产,对电子文档进行全生命周期防护,系统具有透明加密、主动加密、智能…

睿尔曼超轻量仿人机械臂——外置按钮一键启停程序配置

在睿尔曼超轻量仿人机械臂—外置按钮盒使用说明一文中&#xff0c;介绍了外置按钮盒的安装及使用。它能够使机械臂的使用变得更加编辑&#xff0c;仅需按钮即可完成运动程序的启停等控制&#xff0c;而无需进入示教界面操作。 在示教界面中&#xff0c;我们可以完成运动程序的…

UserWarning: Glyph 39640 missing from current font问题

是因为不支持中文字体导致的&#xff0c;设置为一个支持中文的字体就行了。 另外&#xff0c;上面的改动会引起负号显示为方块&#xff0c;需要额外再加一条设置。 在中文系统上 import matplotlib.pyplot as plt plt.rcParams[font.sans-serif] [SimHei] # 设置为一个支持…

xlsx xlsx-style坑记录

1 安装 npm install xlsx --savenpm install xlsx-style --save Umi运行会报错 自己代码 import XLSX from "xlsx"; import XLSXStyle from "xlsx-style";const data [["demo1","demo2","demo3","demo4","…

计算机设计大赛 深度学习 python opencv 火焰检测识别 火灾检测

文章目录 0 前言1 基于YOLO的火焰检测与识别2 课题背景3 卷积神经网络3.1 卷积层3.2 池化层3.3 激活函数&#xff1a;3.4 全连接层3.5 使用tensorflow中keras模块实现卷积神经网络 4 YOLOV54.1 网络架构图4.2 输入端4.3 基准网络4.4 Neck网络4.5 Head输出层 5 数据集准备5.1 数…

CSS3的新盒子,选择器等

新增的选择器&#xff1a; 属性选择器&#xff1a; 结构伪类选择选器&#xff1a; nth较为重要&#xff1a;但公式中的字母必须是n 区别&#xff1a; nth-child&#xff1a; 认为父类下的都是儿子&#xff0c;此时就需要有对应的需要&#xff0c;如下&#xff0c;此时即使排1&…

如何从零开始开发一个PS5浏览器 | How to develop a PS5 browser

环境&#xff1a;Windows PS5一台 问题&#xff1a;PS5折腾需要使用PKG浏览器访问特定网址&#xff0c;如何自定义网址呢&#xff1f; 解决办法&#xff1a;使用开发套件PS Multi Tools开发一个空应用&#xff0c;利于deeplinkUri 参数访问网页 背景&#xff1a;PS5折腾后&…

【IMAX6U移植OpenCV】

IMAX6U移植OpenCV V1.3 一 安装通用交叉编译器1.1 下载通用交叉编译器1.2 安装通用交叉编译器1.3 验证通用交叉编译器 二 搭建 OpenCV 3.4.1 的编译环境2.1 下载 OpenCV 3.4.1 源码2.2 配置 OpenCV 环境2.3 编译 OpenCV 源码 三 Qt 项目中加入OpenCV3.1 Qt 项目的 pro 文件Open…

uniapp 使用 uni-file-picker 上传头像

此处使用 select 处理选择完文件后的逻辑&#xff0c;即将文件上传到自己的服务器。 <uni-file-picker limit"1" :del-icon"false" disable-preview :imageStyles"imageStyles"file-mediatype"image" select"upload"&g…

Debug Eigen

(参考https://eigen.tuxfamily.org/index.php?titleDeveloper%27s_Corner#Debugging_under_Visual_Studio&#xff09; 假如我们直接想要检查Eigen中的VectorXf的值&#xff0c;我们会发现无法看到内部的值&#xff0c;如图 只需要下载eigen.natvis这个文件&#xff0c; &…

【Pytorch】CNN中的Attention

目录 更大层面上的Attention在attention中&#xff0c;怎么分区channel-wise还是spatial-wise举一个Spatial-Channel Attention的例子 使用广泛的Dot-product Attentionattention机制中的query,key,value的概念解释Attention的一个例子 更大层面上的Attention 在attention中&a…

GitHub的使用操作

记得看目录哦&#xff01; 1. 创建仓库2. 下载desktop3. 把创建的库克隆到本地4. 文件拷贝到本地仓库![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/7171ac6c4ca14e3b8d22717121f79c9e.png)5. 在网址后面加/compare进行比较6. 给系统添加功能 1. 创建仓库 2. 下载…

proxmox集群从7.4升级到最新的8.1

关于proxmox&#xff0c;给Zstack的公开建议 十一放假折腾服务器札记 proxmox​​​​​​​专栏上面第一篇文写的时间还是22年6月底&#xff0c;用proxmox搭建的3机集群在合肥光源束测系统后台在线工作快两年了&#xff0c;在没有UPS保护的情况下&#xff0c;经历了实验室的…

CHS_08.2.3.6_1+生产者-消费者问题

CHS_08.2.3.6_1生产者-消费者问题 问题描述问题分析思考&#xff1a;能否改变相邻P、V操作的顺序&#xff1f;知识回顾 在这个小节中 我们会学习一个经典的进程同步互斥的问题 问题描述 并且尝试用上个小节学习的p v操作 也就是信号量机制来解决这个生产者消费者问题 问题的描…

【实战系列----消息队列 数据缓存】rabbitmq 消息队列 搭建和应用

线上运行图&#xff0c;更新不算最新版&#xff0c;但可以使用修改线程等补丁功能&#xff0c;建议使用新版本。 远程服务器配置图: 这个可以更具体情况&#xff0c;因为是缓存队列理所当然 内存越大越好&#xff0c;至于核心4核以上足够使用。4核心一样跑 这里主要是需要配置服…

麒麟系统—— openKylin 安装 Nginx

麒麟系统—— openKylin 安装 Nginx 一、准备工作1. 确保麒麟系统 openKylin 已经安装完毕。 二、下载 nginx三、解压与运行解压检查与编译安装编译运行 四、配置加入到服务中加入环境变量nginx 配置文件 五、常用命令 Nginx 是一款高性能的 HTTP 和反向代理服务器&#xff0c…

Android super.img解包和打包指南(含工具下载lpunpack、lpmake、lpdump)

本文所有命令均需要在linux 上执行 一、解包 1、将Android sparse image格式的super.img转成二进制文件 $ sudo apt install android-sdk-libsparse-utils $ simg2img super.img super.img.bin 2、下载工具lpunpack 和lpmake、lpdump 以及其依赖库 下载地址:https://downl…

C语言实现12种排序算法

1.冒泡排序 思路&#xff1a;比较相邻的两个数字&#xff0c;如果前一个数字大&#xff0c;那么就交换两个数字&#xff0c;直到有序。 时间复杂度&#xff1a;O(n^2)&#xff0c;稳定性&#xff1a;这是一种稳定的算法。 代码实现&#xff1a; void bubble_sort(int arr[],…

在Debian11安装Proxmox VE 7及设置GPU工作环境

我们在测试大模型&#xff0c;深度学习的过程中&#xff0c;可能遇到的情况就是不断的清空系统&#xff0c;避免老系统中安装的软件对测试系统造成影响&#xff0c;导致测试结果不准确或莫名报错。今天为小伙伴们介绍使用PVE7做成一个人工智能开发和测试的平台&#xff0c;你可…

Day40 0-1背包问题

0-1背包问题 小明是一位科学家&#xff0c;他需要参加一场重要的国际科学大会&#xff0c;以展示自己的最新研究成果。他需要带一些研究材料&#xff0c;但是他的行李箱空间有限。这些研究材料包括实验设备、文献资料和实验样本等等&#xff0c;它们各自占据不同的空间&#x…