vue3+tsx+element-plus封装组件总结

2023-11-18

最近在做vue3+plan+tsx+element-plus的项目,tsx在我这里是用来做组件的,以往的开发方式是sfc,就是vue页面的写法

<template>
</template>
<script>
</script>
<style scoped="scoped" lang="scss">
</style>

自从vue3出来之后,舍弃了很多方式,比如支持tsx,额,不解释了,我也是差不多知道意思,更详情的问度娘,我这里讲的就是主要tsx开发的时候碰到的一些问题还有vue3开发的一点总结,后续还会继续补充

我的大部分tsx知识都是在 https://zhuanlan.zhihu.com/p/563203507这篇文章里面学到的,有兴趣的朋友可以去看看
    • tsx支持element-plus里el-table自定义模板<template #default="scope"></template>

这个也是困扰了我很久,在百度上找不到的,可能现在受众少吧,我也是从别人的文章里的蛛丝马迹里面找出来的,实现方式如下

这是用sfc方式的写法

<el-table-column label="Date" width="180">
      <template #default="scope">
        //在这里实现自定义内容,参数是 scope,比如要自定义显示图片就可以<img :src="scope.row.image"/>
      </template>
</el-table-column>

用tsx方式的写法

<el-table-column v-slots={{
              default: (props: Record<'scope', string>) =>
               //在这里实现自定义内容,参数是props,比如要自定义显示图片就可以<img :src="props.row.image"/>
              }}
/>

解释:v-slots必须(我也不知道有没有其他办法,就是写在外面就不行)写在标签里面,然后用双花括号{{}}写具体代码,

default 对应的就是 <template #default="scope"> 里的default

props对应的就是<template #default="scope">里的scope,是一个回调的数组

    • 支持在<template #default="scope"></template>再声明一个具名插槽并且传这个参数回去

这是我在element-plus的基础上封装的一个组件,所以如果需要自定义内容的话还是要把数据给传下去,那就要用到作用域插槽了,不说了,上写法

<el-table-column 
            v-slots={{
              default: (props: Record<'scope', string>) =>
                slots.image && slots.image({row:props.row.image})
              }}
/>

主要实现是slots.image && slots.image({row:props.row.image})

这相当于sfc的<slot name="image" :row="props.row.image"/>

这是作用域插槽

    • v-slots写多个元素,比如写几个el-button时还是要用<>包围

v-slots={{
            default: (prop: Record<'scope', string>) =>
            <>
              <el-button size="small">
                更新
              </el-button>
              <el-button type="primary" size="small">
                查看
              </el-button>
              <el-button type="danger" size="small" >
                删除
              </el-button>
             </>
  }}
    • 那用tsx编写的组件如何导出去并注册(全局+局部)?

首先要注册成为组件

import { defineComponent,reactive,ref,watch } from "vue";

export default defineComponent({
    name: "WayContent",
    props,
    setup(props, {slots }) {
    return ()=>()
    }
)}
  1. 在vue中将defineComponent拿出

  1. 声明name

  1. 在setup里面的return写组件页面,就是写<div></el-button>这些

  1. setup第一个参数props是父组件传递过来的值,第二个参数是context,{slots}是从context取出slots属性,{slots,emit}就是从context里面取出emit属性

  1. 在defineComponent里面的props参数是描述父组件传递过来的值,像vue2那样写,不过没有默认值了,得自己做判断或者用计算属性

全局注册

在main.js或main.ts中

import WayContent from "@/components/WayContent";
const app = createApp(App);
app.component("WayContent", WayContent);

局部注册

在需要得地方

import WayContent from "@/components/WayContent";

然后可以直接使用<WayContent/>,不用再到components里面去注册了,不过或许是要在setup语法糖下才能这样写吧,没试过,就是这样

<script setup lang="ts">
import WayContent from "@/components/WayContent";
</scipt>
    • 监听

import { ref,watch } from "vue";
const test = ref()
watch(() => test.value, (newVal) => {
    console.log(newVal)
 }, {
     deep: true,
     immediate: true
})

deep,imediate这些配置的作用应该和vue2没啥区别,就是写法都改成组合式api写的了,监听的变量必须要加上.value

    • mixin混入

vue3还可以跟vue2一样写mixin,就是vue3向下包容的,只要没明确舍弃的vue2有的vue3都可以写,不过vue3不推荐vue2那种写法了,都是倾向于组合式,mixin也是如此

context.ts

import { ref,reactive,onMounted,watch } from "vue";

export const context =(gets) => {
// 数据列表
const list = ref()
// 搜索条件
const condition = ref()
// 分页配置
const pagination = ref({
    pageNo: 1,
    pageSize: 10,
    total: 0,
    layout: "total, sizes, prev, pager, next, jumper",
    handleCurrentChange: (p)=>{
      gets2(p,pagination.value.pageSize)
    },
    handleSizeChange: (p)=>{
      gets2(pagination.value.pageNo,p)
    }
  })
// 获取数据
const gets2 = (pageNo,pageSize) =>{
  let c = {};
  c.pageNo = pageNo;
  c.pageSize = pageSize;
  if(condition.value){
    for(let k in condition.value){
      if(condition.value[k]){
        c[k] = condition.value[k]
      }
    }
  }
    gets(c).then(res => {
      list.value = res.data.data;
      pagination.value.total = res.data.total;
    })
}
//监听搜索条件的改变,当搜索条件改变了就触发请求获取数据
watch(() => condition.value, (newVal) => {
    if(newVal){
    gets2(1,pagination.value.pageSize)
  }
}, {
   deep: true,
   immediate: true
})
//页面加载完成后请求获取数据
onMounted(() => {
    gets2(1,pagination.value.pageSize)
})
return {
    list,pagination,gets2,condition
}
}

在需要它的地方

<script setup lang="ts">
  import { ref,onMounted,reactive } from "vue";
  import { gets } from "@/api/article.ts"
  import { context } from "@/mixin/context.ts"
  const {list, pagination,condition} = context(gets);
</script>

如上所示

在context.ts里面可以写watch,声明响应式变量,然后引用的比如list,在引用的页面改变它context.ts里面的list也会跟着改变,然后也可以传递一个参数,比如我是传了一个方法gets进去,也都有用,他不再像是vue2那样

import context from "@/mixin/context"
export default {
    mixin: [context]
}

这种写法了

    • 写一个有v-model作用的组件

input.tsx

import { defineComponent,reactive,ref,watch } from "vue";

const props = {
   placeholder: { //提示内容
     type:String,
   },
   modelValue: {
      type: [String,Number],
      required: true,
    }
}
export default defineComponent({
    name: "WayInput",
    props,
    emits: ['update:modelValue'],
    setup(props, {emit,slots}) {
       const modelValue = ref(props.modelValue)
      watch(() => modelValue.value, (newVal) => {
            emit('update:modelValue', newVal)
          }, {
            deep: true,
            immediate: true
          })
      watch(() => props.modelValue, (newVal) => {
            modelValue.value = newVal
          }, {
            deep: true,
            immediate: true
          })
      return ()=>(
        <div wid="wayInput">
              <el-input clearable v-model={modelValue.value} placeholder={props.placeholder || "请输入内容"} />
        </div>
      )
    }
})

使用它

<WayInput v-model="test"/>

import WayInput from "./input.tsx"
import { reactive } from "vue";
const test = reactive()

在input.tsx中主要是以下代码

const props = {
   modelValue: {
      type: [String,Number], //用来接受父组件的v-model
      required: true,
   }
}
const modelValue = ref(props.modelValue) //声明一个modelValue并把父组件的v-model值赋予给他
//监听modelValue的变化,把值传递给父组件的v-model
watch(() => modelValue.value, (newVal) => {
            emit('update:modelValue', newVal)
          }, {
            deep: true,
            immediate: true
})
//监听父组件的v-model变化,把值传递给modelValue
watch(() => props.modelValue, (newVal) => {
            modelValue.value = newVal
          }, {
            deep: true,
            immediate: true
})
//把modelValue.value绑定给el-input
<el-input clearable v-model={modelValue.value} placeholder={props.placeholder || "请输入内容"} />

扩展,如今vue3支持多v-model了,还能写函数,这些就不再阐述了,有兴趣的小伙伴可以去百度了解一下

    • 总结暂时完成

另外一些细节的,比如ref,reactive的区别,还有setup语法糖等等,网上一搜一大把,我就不说了,还有,我在写一个可以传几个参数列表,增删查改配置的参数列表,就可以实现普通后台管理的搜索,展示,新增,修改,删除的组件,有兴趣的小伙伴可以收藏我的博客https://www.wayblogs.com/随时欢迎访问来关注我的进度

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

vue3+tsx+element-plus封装组件总结 的相关文章

随机推荐

  • Pycharm无法正常安装第三方库的时候,有以下几条应对方法

    1 首先检查自己的环境变量是否配置正确 点击setting 点击 Python Interpreter 点击Add Interpreter 找到这个界面 点击右方三个点 然后选择正确的python安装位置 点击OK 配置完毕之后再试一次从这
  • android轮播图实现方案,Android轮播图实现教程

    ListView的headerView设置为轮播图之后结合上 下拉刷新 加载的模式成为现在大多数APP的一个必须具备的功能 对于许多初学者来说想要实现轮播图这样一个集线程睡眠 自动处理 替换过程中刷新UI界面的组合功能非常困难 没有思路 感
  • 实验吧 web题--代码审计类

    一 因缺思汀的绕过 1 web题常规套路就是查看源代码 于是右击查看源代码发现 br 构造url http ctf5 shiyanbar com web pcat source txt 查看php代码 2 关键php代码 if mysql
  • [HashMap源码学习之路]---put方法中的hash方法介绍

    HashMap中的put方法中的hash方法 以下是put方法的代码 public V put K key V value return putVal hash key key value false true 当我第一次看到这个地方的时候
  • 2022年,能让你月入过万的5个副业,不信试试

    2021年已经过去了 不管过去的一年 是成功还是失败 一切都过去了 新的一年要开始做新的规划 当务之急 搞钱最为重要 01 自媒体写作 以前我总是觉得会写文章不算什么技能 工作之后才发现 文字功底好优势好大 无论是工作还是做副业 发现会写文
  • 10.29奇偶交换排序

    奇偶交换排序如下所述 第一趟对所有奇数i 将a i 和a i 1 进行比较 第二趟对所有的偶数i 将a i 和a i 1 进行比较 若a i gt a i 1 则将两者交换 第三趟对奇数i 第四趟对偶数i 依次类推直至整个序列有序为止 in
  • Flask 学着用模板 render_template

    上一章节是做到了在本地浏览器上打印出hello world 如果你要更加复杂 可以像下面一样在return结果里添加内容 但是 简单的几句话你可以这么写 要是整的一个网页 你可没法把代码都拖在return后面吧 所以 后面引入了模板功能 模
  • 抽象函数(Java)

    我们现在深入理解一下抽象数据类型背后的理论 这些理论不仅本身很有趣 它们在ADT的设计与实现中也很有意义 如果你能够很好的理解它们 你将会设计出更好的抽象类型 并且远离那些隐晦的陷阱 在研究抽象类型的时候 先思考一下两个值域之间的关系 表示
  • console错误合集

    handlers i call is not a function 从报错的handlers i call 入手查找原因 这个错误是 调用相关的生命周期钩子函数引起来的错误 查看你的页面相关 生命周期钩子函数 是否有 声明了未定义方法 或是
  • 程序员的小浪漫----烟火

    多代码 慎读 预览 完整项目预览 预览地址 属性设计 烟花状态 烟花应有三个状态 升空 等待炸裂 炸裂后 烟花 发射点 x y 爆炸点 xEnd yEnd 升空后等待炸裂时间 wait 炸裂后微粒个数 count 烟花半径 radius 烟
  • 数据产品经理基础之写好报表需求文档

    今天业务部门向我提了个需求 想要在BI上实现一份日报表 并提供了一份日报表的excel文档样例 我为了 敏捷开发 没写需求文档 直接把excel扔给了开发 结果就导致一系列后遗症 首先是开发在写sql的过程频繁确认需求 xxx字段是什么意思
  • 白盒测试相关的一些知识

    在白盒测试中 可以使用各种测试方法进行测试 下面这篇文章 可能比较枯燥 如果不乐意读 可以先收藏 如果在你的工作中真遇到白盒测试的话 可以回过头再来看看 还是值得读一读 一般来说 白盒测试时要考虑以下5个问题 1 测试中尽量先用自动化工具来
  • 数据结构之链表与线性表

    数据结构之链表与线性表 线性表 顺序线性表 顺序表 顺序线性表 使用数组实现 一组地址连续的存储单元 数组大小有两种方式指定 一是静态分配 二是动态扩展 优点 随机访问特性 查找O 1 时间 存储密度高 逻辑上相邻的元素 物理上也相邻 缺点
  • JVM面试FAQ分析

    JVM面试FAQ分析 1 入门部分 1 1为什么要学习JVM 1 2 你了解哪些JVM产品 1 3 JVM的构成有哪几部分 2 类加载部分 2 1 你知道哪些类加载器 2 2 什么是双亲委派类加载模型 2 3 双亲委派方式加载类有什么优势
  • AdaBoost算法

    参考 https www bilibili com video BV1ix411i7yp p 26 机器学习技法 之 聚合模型 Aggregation Model 士杰的博客 CSDN博客 聚合模型
  • Java当中解析ini文件对应到JavaBean当中

    目录 1 ini文件简介 2 ini文件 3 ini解析工具类 4 示例运行结果 1 ini文件简介 ini 文件是Initialization File的缩写 即初始化文件 是windows的系统配置文件所采用的存储格式 统管window
  • 使用Nginx做反向代理超时的问题

    使用Nginx做反向代理时 当被代理服务器没有在指定时间内创建连接 接受请求或返回响应时 Nginx就会断开连接 并返回给客户端 504 Gateway Time out 错误 关于Nginx做反向代理超时 可以通过proxy connec
  • java判断是否为金额

    金额验证 public static boolean isNumber String str java util regex Pattern pattern java util regex Pattern compile 1 9 1 d 0
  • VsCode 常用好用插件/配置+开发Vue 必装的插件

    一 VsCode 常用好用插件 1 实时刷新网页的插件 LiveServer 2 open in browser 支持快捷键与鼠标右键快速在浏览器中打开html文件 支持自定义打开指定的浏览器 包括 Firefox Chrome Opera
  • vue3+tsx+element-plus封装组件总结

    最近在做vue3 plan tsx element plus的项目 tsx在我这里是用来做组件的 以往的开发方式是sfc 就是vue页面的写法