Vue学习记录之二十一 Vue3中3种编程风格介绍

在Vue3中,我们一般使用template、tsx、函数式组件(h函数)

一、template风格

html 复制代码
<template>
    <div class="lmb">lvmanba</div>
</template>
<script setup lang='ts'>
import { ref,reactive } from 'vue'
</script>
<style scoped>

</style>

二、tsx风格

需要在vite+vue构建的时候选择支持jsx,或者自行安装。

详见 https://blog.csdn.net/LvManBa/article/details/142926978

ts 复制代码
<script lang="tsx">
import { defineComponent, defineProps } from "vue"
const childAbc = () => {
  return (<div>childAbc</div>)
}
const childCbd = (props, ctx) => {
  console.log(props, ctx, "childCbd")
  const { emit } = ctx;
  setTimeout(() => {
    //emit事件给父组件
    emit('listen', 8888)
  }, 2000);
  return (
    <>
      <div>childCbd</div>
      <div>mytime</div>
      <div>{props.msg}</div>
    </>
  )
}

export default defineComponent({
  name: "ChildWorld",
  setup(props, ctx) {
    const todo = (val) => {
      console.log(val, "todo")
    }
    return () => (<div>Hello World
      <childAbc />
      事件加onSomeThing,这里的on代表监听子组件事件,子组件需要去掉on来emit事件
      <childCbd msg="abc" onListen={todo} />
      < /div>);
  }
})
</script>

三、函数式组件(h函数)

在使用页面通过导入h函数,用于创建虚拟 DOM 节点。vue3中很少使用h函数。

ts 复制代码
import {ref,reactive,h} from 'vue'

h函数的本质是对createVnode进行了封装,优势是跳过了模版的编译。

总结流程

1、模板解析(Parser):Vue 的模板被解析为 AST 树结构。

2、AST 优化:静态节点和动态节点的标记优化,减少不必要的渲染。

3、代码生成:将 AST 转换为渲染函数,这个函数通过调用 h 函数来创建虚拟 DOM。

4、渲染函数执行:渲染函数执行时,h 函数会生成虚拟 DOM 树(VNode)。

5、VNode -> 真实 DOM:虚拟 DOM 树被 diff 和 patch,更新为真实的 DOM。

h 函数在这个流程中主要作用是:将 AST 转换为渲染函数,渲染函数调用 h 函数生成虚拟 DOM 树,最后虚拟 DOM 树通过 diff 算法转换为真实 DOM。

使用h函数

以下是 h 函数在 Vue 3 中的执行流程的大致步骤:

参数接收: h 函数通常接收三个参数:

第一个参数是标签名或组件(创建节点)

第二个参数是属性对象(节点属性 )。

第三个参数是子节点或文本(节点内容)。

shell 复制代码
h('div', { class: 'container' }, 'Hello World')

如果只传递了一个参数,且该参数为字符串或组件,则默认没有属性和子节点。

如果只传递了两个参数,需要判断第二个参数是属性对象还是子节点。

如果传递了三个参数,则分别对应标签、属性和子节点。

ts 复制代码
function h(type, propsOrChildren, children) {
  const l = arguments.length
  if (l === 2) {
    // 如果第二个参数是数组或字符串,视为子节点
    if (isArray(propsOrChildren) || isVNode(propsOrChildren)) {
      return createVNode(type, null, propsOrChildren)
    }
    // 如果第二个参数是对象,视为属性
    if (isObject(propsOrChildren)) {
      return createVNode(type, propsOrChildren, null)
    }
  } else {
    // 三个参数分别为类型、属性和子节点
    return createVNode(type, propsOrChildren, children)
  }
}

一般使用的场景为 按钮或者弹出框

按钮实例

html 复制代码
<template>
    <table border>
        <tr>
        <th>name</th>
        <th>age</th>
        <th>address</th>
        <th>操作</th>
        </tr>
        <tr v-for="item in list" :key="item.id">
            <td>{{ item.name }}</td>
            <td>{{ item.age}}</td>
            <td>{{ item.address}}</td>
            <td>
                <Btn type="success" :id="item.id">编辑</Btn>
                <Btn type="error" :id="item.id">删除</Btn>
            </td>
        </tr>
    </table>
</template>
<script setup lang='ts'>
import { ref,reactive,h } from 'vue'
import WelcomeItem from './components/WelcomeItem.vue';
let list = reactive([
    {id:1,name:'lmb1',age:21,address:'jilin'},
    {id:2,name:'lmb2',age:22,address:'jilin'},
    {id:3,name:'lmb3',age:23,address:'jilin'},
    {id:4,name:'lmb4',age:24,address:'jilin'},
    {id:5,name:'lmb5',age:25,address:'jilin'},
    {id:6,name:'lmb6',age:26,address:'jilin'},
    {id:7,name:'lmb7',age:27,address:'jilin'},
    {id:8,name:'lmb8',age:28,address:'jilin'},
])
interface Props{
    type: 'success'|'error'|'warning'
    id: number
}
const Btn = (props:Props,ctx:any) =>{
    return h('button',
    {
        style:{
            color:props.type ==='success'?'green':'red'
        },
        onClick:()=>{
            //ctx.emit('click',123123)
            if(props.type == 'success'){
                console.log('编辑'+props.id)
            }else{
                console.log('删除'+props.id)
            }
            //console.log('click',props.id)
        }
    }, ctx.slots.default())
}
</script>
相关推荐
BD_Marathon11 分钟前
关于JS和TS选择的问题
开发语言·javascript·ecmascript
dly_blog17 分钟前
Vite 原理与 Vue 项目实践
前端·javascript·vue.js
重生之我在番茄自学网安拯救世界23 分钟前
网络安全中级阶段学习笔记(九):upload靶场实战(14-16关)-图片马制作与通过教学
笔记·学习·网络安全·文件上传漏洞·图片木马
计算机毕设VX:Fegn089532 分钟前
计算机毕业设计|基于springboot + vue汽车销售系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·汽车·课程设计
仅此,33 分钟前
前端接收了id字段,发送给后端就变了
java·前端·javascript·spring·typescript
RanceGru33 分钟前
LLM学习笔记7——unsloth微调Qwen3-4B模型与vllm部署测试
人工智能·笔记·学习·语言模型·vllm
deng-c-f35 分钟前
Linux C/C++ 学习日记(57):定时器
学习
樱桃园园长38 分钟前
【Three.js 实战】手势控制 3D 奢华圣诞树 —— 从粒子系统到交互实现
javascript·3d·交互
楠了个难42 分钟前
安服优-B-1 人体红外测温传感器——ZYNQ学习笔记23
笔记·学习
二狗哈1 小时前
Cesium快速入门30:CMZL动画
javascript·3d·webgl·cesium·地图可视化