JSX简介以及在Vue3中使用JSX+antd开发组件

一、什么是JSX?

就像这样:

let jsx = 

hello world

;

从表面上来看这和html没啥区别,但是请看左边;我们把一段html代码直接赋值给了一个变量。
JSX=javascript xml就是Javascript和XML结合的一种格式。是 JavaScript 的语法扩展,只要你把HTML代码写在JS里,那就是JSX

二、书写规范

JSX支持换行
let jsx = (
    

hello world

)

1、jsx顶部只能有一个根元素,通常我们用

包起来(在Vue3中也可以使用和React一样不占据Dom结构的Fragment<>空标签)。
2、为了方便阅读,jsx外面需要包上一层小括号()
3、标签要闭合(单边标签得有斜杠)

jsx的注释都需要用花括号包起来
{
    //我是单行注释
}

{/*我是一段注释*/}
jsx插入变量
const _c = 'hello world';
let jsx = (
    

{ _c }

)
jsx表达式嵌入

1.运算表达式

const a = 1;
const b = 1;
let jsx = (
  
{ a + b }
)

2.三元表达式

let _t = 'hello world';
let a = 1;
let b = 2;
let hasButton = true;
let jsx = (
  <>
    

{ _t === 'hello world' ? a :b }

{ //如果hasButton为true,则渲染button组件 hasButton &&

3.函数调用

const func1 = ()=>{ return (
func1
) } let jsx = (

{ //如果在render外定义的函数,请注意加this:this.func1() func1() }

)
JSX 绑定属性

1.绑定普通属性

let jsx = (
    <>
        

hello world

)

2.绑定style

在jsx中,windows风格的命名方式(属性、style、方法、event)都需要转换成驼峰式的写法,比如,正常写一个style指定左边的外边距:margin-left:‘10px’,需要换成:marginLeft: '10px'

let jsx = (
    <>
        

hello world

)

3.绑定class

在jsx中,class属性需要指定为className,因为class在JavaScript中是保留字段

const hasCss = true;
const h1Css = [
    'flex',
    hasCss ? 'css' : 'noCss',
]
let jsx = (
    <>
        

hello world

hello world

)

在vue3+jsx中,jsx文件里面可以用css模块化的方式进行样式导入后绑定。即在vue.config.js文件中css配置项中开启css模块化(requireModuleExtension: true),然后把css文件命名设置成***.module.less

import style from './style.module.less'
let jsx = (
    <>
        

hello world

)
JSX 绑定事件

JSX中绑定事件类似在HTML原生中绑定事件,只不过React中事件命名采用小驼峰(camelCase),而不是纯小写;(Vue3中经过测试也通用)

function fnc(){}
let jsx = (
  <>
     
JSX 条件渲染

在jsx中,不允许使用if、if-else,请使用三元运算符或者逻辑与&&
同样,也允许使用for循环,请使用JS中的高阶函数map、filter……

const t = 'hello world';
const arg1 = 1;
const arg2 = 2;
const hasButton = true;
const list = [1,2,3,4,5,6,7,8,9];
let jsx = (
    

{ t === 'hello world' ? arg1 : arg2 }

{ //如果hasButton为true,则渲染button组件 hasButton &&
)

二、为什么我们要抛弃Vue的优势和各种指令去使用JSX

当出现以下场景,虽然下列写法也能实现想要的效果,但是他不仅冗长,而且我们为每个级别标题重复书写了 。当我们添加锚元素时,我们必须在每个 v-if/v-else-if 分支中再次重复它


Vue.component('anchored-heading', {
  template: '#anchored-heading-template',
  props: {
    level: {
      type: Number,
      required: true
    }
  }
})

这里用模板并不是最好的选择:不但代码冗长,而且在每一个级别的标题中重复书写了 ,在要插入锚点元素时还要再次重复。
虽然模板在大多数组件中都非常好用,但是显然在这里它就不合适了。那么,我们来尝试使用 render 函数重写上面的例子:

Vue.component('anchored-heading', {
  render: function (createElement) {
    return createElement(
      'h' + this.level,   // 标签名称
      this.$slots.default // 子节点数组
    )
  },
  props: {
    level: {
      type: Number,
      required: true
    }
  }
})

三、如何在vue3中使用JSX

vue3中jsx的两种写法

1.在vue3中,可以直接使用render选项编写。

import { defineComponent } from "vue";
export default defineComponent({
  name: "Jsx",
  render() {
    return 
我是一个div
; }, });

2.也可以在setup中返回

import { defineComponent } from "vue";
export default defineComponent({
  name: "Jsx",
  setup() {
    return () => 
我是div
; }, });

在项目目录中新建***.jsx文件;
jsx文件中从vue中导入defineComponent

如何导入JSX导入的组件以及向子组件传值


子组件接收并使用父组件传过来的值
import { defineComponent } from 'vue'
export default defineComponent ({
    props:{
        name:{
            type:String
        }
    },
    setup(props) {
        const render = () =>{
            return (
                
hello {props.name}
); } return render }, })
子组件传值给父组件
import { defineComponent } from 'vue'
export default defineComponent ({
    setup({emit}) {
        let childNode = '不是老王';
        emit('clickMe',childNode )
        const render = () =>{
            return (
                <>
                  请无视我
                
            );
        }
        return render
    },
})
父组件接收子组件传值


vue3+jsx+antd--Demo

import { defineComponent, ref, reactive } from 'vue'
import { Form, Input, Button  } from 'ant-design-vue';
export default defineComponent({
    setup() {
        let formRef = ref();// 绑定表单,对提交时触发表单验证规则
        let formState = reactive({
            name: '',
            password: '',
            type: null // 下拉下选择默认值 设置为null  默认展示placeholder的值 设置为1 展示typeArr  id为1 的 ‘类型1’
        });
        let typeArr = ref([
            {
                id: 1,
                type: '类型1'
            },
            {
                id: 2,
                type: '类型2'
            }
        ]);
        const validatePassword = () => {
            if (formState.password == '123456789') {
                return Promise.reject('密码不能是123456789');
            } else {
                return Promise.resolve();
            }
        };
        let rules = {
            name: [
                {
                    required: true,
                    message: '请输入账号',
                    trigger: 'blur'
                },
            ],
            password: [
                {
                    required: true,
                    message: '请输入密码',
                    trigger: 'change',
                    // 触发方式   ['change', 'blur']  可以这样多种写法
                    // type:'string|array|number' //这是规定了类型  字符串  数组   数字 
                },
                {
                    validator: validatePassword,//自定义规则
                    trigger: 'blur'
                }
            ],
            type: [
                {
                    required: true,
                    message: '请选择类型',
                    trigger: 'blur'
                }
            ]
        };

        const onSubmit = () => {
            // formRef 就是为了这一步  这样点击提交的时候  会触发表单验证 注:绑定formRef时不是{this.formRef}
            console.log(formRef.value)
            formRef.value
                .validate()
                .then(() => {
                    console.log('values', formState);
                    // 表单验证通过就会执行这里  你就可以操作了
                    formRef.value.resetFields(); // 重置表单到初始状态
                })
                .catch((error) => {
                    console.log('error', error);
                });
        }
    
        return {
            formRef,
            formState,
            rules,
            typeArr,
            onSubmit
        }
    },
    render() {
        return (
            <>
                
{/* name 表单域 model 字段,在使用 validate(自定义规则)、resetFields(表单重置) 方法的情况下,该属性是必填的 */} {this.typeArr.map((item) => { return ( {item.type} ); })}
); } })
image.png

你可能感兴趣的:(JSX简介以及在Vue3中使用JSX+antd开发组件)