17 vue3之tsx手写vite tsx插件

news2024/10/16 15:19:04

我们之前呢是使用Template去写我们模板。现在可以扩展另一种风格TSX风格

vue2 的时候就已经支持jsx写法,只不过不是很友好,随着vue3对typescript的支持度,tsx写法越来越被接受,减少我们学习react的成本 Ant Design组件库就是使用tsx语法编写的

安装插件

npm install @vitejs/plugin-vue-jsx -D

vite.config.ts配置 

import vueJsx from "@vitejs/plugin-vue-jsx";

export default ({ mode }: any) => {
  console.log("mode===>", mode);
  console.log(loadEnv(mode, process.cwd()));
  return defineConfig({
    plugins: [
      vue(),
      vueJsx(), //注册
      AutoImport({
        imports: ["vue"], // 引入vue的自动引入
      }),
    ],
  });
};

 修改tsconfig.json 配置文件

    "jsx": "preserve",
    "jsxFactory": "h",
    "jsxFragmentFactory": "Fragment",

使用Tsx

在目录新建一个xxxxxx.tsx文件

tsx支持 v-model 的使用

 
import { ref } from 'vue'
 
let v = ref<string>('')
 
const renderDom = () => {
    return (
        <>
           <input v-model={v.value} type="text" />
           <div>
               {v.value}
           </div>
        </>
    )
}
 
export default renderDom

v-show

 
import { ref } from 'vue'
 
let flag = ref(false)
 
const renderDom = () => {
    return (
        <>
           <div v-show={flag.value}>景天</div>
           <div v-show={!flag.value}>雪见</div>
        </>
    )
}
 
export default renderDom

v-if是不支持 可使用三元表达式支持

import { ref } from 'vue'
 
let flag = ref(false)
 
const renderDom = () => {
    return (
        <>
            {
                flag.value ? <div>景天</div> : <div>雪见</div>
            }
        </>
    )
}
 
export default renderDom

v-for不支持 可使用map支持

import { ref } from 'vue'
 
let arr = [1,2,3,4,5]
 
const renderDom = () => {
    return (
        <>
            {
              arr.map(v=>{
                  return <div>${v}</div>
              })
            }
        </>
    )
}
 
export default renderDom

v-bind使用

import { ref } from 'vue'
 
let arr = [1, 2, 3, 4, 5]
 
const renderDom = () => {
    return (
        <>
            <div data-arr={arr}>1</div>
        </>
    )
}
 
export default renderDom

v-on绑定事件 所有的事件都按照react风格来

  • 所有事件有on开头
  • 所有事件名称首字母大写
 
const renderDom = () => {
    return (
        <>
            <button onClick={clickTap}>点击</button>
        </>
    )
}
 
const clickTap = () => {
    console.log('click');
}
 
export default renderDom

Props 接受值

 
import { ref } from 'vue'
 
type Props = {
    title:string
}
 
const renderDom = (props:Props) => {
    return (
        <>
            <div>{props.title}</div>
            <button onClick={clickTap}>点击</button>
        </>
    )
}
 
const clickTap = () => {
    console.log('click');
}
 
export default renderDom

Emit派发

type Props = {
    title: string
}
 
const renderDom = (props: Props,content:any) => {
    return (
        <>
            <div>{props.title}</div>
            <button onClick={clickTap.bind(this,content)}>点击</button>
        </>
    )
}
 
const clickTap = (ctx:any) => {
 
    ctx.emit('on-click',1)
}

Slot

const A = (props, { slots }) => (
  <>
    <h1>{ slots.default ? slots.default() : 'foo' }</h1>
    <h2>{ slots.bar?.() }</h2>
  </>
);
 
const App = {
  setup() {
    const slots = {
      bar: () => <span>B</span>,
    };
    return () => (
      <A v-slots={slots}>
        <div>A</div>
      </A>
    );
  },
};
 
// or
 
const App = {
  setup() {
    const slots = {
      default: () => <div>A</div>,
      bar: () => <span>B</span>,
    };
    return () => <A v-slots={slots} />;
  },
};
 
// or you can use object slots when `enableObjectSlots` is not false.
const App = {
  setup() {
    return () => (
      <>
        <A>
          {{
            default: () => <div>A</div>,
            bar: () => <span>B</span>,
          }}
        </A>
        <B>{() => "foo"}</B>
      </>
    );
  },
};

完整示例代码

三种不同写法的tsx语法

三种不同写法的tsx语法 一和3的方式用的比较多 我们这里主要是使用第三种

  • 第一种返回渲染函数
  • 第二种optionsApi方式

  • 第三种setup函数模式

// 三种不同写法的tsx语法 一和3的方式用的比较多 我们这里主要是使用第三种
// 第一种返回渲染函数
/* export default function () {
  return <div>cookie</div>;
} */

// 第二种optionsApi方式

/*import { defineComponent } from "vue";
 export default defineComponent({
  data() {
    return {
      name: "cookie123",
    };
  },
  render() {
    return <div>{this.name}</div>;
  },
}); */

//第三种setup函数模式
/* import { defineComponent } from "vue";
export default defineComponent({
  setup() {
    return () => <div>cookie-setup</div>;
  },
}); */

父组件

<template>
  <div class=""></div>
  <Cookie :title="'Cookie标题'" @cusemit="getStr"></Cookie>
  <hr />
  <MyTSX title="MyTSX标题" @emit1="getStr"></MyTSX>
</template>

<script setup lang="ts">
import { ref, reactive } from "vue";
import MyTSX from "./components/MyTSX";
import Cookie from "./components/Cookie ";
let getStr = (params: string) => {
  console.log("a接收,,,", params);
};
</script>

<style lang="less" scoped></style>

子组件MyTSX.tsx

  • 派发事件注意函数柯里化
// 三种不同写法的tsx语法 一和3的方式用的比较多 我们这里主要是使用第三种
// 第一种返回渲染函数
/* export default function () {
  return <div>cookie</div>;
} */

// 第二种optionsApi方式

/*import { defineComponent } from "vue";
 export default defineComponent({
  data() {
    return {
      name: "cookie123",
    };
  },
  render() {
    return <div>{this.name}</div>;
  },
}); */

//第三种setup函数模式
/* import { defineComponent } from "vue";
export default defineComponent({
  setup() {
    return () => <div>cookie-setup</div>;
  },
}); */

// v-show 指令
// 1.ref在tsx语法中变量中使用{flag.vue},并且值不会如在template中自动解析.value
// 2.在tsx语法中,v-if不支持可使用三元表达式代替
// v-for也是不支持的,需要使用map函数代替
// v-bind直接使用name={}  <div name="666">name</div>
// props emit  <button onClick={fn()}>点击</button>还未点击就触发了 需要使用函数柯里化的方式处理
// slot插槽
import { defineComponent, ref } from "vue";
type Props = {
  // 泛型字面量
  title?: string;
};
// 定义一个组件

const A = (props, { slots }) => (
  <div>
    <div>{slots.default ? slots.default() : "默认值"}</div>
    {/* 定义其他的插槽 slots.bar?.()等同上面的写法 */}
    <div>{slots.bar?.()}</div>
  </div>
);
export default defineComponent({
  props: { title: String },
  emits: ["cusemit"],
  setup(props: Props, { emit }) {
    let show = ref(true);
    let arr = [1, 2, 3, 4, 5];
    let name = "666";
    const fn = (a: any) => {
      console.log("fn触发了", a);
      emit("cusemit", a);
    };
    const slot = {
      default: () => <div>default插槽值</div>,
      bar: () => <div>bar插槽值</div>,
    };
    return () => (
      <div>
        <div v-show={show.value}>show</div>
        {show ? <div>显示1</div> : <div>显示0</div>}
        {arr.map((v) => {
          return <div>${v}</div>;
        })}
        <div name={name}>name</div>
        <hr />
        <h3>props emit 语法</h3>
        <div>{props?.title}</div>
        <button onClick={() => fn(33)}>点击</button>
        <hr />
        <h3>插槽 语法</h3>
        <A v-slots={slot} />
      </div>
    );
  },
});

子组件cookie.tsx 与MyTSX.tsx不同的写法

import { ref } from "vue";
/* 
需要注意的点
1.ref在tsx语法中变量中使用{flag.vue},并且值不会如在template中自动解析.value

*/

let v = ref<string>("");
let flag = ref(false);
let list = [1, 2, 3];

type Props = {
  // 泛型字面量
  title: string;
};

const renderDom = (props: Props, ctx: any) => {
  // ctx东西
  //  1.v-model
  /*return (
    <>
      <input v-model={v.value} type="text" />
      <div>{v.value}</div>
    </>
  ); */

  //2.v-show ,v-if不支持可以使用js编程的方式去转变
  /* return (
    <div>
      <div v-show={flag}>显示1</div>
      <div v-show={!flag}>显示2</div>
      {flag ? <div>显示3</div> : <div>显示4</div>}
    </div>
  ); */

  //3.v-for不支持,可以用map ,v-bind不支持可以用data-index,v-on不支持可以用onClick={tap}  传参使用onClick={tap1.bind(this, 66)}
  // props在组件中使用的是一样的,事件派发ctx
  return (
    <div>
      <div>{props.title}</div>
      {list.map((v) => {
        return (
          <div onClick={tap} data-index={v}>
            ${v}
          </div>
        );
      })}
      <button onClick={tap1.bind(this, 66)}>
        函数传参,请点击
      </button>
      <button onClick={tap2.bind(this, ctx)}>
        派发事件,请点击
      </button>
    </div>
  );
};
let tap = () => {
  console.log("click");
};
let tap1 = (v: number) => {
  console.log(v);
};
let tap2 = (ctx: any) => {
  console.log(ctx);
  ctx.emit("emit1", "发送");
};

export default renderDom;

效果图:

定义tsx样式

 test.tsx

内联样式不能和className一起使用

import { defineComponent } from "vue";
import styles from "./styles.module.css";
export default defineComponent({
  setup() {
    return () => (
      /*  <div style={{ color: "blue", fontSize: "16px" }}>
        tsx -内联样式
      </div> */
      <div className={styles.container}>
        tsx -CSS Modules
      </div>
    );
  },
});

 styles.module.css 

/* styles.module.css */ 
container { padding: 20px; border: 1px solid #ccc; } 
.title { font-size: 2em; color: #333; }

18 vue3之自动引入ref插件&深入使用v-model-CSDN博客TIps 在Vue3 v-model 是破坏性更新的v-model在组件里面也是很重要的v-model 其实是一个语法糖 通过props 和 emit组合而成的默认值的改变prop:value -> modelValue;事件:input -> update:modelValue;v-bind 的 .sync 修饰符和组件的 model 选项已移除新增 支持多个v-model新增 支持自定义 修饰符 Modifiershttps://blog.csdn.net/qq_37550440/article/details/142522527?sharetype=blogdetail&sharerId=142522527&sharerefer=PC&sharesource=qq_37550440&spm=1011.2480.3001.8118

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

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

相关文章

利用LLMs自动寻找量化投资策略

利用LLMs自动寻找量化投资策略 J.P.Morgan的python教程 Content 本文提出了一个利用大型语言模型&#xff08;LLMs&#xff09;和多代理架构的新框架&#xff0c;用于量化股票投资和投资组合管理。该框架通过整合LLMs生成多样化的alpha因子&#xff0c;并动态评估市场条件&am…

基于 QAnything 的知识库问答系统:技术解析与应用实践

最近已有不少大厂都在秋招宣讲了&#xff0c;也有一些在 Offer 发放阶段。 节前&#xff0c;我们邀请了一些互联网大厂朋友、今年参加社招和校招面试的同学。 针对新手如何入门算法岗、该如何准备面试攻略、面试常考点、大模型技术趋势、算法项目落地经验分享等热门话题进行了…

Mysql 学习——项目实战

MySQL 学习——项目实战 项目出处 博主&#xff1a;Asmywishi Linux-Ubuntu启动Mysql sudo mysqlData preparation Create Database and Table Create database : create database mysql_example1;Start database : use mysql_example1;Create Student table : # 学生表…

vue页面保持在div的底部(适用于聊天界面等需要显示最新信息的场景)

代码示例&#xff1a; <script setup lang"ts"> import {nextTick, onMounted, ref} from vueconst count [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, …

如何将题目文档做成一个题库刷题小程序?

✨告别题海战术&#xff0c;迎接智慧刷题新时代&#xff01;&#x1f680; &#x1f4da;面对堆积如山的题库文档&#xff0c;是否感到无从下手&#xff1f;别担心&#xff0c;这款本土定制刷题小程序来救场啦&#xff01;&#x1f389; &#x1f31f;自动生成题库&#xff0c…

数据结构-3.9.栈在递归中的应用

一.函数被调用背后的过程&#xff1a;最后被调用的函数最先结束也符合栈的后进先出 1.main函数为主函数即程序入口&#xff0c;运行时主函数先入栈&#xff0c;然后存入主函数里的数据&#xff1b; 2.func1函数加载在栈中时他后面的代码的地址#1(调用返回地址&#xff0c;不是…

Xshell7下载及服务器连接

一、Xshell-7.0.0164p、Xftp 7下载 1.1、文件下载 通过网盘分享的文件&#xff1a;xshell 链接: https://pan.baidu.com/s/1qc0CPv4Hkl19hI9tyvYZkQ 提取码: 5snq –来自百度网盘超级会员v2的分享 1.2、ip连接 下shell和xftp操作一样&#xff1a;找到文件—》新建—》名称随…

链表OJ经典题目及思路总结(一)

目录 前言1.移除元素1.1 链表1.2 数组 2.双指针2.1 找链表的中间结点2.2 找倒数第k个结点 总结 前言 解代码题 先整体&#xff1a;首先数据结构链表的题一定要多画图&#xff0c;捋清问题的解决思路&#xff1b; 后局部&#xff1a;接着考虑每一步具体如何实现&#xff0c;框架…

JavaScript 数学基础:数字与运算符解析——WEB开发系列43

哈哈哈哈可能不是每个人都喜欢数学。有些人从小就享受解决复杂的数学问题&#xff0c;而另一些人则在学校被迫学习乘法表和长除法时对数学产生了厌恶。尽管如此&#xff0c;数学仍是生活中不可或缺的组成部分。无论我们处在哪里&#xff0c;数学的应用在我们生活中随处可见。在…

使用 ModelScope Studio 实现可滚动 ChatBot

前面的文章提到过 Gradio 的 Chatbot 不能自动滚动的问题&#xff0c;最近看到了 ModelScope Studio 扩展的一些组件&#xff0c;其中 Chatbot 就完美解决了自动滚动的问题&#xff0c;同时还增加了很多更细化的功能&#xff0c;例如可以设置用户和 AI 的头像。官方文档&#x…

C++进阶(3): 二叉搜索树

二叉搜索树的概念 二叉搜索树又称二叉排序树&#xff0c;它或者是一颗空树&#xff0c;或者具有以下性质的二叉树&#xff1a; 若它的左子树不为空&#xff0c;则左子树上所有的节点的值都小于等于 根节点的值若它的右子树不为空&#xff0c;则右子树上所有的节点的值都大于等…

时序必读论文15|TimeXer:通过外部变量增强Transformer在时间序列预测中的能力

论文标题&#xff1a;TimeXer: Empowering Transformers for Time Series Forecasting with Exogenous Variables 论文链接&#xff1a;https://arxiv.org/abs/2402.19072 前言 仅仅关注内生变量&#xff0c;通常不足以保证准确的预测&#xff0c;外部序列可以为内生变量提供…

MongoDB 副本集搭建 【docker compose + 本机部署】【建议收藏起来】

什么是副本集 MongoDB副本集&#xff08;Replica Set&#xff09;是一种数据冗余和故障恢复机制&#xff0c;它允许你维护相同数据的一个或多个副本&#xff0c;并提供自动故障转移和数据恢复能力。副本集是一个包含多个MongoDB实例&#xff08;通常称为成员&#xff09;的集合…

Linux学习笔记(一):Linux学习环境的安装及远程连接工具的使用

Linux学习笔记&#xff08;一&#xff09;&#xff1a;Linux学习环境的安装及远程连接工具的使用 本地安装虚拟机 1.安装VMWare(点击图片跳转下载&#xff09; 2.安装CentOS7光盘源(点击图片下载&#xff09; 3.安装 一路点下一步 点击确认 等待不要动,可能有点久,直到这个…

【内网渗透】最保姆级的春秋云镜Flarum打靶笔记

目录 flag1 flag3 flag4​ flag2 flag1 扫外网 打的是flarum论坛&#xff0c;p牛之前有写过phar反序列化的利用&#xff1a; 从偶遇Flarum开始的RCE之旅 rockyou.txt爆出administrator/1chris&#xff0c;登录 用这个工具生成phar包 https://github.com/ambionics/p…

【Python报错已解决】IndexError: index 0 is out of bounds for axis 1 with size 0

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 专栏介绍 在软件开发和日常使用中&#xff0c;BUG是不可避免的。本专栏致力于为广大开发者和技术爱好者提供一个关于BUG解决的经…

springboot整合seata

一、准备 docker部署seata-server 1.5.2参考&#xff1a;docker安装各个组件的命令 二、springboot集成seata 2.1 引入依赖 <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-seata</artifactId>&…

helm部署ingress-nginx

helm部署ingress-nginx 19/100 保存草稿 发布文章 sj1163739403 未选择任何文件 ingress-nginx是管理南北向流量很好的一个工具&#xff0c;可以避免在云端频繁对LB进行配置&#xff0c;通过Label也可以实现让ingress-nginx都部署在指定的NodeGroup 一、helm安装ingress-nginx…

数据管理_DM的实现

DataManager 的实现 DataManager 是数据库系统中的核心组件&#xff0c;负责管理底层数据的访问、修改和事务处理。它是 DM 层直接对外提供方法的类&#xff0c;用来对上层其他模块提供数据操作的API的,同时也实现了对 DataItem 对象的缓存管理。DataItem 存储的 key 是由页号…

使用root账号ssh登录虚拟机ubuntu

在C:\Users\Administrator\.ssh目录下的config中&#xff0c;添加ubuntu会在根目录中&#xff0c;建立一个root文件夹。在该文件夹中建一个.ssh目录。像免密登录ubuntu设置中&#xff0c;把公钥考进去。在vscode中打开文件夹中选择要打开的文件夹&#xff0c;就可以不需要在ubu…