render函数

news2025/2/27 5:35:49

render函数

通常我们都会把我们的页面结构逻辑都写在 template 中,然后再通过vue将我们的代码转换成虚拟DOM,相比于真实DOM,虚拟DOM是通过js代码处理的,所以消耗的性能相对较小,当然大部分情况下使用 template 创建我们的HTML是可以的,但是在有些场景下,我们真的需要通Javascript的完全编程的能力来完成时,就可以用到 render函数,比之 template 更接近编译器

render函数的作用就是返回一个虚拟dom,将该虚拟dom渲染成真实的dom。

render函数的参数

render函数即渲染函数,它是个函数,render返回的参数是Vnode(即虚拟节点,也就是我们要渲染的节点)

createElement是render函数返回的参数,它本身也是一个函数,并且有3个参数:

第一个参数(必填):可以为String|Object|Function

  • String:表示的是HTML 标签名;
  • Object :一个含有数据的组件选项对象;
  • Function :返回了一个含有标签名或者组件选项对象的async函数。

第二个参数(选填):可为Class|Style|attrs|domProps|on

  • class:控制类名;
  • style :样式;
  • attrs :用来写正常的 html 属性 id src 等;
  • domProps :用来写原生的dom 属性;
  • on:用来写原生方法;

第三个参数(选填):代表子级虚拟节点,由 createElement() 构建而成,正常来讲接收的是一个字符串或者一个数组,一般数组用的是比较多的

参数二详细参数

            {
                // 与 `v-bind:class` 的 API 相同,
                // 接受一个字符串、对象或字符串和对象组成的数组
                'class': {
                    foo: true,
                    bar: false
                },
                // 与 `v-bind:style` 的 API 相同,
                // 接受一个字符串、对象,或对象组成的数组
                style: {
                    color: 'red',
                    fontSize: '14px'
                },
                // 普通的 HTML attribute
                attrs: {
                    id: 'foo'
                },
                // 组件 prop
                props: {
                    myProp: 'bar'
                },
                // DOM property
                domProps: {
                    innerHTML: 'baz'
                },
                // 事件监听器在 `on` 内,
                // 但不再支持如 `v-on:keyup.enter` 这样的修饰器。
                // 需要在处理函数中手动检查 keyCode。
                on: {
                    click: this.clickHandler
                },
                // 仅用于组件,用于监听原生事件,而不是组件内部使用
                // `vm.$emit` 触发的事件。
                nativeOn: {
                    click: this.nativeClickHandler
                },
                // 自定义指令。注意,你无法对 `binding` 中的 `oldValue`
                // 赋值,因为 Vue 已经自动为你进行了同步。
                directives: [
                    {
                        name: 'my-custom-directive',
                        value: '2',
                        expression: '1 + 1',
                        arg: 'foo',
                        modifiers: {
                            bar: true
                        }
                    }
                ],
                // 作用域插槽的格式为
                // { name: props => VNode | Array<VNode> }
                scopedSlots: {
                    default: props => createElement('span', props.text)
                },
                // 如果组件是其它组件的子组件,需为插槽指定名称
                slot: 'name-of-slot',
                // 其它特殊顶层 property
                key: 'myKey',
                ref: 'myRef',
                // 如果你在渲染函数中给多个元素都应用了相同的 ref 名,
                // 那么 `$refs.myRef` 会变成一个数组。
                refInFor: true
            }

示例

父组件

<template>
        <div class="container">
                <AnchoredHeading :level="2">222</AnchoredHeading>
        </div>
</template>
    <script>
    import AnchoredHeading from "./test_add";
    export default {
        name: "RenderDemo",
        components: {
            AnchoredHeading
        },
        data () {
            return {};
        },
        methods: {},
    };
    </script>
<style scoped>

</style>

子组件

<script>
export default {
    name: "AnchoredHeading",
    render: function (createElement, context) {
        return createElement(
            "h" + this.level, // 标签名称
            this.$slots.default // 子节点数组
        );
    },
    props: {
        level: {
            type: Number,
            required: true
        }
    }
};
</script>

最终效果

注意:template和render不能一起使用,否则无效

v-if和v-for

只要是在原生的JavaScript中可以轻松完成的操作,Vue渲染函数就不会提供专有的代替方法,比如在模板中使用的v-if和v-for。

        <ul v-if="level.length">
            <li v-for="item in level">{{ item.name }}</li>
        </ul>

这些都可以在渲染函数中用 JavaScript 的 if/else 和 map 来重写:

子组件:

<script>
export default {
    props: ["level", "title"],
    render (h) {
        console.log("this.$slots.default :>> ", this.$slots.default);
        if (this.level.length) {
            return h("ul", this.level.map((item) => {
                return h("li", item.name)
            }));
        } else {
            return h("p", "这是p元素")
        }

    },

};
</script>

父组件:

<template>
    <div>
        <heading :level="level">
            {{ title }}
        </heading>
    </div>
</template>
  
<script>
import Heading from "./test_add.vue";
export default {
    components: { Heading },
    data () {
        return {
            level: [
                { name: '这是li' },
                { name: '这是li' },
                { name: '这是li' },
                { name: '这是li' },
                { name: '这是li' },
                { name: '这是li' },
                { name: '这是li' },
                { name: '这是li' },
            ],
        };
    },
};
</script>

最终效果:

事件 & 按键修饰符

对于 .passive、.capture 和 .once 这些事件修饰符,Vue 提供了相应的前缀可以用于 on:

修饰符

前缀

.passive

&

.capture

!

.once

~

.capture.once 
.once.capture

~!

on: {
        '!click': this.doThisInCapturingMode,
        '~keyup': this.doThisOnce,
        '~!mouseover': this.doThisOnceInCapturingMode
     }

这里是一个使用所有修饰符的例子:

                on: {
                    keyup: function (event) {
                        // 如果触发事件的元素不是事件绑定的元素
                        // 则返回
                        if (event.target !== event.currentTarget) return
                        // 如果按下去的不是 enter 键或者
                        // 没有同时按下 shift 键
                        // 则返回
                        if (!event.shiftKey || event.keyCode !== 13) return
                        // 阻止 事件冒泡
                        event.stopPropagation()
                        // 阻止该元素默认的 keyup 事件
                        event.preventDefault()
                        // ...
                    }
                }

插槽

你可以通过 this.$slots 访问静态插槽的内容,每个插槽都是一个 VNode 数组:

                render: function (createElement) {
                    // `<div><slot></slot></div>`
                    return createElement('div', this.$slots.default)
                }

也可以通过 this.$scopedSlots 访问作用域插槽,每个作用域插槽都是一个返回若干 VNode 的函数:

                props: ['message'],
                render: function (createElement) {
                    // `<div><slot :text="message"></slot></div>`
                    return createElement('div', [
                        this.$scopedSlots.default({
                            text: this.message
                        })
                    ])
                }

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

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

相关文章

(详解)Vue设置select下拉框的默认选项(解决select空白的bug)

最近在用vue设置表单数据时发现了一个小问题&#xff1a;用vue动态渲染select下拉框时&#xff0c;select下拉框会出现空白的bug。 <template><div><select name"art-cate" v-model"select"><option disabled selected style"d…

Vue项目启动出现的问题及解决方法

今天在公司入职第二天&#xff0c;昨天拉下来的代码没有跑起来&#xff0c;看了各种博客也没有解决这个报错 今天一大早来公司&#xff0c;捋了一下顺序 ①删除要启动项目里的 node_modules 文件夹&#xff0c;这是vue项目的依赖包。 因为“node_modules”文件夹太大&#x…

《Vue插件》瀑布流插件vue-masonry的使用与踩坑记录

这是一个没有套路的前端博主&#xff0c;热衷各种前端向的骚操作&#xff0c;经常想到哪就写到哪&#xff0c;如果有感兴趣的技术和前端效果可以留言&#xff5e;博主看到后会去代替大家踩坑的&#xff5e; 主页: oliver尹的主页 格言: 跌倒了爬起来就好&#xff5e; 《Vue插件…

Moment.js的基本使用

一、Moment.js的简介 Moment.js是一个轻量级的JavaScript时间库&#xff0c;以前我们转化时间&#xff0c;都会进行很复杂的操作&#xff0c;而Moment.js的出现&#xff0c;简化了我们开发中对时间的处理&#xff0c;提高了开发效率。日常开发中&#xff0c;通常会对时间进行下…

React面试题最全

1.什么是虚拟DOM&#xff1f; 虚拟DOM是真实DOM在内存中的表示&#xff0c;ul的表示形式保存在内存中&#xff0c;并且与实际的DOM同步&#xff0c;这是一个发生在渲染函数被调用和元素在屏幕上显示的步骤&#xff0c;整个过程被称为调和 2.类组件和函数组件之间的区别是什么…

【uni-app】小程序实现微信在线聊天(私聊/群聊)

之前学习使用uni-app简单实现一个在线聊天的功能&#xff0c;今天记录一下项目核心功能的实现过程。页面UI以及功能逻辑全部来源于微信&#xff0c;即时聊天业务的实现使用socket.io&#xff0c;前端使用uni-app开发&#xff0c;后端服务器基于node实现&#xff0c;数据库选择m…

vue3生命周期及setup介绍

&#x1f337; 生命周期 下图对比了vue3&#xff08;左&#xff09;和vue2&#xff08;右&#xff09;的生命周期&#xff1a;vue3将destoryed该名成了unmounted&#xff0c;相应的beforeDestory改成了beforeUnmounted。除此之外在组合式API中新增了个钩子函数&#xff1a;set…

vue项目:大屏自适应解决方案(两种)

css缩放方案&#xff1a; 利用transform&#xff1a;scale 进行适配 推荐使用v-scale-screen 值得注意的是&#xff1a; vue 2.6、2.7 要使用 npm install v-scale-screen1.0.2 vue3&#xff1a;要使用v-scale-screen版本 npm install v-scale-screen2.0.0 用法&#x…

解决npm ERR! Cannot read properties of null (reading ‘pickAlgorithm‘)

文章目录1. 复现问题2. 分析问题3. 解决问题1. 复现问题 今天准备克隆Redis桌面(GUI)管理客户端&#xff0c;故按照官方文档给出的指令运行时&#xff0c;如下图所示&#xff1a; 但在执行指令npm install --platformwin32却报出如下图错误&#xff1a; PS D:\Software\Redis…

Vue中使用Datav 完成大屏基本布局

效果图 大屏前言 在实际开发过程中&#xff0c;我们经常需要一个大屏进行一些常规数据的展示。在Vue中也是提供了这样的容器组件 我们可以使用基于Vue的 Datav组件 Vue-Baidu-Map地图组件 Echarts图表组件 时间戳就实现基本布局 在Vue中配置大屏路由的时候&#xff0c;我们…

vue播放rtsp视频流

工作有要播放视频监控的需求&#xff0c;最近就自己先了解了一下网页播放rtsp视频流的方法&#xff0c;以下是我的个人经验。 最终选择了vuewebrtc-streamer实现在网页播放rtsp流这种方法进行测试。 个人经验 第一次尝试了vue-video-playervideojs的方法&#xff0c;发现只适…

WPS JS宏入门案例集锦

JS宏官方API文档&#xff1a;https://qn.cache.wpscdn.cn/encs/doc/office_v19/index.htm 批量创建工作表/簿 批量创建工作表&#xff1a; function 批量创建工作表(){for (var city of ["成都","上海","北京"]){let sht Worksheets.Add();s…

无需本地部署 在线使用Stable Diffusion Webui 使用共享模型

尝试本地部署Stable Diffusion的时候遇到了很多的麻烦&#xff0c;自己训练AI也非常的麻烦&#xff0c;可以尝试使用Webui使用别人上传的模型第一步进入网站https://github.com/camenduru/stable-diffusion-webui-colab向下拉到readme第一个 stable_diffusion_webui_colab&…

前端常见八大设计模式

一、设计模式是什么&#xff1f; 设计模式是在某种场合下对某个问题的一种解决方案。设计模式是通过概念总结出来的模版&#xff0c;总结出来的固定的东西。每一个模式描述了一个在我们周围不断重复发生的问题&#xff0c;以及该问题的解决方案的核心。 二、设计原则–设计模…

给女友的网页小惊喜,(生日,周年,表白通用) ☞谁说程序员不懂浪漫

有女朋友的拿去给女朋友一个惊喜&#xff0c;没女朋友的拿去表白&#xff0c;或者NEW它10000000个&#xfeff;ε≡٩(๑>₃<)۶ 文章目录前言适用范围网页展示登录界面文字界面图片界面尾部界面获取源码前言 前些日子是女友的一周年&#xff0c;康康想用一种特殊的方式…

vue实现导出word文档(含多张图片)

一、实现效果 以填写并导出房屋出租审批表为例&#xff0c;首先填写表格相应内容后&#xff0c;点击" 导出 "按钮实现word文档的导出功能&#xff0c;界面如下所示&#xff1a; 最后导出word文档如下所示&#xff1a; 二、所需插件 这里使用npm对以下所需依赖进…

【SpringBoot+Vue】全网最简单但实用的前后端分离项目实战笔记 - 前端

配套视频地址&#xff1a;https://www.bilibili.com/video/BV1dG4y1T7yp/ 前端笔记 1. node环境 官网&#xff1a;https://nodejs.org 注意&#xff0c;node可以比我稍低&#xff0c;但不要更高 2. 下载vue-admin-template https://panjiachen.gitee.io/vue-element-admin…

HTML表格合并行和列

HTML表格合并行和列1.合并行&#xff1a;rowspan2.合并列&#xff1a;colspan1.合并行&#xff1a;rowspan 在设计表格时&#xff0c;有时我们需要将“横向的N个单元格”或者“纵向的N个单元格”合并成一个单元格&#xff08;类似Word的表格合并&#xff09;&#xff0c;这个时…

2023前端最新高频面试题总结(附答案)

目录 1.vue双向数据绑定的原理&#xff1f; 2.vue的生命周期有哪些 3.v-if 和v-show有什么区别&#xff1f; 4.async await 是什么&#xff1f;它有哪些作用&#xff1f; 5、数组常用的方法&#xff1f;哪些方法会改变原数组&#xff0c;哪些不会 6.什么是原型链&#xf…

前端网页设计必逛的六个宝藏网站(非常值得收藏)

&#x1f389;个人主页&#xff1a;这个昵称我想了20分钟 ✨往期专栏&#xff1a; 【速成之路】jQuery 【SQL server速成之路】 素材网站✨iconfont阿里巴巴矢量图标库  ✨美叶  ✨IconPark  ✨pexels  ✨COLOR  ✨Uigradients✨iconfont阿里巴巴矢量图标库 网站入口…