zoukankan      html  css  js  c++  java
  • vue渲染函数&JSX

    Vue推荐在绝大多数情况下使用template来创建你的HTML。然而在一些场景中,你真的需要JavaScript的完全编程能力,这时你可以使用render函数,它比template跟接近编译器.

    虚拟DOM

    在深入渲染函数之前,了解一些浏览器的工作原理很重要。以下面这段HTML为例:

    
    <div>
        <h1>My title</h1>
        Some text content
        <!--TODO:添加标签行-->
    </div>
    

    当浏览器读到这些代码时,它会建立一个‘DOM节点树’来保持追踪,如同你会画一张家谱树来追踪家庭成员的发展一样。
    HTML的DOM节点树如下图所示:

    每个元素都是一个节点。每片文字也是一个节点。甚至注释也都是节点。一个节点就是页面的一个部分。就像家谱树一样,每个节点都可以有孩子节点(也就是说每个部分可以包含其它一些部分)。
    高效的更新所有这些节点会是比较困难的,不过所幸你不必再手动完成这个工作了。你只需要告诉Vue你希望页面上的HTML是什么,这可以是在一个模板里:

    
    <h1>{{blogTitle}}</h1>
    

    或则一个渲染函数里:

    
    render:function(createElement){
        return createElement('h1',this.blogTitle);
    }
    

    在这两种情况下,Vue都会自动保持页面的更新,即便blogTitle发生了改变。

    Vue通过建立一个虚拟DOM对真实的DOM发生的变化保持追踪。请仔细看这行代码:

    
    return createElement('h1',this.blogTitle)
    

    createElement到底返回什么呢?其实不是一个实际的Dom元素。它更准确的名字可能是createNodeDescription,因为它所包含的信息会告诉Vue页面上需要渲染什么样的节点,及其子节点。我们把这样的节点描述为虚拟节点,也常简写为VNode。虚拟DOM是我们对Vue组件树建立起来的整个VNode树的称呼。

    createElement参数

    
    createElement(
        //{String|Object|Function}
        //一个HTML标签字符串,组件选项对象,或则解析上述任何一种的一个async异步函数。必须参数。
        'div',
        
        //{Object}一个包含模板相关属性的数据对象,你可以在template中使用这些特性。可选参数。
        {},
        
        //{String|Array}子虚拟节点,由createElement()构建而成,也可以使用也可以使用字符串来生成文本虚拟节点。可选参数。
        [
            '先写一些文字',
            createElement('h1','一则头条'),
            createElement(Mycomponent,{
                props:{
                    someProp:'foobar'
                }
            })
        ]
        
    )
    

    深入data对象

    有一点要注意:正如在模板语法中,v-bind:class和v-bind:style,会被特别对待一样,在VNode数据对象中,下列属性名是级别最高的字段。该对象也允许你绑定普通的HTML特性,就像DOM属性一样,比如innnerHTML(这会取代v-html指令)。

    
    {
        //和v-bind:class一样的API,接收一个字符串、对象或字符串和对象组成的数组。
        'class':{
            foo:true,
            bar:false
        },
        //和v-bind:style一样的API,接收一个字符串、对象或对象数组组成的数组
        style:{
            color:'red',
            fontSize:'14px'
        },
        //普通的HTML特性
        attrs:{
            id:'foo'
        },
        //组件props
        props:{
            myPro:'bar'
        },
        //DOM属性
        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=>createElement('span',props.text)}
        scopedSlots:{
            default:props=>createElement('span',props.text)
        },
        //如果组件是其它组件的子组件,需要为插槽指定名称。
        slot:'name-of-slot',
        //其它特殊顶层属性
        key:'myKey',
        ref:'myRef',
        //如果你在渲染函数中向多个元素都应用了相同的ref名,那么$refs.myRef会变成一个数组。
        refInFor:true
    }
    

    完整示例

    有了这些知识,我们现在可以完成我们最开始想实现的组件:

    
    var getChildrenTextContent = function(children){
        return children.map(function(node){
            return node.children
            ?getChildrenTextContent(node.children)
            :node.text
        }).join('')
    }
    Vue.component('anchord-heading',{
        render:function(createElement){
            //创建kebab-case风格的ID
            var headingId = getChildrenTextContent(this.$slots.default)
                .toLowerCase()
                .replace(/W+/g,'-')
                .replace(/(^-|-$)/g,'')
            return createElement(
                'h'+this.level,
                [
                    createElement('a',{
                        attrs:{
                            name:headingId,
                            href:'#'+headingId
                        }
                    },this.$slots.default)
                ]
            )
        },
        props:{
            level:{
                type:Number,
                required:true
            }
        }
    })
    

    原文地址:https://segmentfault.com/a/1190000017354905

  • 相关阅读:
    hive使用derby的服务模式(可以远程模式)
    使用sqoop过程
    使用mongodump及mongorestore备份及恢复数据
    sql server 2000 错误229 拒绝了对象sysobjects 的select 权限
    node.js 连接 sql server 包括低版本的sqlserver 2000
    centos7 安装jdk1.8
    mybatis配置时出现org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)
    该网页已屏蔽以下插件Adobe Flash Player
    关于IntelliJ IDEA 文档无法编辑的解决办法
    华硕_ZX50JX4200 安装ssd固态盘
  • 原文地址:https://www.cnblogs.com/lalalagq/p/10114383.html
Copyright © 2011-2022 走看看