zoukankan      html  css  js  c++  java
  • 如何理解Vue的render函数

    第一个参数(必须) - {String | Object | Function}

    <!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">
            <elem></elem>
        </div>
        <script>
            Vue.component('elem', {
                render: function(createElement) {
                    return createElement('div');//一个HTML标签字符
                    /*return createElement({
                        template: '<div></div>'//组件选项对象
                    });*/
                    /*var func = function() {
                        return {template: '<div></div>'}
                    };
                    return createElement(func());//一个返回HTML标签字符或组件选项对象的函数*/
                }
            });
            new Vue({
                el: '#app'
            });
        </script>
    </body>
    </html>
    View Code

     第二个参数(可选) - {Object}

    <!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">
            <elem></elem>
        </div>
        <script>
            Vue.component('elem', {
                render: function(createElement) {
                    var self = this;
                    return createElement('div', {//一个包含模板相关属性的数据对象
                        'class': {
                            foo: true,
                            bar: false
                        },
                        style: {
                            color: 'red',
                            fontSize: '14px'
                        },
                        attrs: {
                            id: 'foo'
                        },
                        domProps: {
                            innerHTML: 'baz'
                        }
                    });
                }
            });
            new Vue({
                el: '#app'
            });
        </script>
    </body>
    </html>
    View Code

    第三个参数(可选) - {String | Array}

    <!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">
            <elem></elem>
        </div>
        <script>
            Vue.component('elem', {
                render: function(createElement) {
                    var self = this;
                    // return createElement('div', '文本');//使用字符串生成文本节点
                    return createElement('div', [//由createElement函数构建而成的数组
                        createElement('h1', '主标'),//createElement函数返回VNode对象
                        createElement('h2', '副标')
                    ]);
                }
            });
            new Vue({
                el: '#app'
            });
        </script>
    </body>
    </html>
    View Code

    两种组件写法对比

    <!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></ele>
        </div>
        <script>
            /*Vue.component('ele', {
                template: '<div id="elem" :class="{show: show}" @click="handleClick">文本</div>',
                data: function() {
                    return {
                        show: true
                    }
                },
                methods: {
                    handleClick: function() {
                        console.log('clicked!');
                    }
                }
            });*/
            Vue.component('ele', {
                render: function(createElement) {
                    return createElement('div', {
                        'class': {
                            show: this.show
                        },
                        attrs: {
                            id: 'elem'
                        },
                        on: {
                            click: this.handleClick
                        }
                    }, '文本');
                },
                data: function() {
                    return {
                        show: true
                    }
                },
                methods: {
                    handleClick: function() {
                        console.log('clicked!');
                    }
                }
            });
            new Vue({
                el: '#app'
            });
        </script>
    </body>
    </html>
    View Code

    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>
    View Code

    使用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>
    View Code

    VNodes必须唯一

    <!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>
        <!-- VNode必须唯一 -->
        <div id="app">
            <ele></ele>
        </div>
        <script>
            var child = {
                render: function(createElement) {
                    return createElement('p', 'text');
                }
            };
            /*Vue.component('ele', {
                render: function(createElement) {
                    var childNode = createElement(child);
                    return createElement('div', [
                        childNode, childNode//VNodes必须唯一,渲染失败
                    ]);
                }
            });*/
            Vue.component('ele', {
                render: function(createElement) {
                    return createElement('div', 
                        Array.apply(null, {
                            length: 2
                        }).map(function() {
                            return createElement(child)//正确写法
                        })
                    );
                }
            });
            new Vue({
                el: '#app'
            })
        </script>
    </body>
    </html>
    View Code

    v-model指令

    <!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">
            <el-input :name="name" @input="val=>name=val"></el-input>
            <div>你的名字是{{name}}</div>
        </div>
        <script>
            Vue.component('el-input', {
                render: function(createElement) {
                    var self = this;
                    return createElement('input', {
                        domProps: {
                            value: self.name
                        },
                        on: {
                            input: function(event) {
                                self.$emit('input', event.target.value);
                            }
                        }
                    })
                },
                props: {
                    name: String
                }
            });
            new Vue({
                el: '#app',
                data: {
                    name: 'hdl'
                }
            });
        </script>
    </body>
    </html>
    View Code

    作用域插槽

    <!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>
                <template scope="props">
                    <span>{{props.text}}</span>
                </template>
            </ele>
        </div>
        <script>
            Vue.component('ele', {
                render: function(createElement) {
                    // 相当于<div><slot :text="msg"></slot></div>
                    return createElement('div', [
                        this.$scopedSlots.default({
                            text: this.msg
                        })
                    ]);
                },
                data: function() {
                    return {
                        msg: '来自子组件'
                    }
                }
            });
            new Vue({
                el: '#app'
            });
        </script>
    </body>
    </html>
    View Code

    向子组件中传递作用域插槽

    <!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></ele>
        </div>
        <script>
            Vue.component('ele', {
                render: function(createElement) {
                    return createElement('div', [
                        createElement('child', {
                            scopedSlots: {
                                default: function(props) {
                                    return [
                                        createElement('span', '来自父组件'),
                                        createElement('span', props.text)
                                    ];
                                }
                            }
                        })
                    ]);
                }
            });
            Vue.component('child', {
                render: function(createElement) {
                    return createElement('b', this.$scopedSlots.default({text: '我是组件'}));
                }
            });
            new Vue({
                el: '#app'
            });
        </script>
    </body>
    </html>
    View Code

    函数化组件

    <!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">
            <smart-item :data="data"></smart-item>
            <button @click="change('img')">切换为图片为组件</button>
            <button @click="change('video')">切换为视频为组件</button>
            <button @click="change('text')">切换为文本组件</button>
        </div>
        <script>
            // 图片组件选项
            var ImgItem = {
                props: ['data'],
                render: function(createElement) {
                    return createElement('div', [
                        createElement('p', '图片组件'),
                        createElement('img', {
                            attrs: {
                                src: this.data.url
                            }
                        })
                    ]);
                }
            }
            // 视频组件
            var VideoItem = {
                props: ['data'],
                render: function(createElement) {
                    return createElement('div', [
                        createElement('p', '视频组件'),
                        createElement('video', {
                            attrs: {
                                src: this.data.url,
                                controls: 'controls',
                                autoplay: 'autoplay'
                            }
                        })
                    ]);
                }
            };
            /*纯文本组件*/
            var TextItem = {
                props: ['data'],
                render: function(createElement) {
                    return createElement('div', [
                        createElement('p', '纯文本组件'),
                        createElement('p', this.data.text)
                    ]);
                }
            };
    
            Vue.component('smart-item', {
                functional: true,
                render: function(createElement, context) {
                    function getComponent() {
                        var data = context.props.data;
                        if (data.type === 'img') return ImgItem;
                        if (data.type === 'video') return VideoItem;
                        return TextItem;
                    }
                    return createElement(
                        getComponent(),
                        {
                            props: {
                                data: context.props.data
                            }
                        },
                        context.children
                    )
                },
                props: {
                    data: {
                        type: Object,
                        required: true
                    }
                }
            });
            new Vue({
                el: '#app',
                data() {
                    return {
                        data: {}
                    }
                },
                methods: {
                    change: function(type) {
                         if (type === 'img') {
                            this.data = {
                                type: 'img',
                                url: 'https://raw.githubusercontent.com/iview/iview/master/assets/logo.png'
                            }
                        } else if (type === 'video') {
                            this.data = {
                                type: 'video',
                                url: 'http://vjs.zencdn.net/v/oceans.mp4'
                            }
                        } else if (type === 'text') {
                            this.data = {
                                type: 'text',
                                content: '这是一段纯文本'
                            }
                        }
                    }
                },
                created: function() {
                    this.change('img');
                }
            });
        </script>
    </body>
    </html>
    View Code
  • 相关阅读:
    遗传算法求函数最值(C语言实现)
    AjaxUploader使用
    AjaxUploader使用:FileUploaded及UploadCompleted
    AutoIt
    网站盗链问题及解决方案
    input不保留历史记录
    必备知识:消息处理
    AjaxUploader使用:文件保存到数据库
    AjaxUploader使用:JavaScript APIs
    页面定时跳转
  • 原文地址:https://www.cnblogs.com/hpx2020/p/8968744.html
Copyright © 2011-2022 走看看