IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 关于 vue3 的 jsx 写法问题 -> 正文阅读

[JavaScript知识库]关于 vue3 的 jsx 写法问题


关于 vue3 的 jsx 写法问题。

安装 @vitejs/plugin-vue-jsx vite 插件

yarn add @vitejs/plugin-vue-jsx -D

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

安装完成之后,在 vite.config.js 中进行配置:

import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import vueJsx from "@vitejs/plugin-vue-jsx";

export default defineConfig({
	plugins: [
		vue(),
		vueJsx(),
	]
})

然后,即可编写 jsx 形式的 vue 单文件组件。

编写示例

基础实例

vue3 新增了 setup 这个组合式 api,这样就使得利用 jsx 编写 vue 组件时的风格非常类似于 react。在 setup 可以创建 state,接受 props,还可以直接返回 jsx。

import { defineComponent} from 'vue';

export default defineComponent({
	setup() {
		return <div>123456789</div>
	}
});

props 和 state

在 vue3 中,存在 ref 和 reactive 这两个创建响应式状态的 api。由于内置的观察者模式,导致 vue 并不需要像 react 那样,提供 useMemo,useCallback 等根据条件判断是否更新的钩子。

ref 在 render 函数中,会自动解构,不需要再使用 ref.value 来获取里面的值。

推荐使用 ref,而不是 reactive。

props 则需要在 defineComponent 中使用 props 属性,指定 props,该组件才会接受对应的 props。
子组件不能在 setup 中返回 jsx,否则弹出警告,不渲染该子组件。

父组件接受子组件后,不可在 setup 中直接返回 ctx,或者 ctx.slots?.default?.() 计算后的值,第一种情况弹出警告,不渲染该子组件;第二种情况,该子组件不会响应式。正确的做法,应该是返回一个渲染函数。

子组件:

import { defineComponent, ref, reactive } from 'vue;

export default defineComponent({
	name: 'TestB',
	// 必须传递props,提醒 vue,该组件可以接受名称为 str 的值
	// 如果不填,则 props 接受不到该值。
	// 如果该组件为子组件,不可在 setup 中返回元素,必须在 render 中返回元素
	props: ['str'],
	setup(this, props, ctx) {
		const count = ref(0);
		const { str } = props;
		const reactiveCount = reactive({value: 0});
		return {
			str,
			count,
			reactiveCount,
		}
	},
	render() {
		const { count, reactiveCount, str } = this;
		return <div>{count} - {reactiveCount.value} - {str}</div>
	}
});

父组件:

import { defineComponent } from "vue";

export default defineComponent({
    props: ['testStr'],
    name: 'TestA',
    setup(props, ctx) {
        const { testStr } = props;
        // 注意,不要直接返回一个 ctx.slots?.default?.() 计算后的值,这样不能响应式
        // 同时,也要注意,不能直接返回 ctx,会有警告,同时不会显示子元素
        const renderFn = () => {
            return <div>{ ctx.slots?.default?.() ?? "" }</div>
        }
        return {
            testStr,
            renderFn,
        }
    },
    render() {
        const { testStr, renderFn } = this;
        return <div>你输入的字符串: {testStr}
            <div>子组件</div>
            <div>{ renderFn() }</div>
        </div>
    }
})

事件监听

@vitejs/plugin-vue-jsx 该插件默认将 @input 等相关模板语法,替换成了 onInput 等 jsx 形式。这里以点击事件举例。

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

interface ITestAProps {
  str: string;
}

export default defineComponent({
  name: "TestA",
  props: ["str"],
  setup(this, props, ctx) {
    const count = ref(0);
    const { str } = props;
    const reactiveCount = reactive({ value: 0 });
    const onClick = () => {
      count.value++;
    };
    const reactiveClick = () => {
      reactiveCount.value++;
    };
    return {
      str,
      count,
      reactiveCount,
      onClick,
      reactiveClick,
    };
  },
  render() {
    const { count, reactiveCount, str, onClick, reactiveClick } = this;
    return (
      <div>
        <div onClick={onClick}>{count}</div>
        <div onClick={reactiveClick}>{reactiveCount.value}</div>
        <div>{str}</div>
      </div>
    );
  },
});

插槽

vue3 中,可以使用快捷语法(以 element-plus 举例)

<el-popconfirm
  title="确认删除最后一个配置内容?"
  confirm-button-text="确认"
  cancel-button-text="取消"
  @confirm="
      addNewValue.newConfigList.length > 1
      ? addNewValue.newConfigList.pop()
      : ElMessage({
          message: '不能删除所有配置内容',
          type: 'error',
  	  })
  "
 >
   <template #reference>
    <el-button type="danger"> 删除最后一个表单配置内容 </el-button>
  </template>
</el-popconfirm>

jsx 形式中的 vue3 中,可以使用

import { defineComponent } from 'vue';
import { ElPopconfirm, ElButton } from 'element-plus';

export default defineComponent({
	render() {
		return <ElPopconfirm
			title="确认删除最后一个配置内容?"
			confirmButtonText="确认"
			cancelButtonText="取消"
			onConfirm={() => {
				addNewValue.newConfigList.length > 1
      			? addNewValue.newConfigList.pop()
      			: ElMessage({
          			message: '不能删除所有配置内容',
          			type: 'error',
  	  			})
			}}
			v-slot={{
				reference: () => <ElButton type="danger">删除最后一个表单配置内容</ElButton>
			}}
		>
			
		</ElPopconfirm>
	}
});

其余相关的属性

其余相关的属性,比如 v-model 啥的,还是按照原来的写法去写。

这里需要注意一点 v-model 如果使用 jsx 写法,不会自动双向绑定,需要自己去写对应的函数。

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-07-21 21:27:19  更:2022-07-21 21:27:55 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 -2025/1/11 12:30:00-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码