前端笔记之vue3 之 render函数和createVNode函数使用

这篇具有很好参考价值的文章主要介绍了前端笔记之vue3 之 render函数和createVNode函数使用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

初学vue3的时候倒是扒了一点点源码,似是而非,而且一直做的工作都是很简单的功能,怎么说呢,ui框架也几乎让我很容易的就可以写出一个成型的页面,有时就忘了初学的时候的一些心得。
本内容只说createVNode函数的用法,不做源码探究

1.简单使用-创建一个组件

<template>
<RenderTest></RenderTest>
</template>
<script setup>
import { defineComponent, createVNode } from "vue";

const RenderTest = defineComponent({
  render(){
  // 参数1:元素名字符串; 参数2:元素属性; 元素子节点,支持createVNode嵌套
    return createVNode("div", {class: "text"}, "render-text")
  }
});
</script>

效果图:
前端笔记之vue3 之 render函数和createVNode函数使用

2.简单使用-渲染组件

虽然在日常中这么写特别鸡肋,甚至有些傻逼,但是别急,慢慢来。
先写一个简单要引用的子组件

<template>
  <div>{{title}}</div>
</template>

<script setup lang="ts" name="SimpleTemplate">
import {defineProps} from "vue";
defineProps<{title: string}>();
</script>

父组件

<template>
  <SimpleTemplateCopy />
</template>

<script setup>
import { defineComponent, createVNode } from "vue";
import SimpleTemplate from "./SimpleTemplate/index.vue";

const SimpleTemplateCopy = defineComponent({
  render(){
    return createVNode(SimpleTemplate, {title: "twoB"})
  }
})
</script>

3.日常使用-我用到它们的地方

element-plus说实话很不错,但是太常使用它有些审美疲劳,但是它的一些组件确实很好用,特别是那些提示弹窗之类,发现了吗,它们都是在函数去调用的,那么如何在纯js中去使用一个已经封装好了的组件呢?反正我是用它们。
简单的实现一下吧。
手写先写一个confirm的组件

<template>
<div class="small-window">
  <div class="upper-tip">
    <span>{{ title }}</span>
  </div>
  <div class="message-content">
    {{ message }}
  </div>
  <div class="button-area">

    <div class="my-button" style="background-color: #11a9ea" @click="submitCallBack">{{ submitText }}</div>
    <div class="my-button" style="background-color: #cecece" @click="cancelCallBack">{{ cancelText }}</div>
  </div>
</div>
</template>

<script setup lang="ts" name="Confirm">
import {defineProps} from "vue";
defineProps<{
  title: {type: string, default: "提示"},
  message: string,
  submitText: string,
  cancelText: string,
  cancelCallBack: () => void,
  submitCallBack: () => void,

}>()
</script>

<style scoped lang="less">
.small-window{
  width: 500px;
  height: 350px;
  background-color: white;
  border: 1px solid rgba(169, 169, 169, 0.92);
  border-radius: 15px;
  display: flex;
  flex-direction: column;

  .upper-tip{
    font-size: 18px;
    height: 45px;
    width: 100%;
    font-weight: 700;
  }
  .message-content{
    width: calc(100% - 40px);
    padding: 15px 20px 15px 20px;
    height: 150px;
    text-indent: 32px;
    display: flex;
    justify-content: center;
    font-size: 16px;
  }
  .button-area{
    display: flex;
    justify-content: end;
    width: calc(100% - 40px);
    padding: 15px 20px 15px 20px;

    .my-button{
      width: 68px;
      margin-left: 20px;
      height: 50px;
      cursor: pointer;
    }
  }
}
</style>

然后给这个组件找个挂载点以及render到dom上

import {createVNode, render} from "vue";
import Confirm from "./Confirm.vue";


export default ({title, message, submitText, cancelText}) => {

    const mask = document.createElement('div');
   	mask.setAttribute('style', 'position: fixed; background-color: rgba(0, 0, 0, 0.5); width: 100vw; height: 100%; display: flex; justify-content: center; align-items: center');
	mask.setAttribute('key', Date.now().toString());
    document.body.appendChild(mask);
    return new Promise((reslove, reject) => {

        // 封装组件属性方法
        const submitCallBack = () => {
            console.log(456)
            //调用完毕后应该清空节点
            render(null, mask)
            mask.remove();
            reslove(true)
        }

        // 封装组件属性方法
        const cancelCallBack= () => {
            console.log(456)
            //清空节点
            render(null, mask);
            mask.remove();
            reject()
        };

        // 在此处才创建节点并挂载属性
        const VNode = createVNode(Confirm, {
            title,
            message,
            submitText,
            cancelText,
            cancelCallBack,
            submitCallBack
        })
        render(VNode, mask);
    });
};

然后使用它

<template>

  <button @click="openMyConfirm">12313213</button>
</template>

<script setup>


import myConfirm from "./Confirm/index.js"


const openMyConfirm = () => {
  myConfirm({title: "提示", message: "你好呀", submitText: "你好", cancelText: "我不好"}).then(() => {
    console.log('点击确认事件处理')
  }).catch(e => {
    console.log('点击取消事件处理')
  })
}
</script>

效果图:很丑,但是起码他是个成熟的confirm了
前端笔记之vue3 之 render函数和createVNode函数使用

4.生产中的正常使用

贴一个简单的tsx的代码,说实话tsx搭配createVNode简直舒服极了文章来源地址https://www.toymoban.com/news/detail-469576.html

import {createVNode, defineComponent, render} from "vue";
import styles from "./errordatacord.module.less";
interface A {
  unusualField: string,
  resultValue: string,
  healthRecordNo: string,
  name: string,
}
interface Prop extends A{
  cancelCallBack: () => void
}

const errorDataCord = defineComponent<Prop>({
  name: "ErrorDataCord",
  setup(props, {attrs}){
    return ()=> <>
      <div class={styles["error-data-cord"]}>
        <div class={styles["upper-sidebar"]}>
          <span>异常结果值</span>
          <div
            class={styles["close-icon"]}
            onClick = { attrs.cancelCallBack as () => void }
          >×</div>
        </div>
        <div class={styles["main-content"]}>
          <div>
            <span>异常字段:{attrs.unusualField}</span>
            <span>异常结果值:{attrs.resultValue}</span>
          </div>
          <div>
            <svg viewBox="0 0 1024 1024" version="1.1"
                 xmlns="http://www.w3.org/2000/svg" p-id="1486" width="48" height="48">
              <path
                d="M511.903244 0.000096a511.903244 511.903244 0 0 1 335.957502 898.350359l-9.598786 8.638907A511.999232 511.999232 0 1 1 511.903244 0.000096z m0 742.274102A281.436398 281.436398 0 0 0 272.605515 875.409357a433.289189 433.289189 0 0 0 225.283502 71.510954h14.014227a433.097213 433.097213 0 0 0 239.393717-71.510954 281.628374 281.628374 0 0 0-239.393717-133.135159z m0-665.483816a435.112958 435.112958 0 0 0-299.674091 750.625046 358.322672 358.322672 0 0 1 599.44417 0A435.112958 435.112958 0 0 0 511.903244 76.790382z m0 127.951814A204.838088 204.838088 0 1 1 307.161144 409.484296a204.7421 204.7421 0 0 1 204.7421-204.7421z m0 76.790286a128.047802 128.047802 0 0 0 0 255.999616 128.047802 128.047802 0 0 0 0-255.999616z"
                p-id="1487" fill="#cdcdcd"></path>
            </svg>
            <span>{attrs.name}</span>
            <span>{attrs.healthRecordNo}</span>
          </div>
        </div>
      </div>
    </>;
  }
});

export default (option: A, htmlElement: HTMLElement) => {
  return new Promise((resolve) => {
    const cancelCallBack = () => {
      render(null, htmlElement);
    };
    const VNode = createVNode(errorDataCord,  {
      ...option,
      cancelCallBack
    });
    render(VNode, htmlElement);
    resolve(true);
  });
};

到了这里,关于前端笔记之vue3 之 render函数和createVNode函数使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 前端学习笔记(14)-Vue3组件传参

    1.props(父组件传递给子组件) 1.1 实现 如果你没有使用 script setup,props 必须以 props 选项的方式声明,props 对象会作为 setup() 函数的第一个参数被传入: 在子组件中: 在父组件中: 一个组件可以有任意多的 props,默认情况下,所有 prop 都接受任意类型的值。 这种情况下,我

    2024年01月21日
    浏览(53)
  • vue中的render函数、h()函数、函数式组件

    官网:用于编程式地创建组件虚拟 DOM 树的函数。 在我们使用webpack脚手架创建项目时,都能在main.js中看到一个render函数 对于render函数 es6中写成了箭头函数  es5写法: 实际上createElement只是形参用h代表了, h()  是  hyperscript  的简称——意思是“能生成 HTML (超文本标记语言

    2024年02月08日
    浏览(33)
  • Vue3之ref取render形式组件jsx元素节点

    [2023 年 7 月 28 日 22:16:06] 一开始注意到组件 setup 和 render 一起使用的情况,好奇怎么通过 ref 取到 render 中 jsx 里的节点,一开始试了以下的尝试,结果是 undefined 的: 后来经过大佬指点,改成以下形式: render 这一步就很像 react 里 jsx 的写法了,react 里也有回调 ref,都是一样

    2024年02月15日
    浏览(44)
  • Vue.js 2.0 Render 函数

    Vue 推荐使用在绝大多数情况下使用 template 来创建你的 HTML。然而在一些场景中,你真的需要 JavaScript 的完全编程的能力,这就是  render 函数 ,它比 template 更接近编译器。 让我们先深入一个使用 render 函数的简单例子,假设你想生成一个带锚链接的标题: 在 HTML 层, 我们

    2023年04月16日
    浏览(43)
  • vue3传属性时报错 [Vue warn]: Component is missing template or render function.

    上网查这个问题,解决方案很多,没有一款适合我。。。先说我的解决办法,如果解决不了再往下看,我的原因是 用的子组件的ref和子组件的标签名一样了: 给 ref 改个名字就好了 。。。 使用技术: vue3+ts 用的props传值,本来都好好的,后来发现给一个子组件传值发生变化

    2024年02月14日
    浏览(37)
  • 前端笔记(11) Vue3 Router 编程式导航 router.push router.replace

    在上篇博客Vue3 Router 监听路由参数变化中,我们使用 router-link 创建 a 标签来定义导航链接: 除了 router-link ,我们还可以借助 router 的实例方法,通过编写代码来实现: router.push 方法会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,会回到之前的 URL。

    2024年02月07日
    浏览(56)
  • VUE3 函数的声明和使用

    在了解了响应式数据如何使用之后,接下来就要开始了解函数了。 在 Vue 2 ,函数通常是作为当前组件实例上的方法在 methods 里声明,然后再在 mounted 等生命周期里调用,或者是在模板里通过 Click 等行为触发,由于组件内部经常需要使用 this 获取组件实例,因此不能使用箭头

    2024年02月16日
    浏览(30)
  • 前端插件库之vue3使用vue-codemirror插件

    基于 CodeMirror ,适用于 Vue 的 Web 代码编辑器。 1.命令行安装 如果运行官网例子时, 报错: 可以在终端中安装对应文件, 解决问题 2.在需要的组件中配置 代码编辑区 支持代码编辑区, 满足白天/黑夜主题切换, 满足c++/python语言切换 不足, 没有满足代码提示 组件代码 vue3 新手作品

    2024年02月04日
    浏览(49)
  • 前端新手Vue3+Vite+Ts+Pinia+Sass项目指北系列文章 —— 第十二章 常用工具函数 (Utils配置)

    在项目开发中,我们经常会使用一些工具函数,也经常会用到例如 loadsh 等工具库,但是这些工具库的体积往往比较大,如果项目本身已经引入了这些工具库,那么我们就没有必要再引入一次,所以我们需要自己封装一些工具函数,来简化我们的开发。 在 src/utils 目录下创建

    2024年02月20日
    浏览(61)
  • Vue3 Hooks函数使用及封装思想

    目录 一. 什么是hooks函数? 二、如何封装一个hooks函数 三、Hooks 常用 Demo (1)验证码倒计时 (2)防抖 (3)节流 专业解释:Vue 3中的Hooks函数是一种用于在组件中共享可复用逻辑的方式。 大白话:将单独功能的js代码抽离出来, 加工成公共函数,从而达到逻辑复用。 在尤大

    2024年02月11日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包