浅谈vue项目进阶开发-杂谈2

本文详细解析Vue中render函数的作用,演示如何通过render生成DOM并实现条件渲染、组件传递、插槽和props。了解其在选择性渲染和复杂逻辑下的优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.vue中render的使用

 初识render是在项目代码中的main.js文件中看到这样一段代码:

new Vue({
  router,
  store,
  render: h => h(App),
  created() {
    // 保存登录信息到store
    let loginMsg = JSON.parse(localStorage.getItem(K_LOGIN_MSG))
    this.$store.commit(SET_LOGIN_MSG, loginMsg || {})
  }
}).$mount('#app')

当时对于 render: h => h(App)的写法比较懵。只知道他应该是用来生成vue根组件的。然后就去深入了解了下render函数。至于这里为什么这么写,度娘告诉我在这

   render被称之为渲染函数。顾名思义是在js里去渲染html标签的,总结有以下几点:

   a. render方法的实质就是生成template模板; 
   b. 通过调用一个方法来生成,而这个方法是通过render方法的参数传递给它的; 
   c. 这个方法有三个参数,分别提供标签名,标签相关属性,标签内部的html内容 
   d. 通过这三个参数,可以生成一个完整的模板

   为什么要用到render函数呢?

    简单地说就是对于有些需要选择性渲染DOM的,按照原来的方式去做会显得繁琐。对于有些比较复杂条件判断去渲染html,并不适合直接通过模板绑定去写。这时候我们就需要render;


 Vue.component('elem', {
   render: function(createElement) {
     //一个HTML标签字符
     let dom = 'div';
     //一个包含模板相关属性的数据对象
     let attrsObj=  {
                    'class': {
                        foo: true,
                        bar: false
                    },
                    style: {
                        color: 'red',
                        fontSize: '14px'
                    },
                    attrs: {
                        id: 'foo'
                    },
                    domProps: {
                        innerHTML: 'baz'
                    }
                };
     //由createElement函数构建而成的数组 createElement函数返回VNode对象
     let childDom = [createElement('h1', '主标'),createElement('h2', '副标')];
     return createElement(dom,attrsObj,childDom);
   }
 });
 new Vue({
   el: '#app'
 });

这里面createElement接收三个参数,第一个(dom)是一个html标签字符。第二个(attrsObj)是包含模板属性的相关数据对象,第三个(childDom)是当前元素的子元素数组。如何使用呢? 跟组件差不多

  <div id="app">
    <elem></elem>
  </div>

这里用的是JSX语法。

插槽在这也可以用(this.$slots用法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>render</title>
    <script src="https://cdn.bootcss.com/vue/2.3.4/vue.js"></script>
</head>
<body>
    <div id="app">
        <blog-post>
            <h1 slot="header"><span>About Me</span></h1>
            <p>Here's some page content</p>
            <p slot="footer">Copyright 2016 Evan You</p>
            <p>If I have some content down here</p>
        </blog-post>
    </div>
    <script>
        Vue.component('blog-post', {
            render: function(createElement) {
                var header = this.$slots.header,//返回由VNode组成的数组
                    body = this.$slots.default,
                    footer = this.$slots.footer;
                return createElement('div', [
                    createElement('header', header),
                    createElement('main', body),
                    createElement('footer', footer)
                ])
            }
        });
        new Vue({
            el: '#app'
        });
    </script>
</body>
</html>

props传递数据

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>render</title>
    <script src="https://cdn.bootcss.com/vue/2.3.4/vue.js"></script>
</head>
<body>
    <div id="app">
        <ele :show="show"></ele>
        <ele :show="!show"></ele>
    </div>
    <script>
        Vue.component('ele', {
            render: function(createElement) {
                if (this.show) {
                    return createElement('p', 'true');
                } else {
                    return createElement('p', 'false');
                }
            },
            props: {
                show: {
                    type: Boolean,
                    default: false
                }
            }
        });
        new Vue({
            el: '#app',
            data: {
                show: false
            }
        });
    </script>
</body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值