• 笔记(摘自blog)


    块级格式化上下文BFC

    BFC是block formatting context,在文档流的类型中,普通文档流属于FC,而BFC可以理解为一种占位的普通文档流。它是页面中的一块渲染区域,有一套渲染规则,决定了其子元素如何布局,以及和其他元素之间的关系和作用。

    -----------------------------------------------------------------

    传统的写法

    首先我们回顾下require.js的写法。假设我们有两个js文件: index.jscontent.js,现在我们想要在index.js中使用content.js返回的结果,我们要怎么做呢?

    //首先定义:
    
    //content.js
    define('content.js', function(){
        return 'A cat';
    })
    //然后require:
    
    //index.js
    require(['./content.js'], function(animal){
        console.log(animal);   //A cat
    })

    那CommonJS是怎么写的呢?

    //index.js
    var animal = require('./content.js')
    
    //content.js
    module.exports = 'A cat'

    ES6的写法

    //index.js
    import animal from './content'
    
    //content.js
    export default 'A cat'


    ---------------------------------------------------------------------------------------------------------------------------------------------------------------
    //content.js
    
    export default 'A cat'    
    export function say(){
        return 'Hello!'
    }    
    export const type = 'dog' 

    上面可以看出,export命令除了输出变量,还可以输出函数,甚至是类(react的模块基本都是输出类)

    //index.js
    
    import { say, type } from './content'  
    let says = say()
    console.log(`The ${type} says ${says}`)  //The dog says Hello

    这里输入的时候要注意:大括号里面的变量名,必须与被导入模块(content.js)对外接口的名称相同。

    如果还希望输入content.js中输出的默认值(default), 可以写在大括号外面。

    //index.js
    
    import animal, { say, type } from './content'  
    let says = say()
    console.log(`The ${type} says ${says} to ${animal}`)  
    //The dog says Hello to A cat

    修改变量名

    此时我们不喜欢type这个变量名,因为它有可能重名,所以我们需要修改一下它的变量名。在es6中可以用as实现一键换名。

    //index.js
    
    import animal, { say, type as animalType } from './content'  
    let says = say()
    console.log(`The ${animalType} says ${says} to ${animal}`)  
    //The dog says Hello to A cat


    --------------------------------------------------------------------------------------------------------------------------
    function view() {
      return <ul id="filmList" className="list">
        <li className="main">Detective Chinatown Vol 2</li>
        <li>Ferdinand</li>
        <li>Paddington 2</li>
      </ul>
    }
    
    // 接下来,我们要将JSX编译成js, 也就是hyperscript。我们先用Babel编译一下,看这段JSX转成js会是什么样子,打开命令行,输入npm run compile,得到的compile.js:
    
    function view() {
      return h(
        "ul",
        { id: "filmList", className: "list" },
        h(
          "li",
          { className: "main" },
          "Detective Chinatown Vol 2"
        ),
        h(
          "li",
          null,
          "Ferdinand"
        ),
        h(
          "li",
          null,
          "Paddington 2"
        )
      );
    }
    
    

    可以看出h函数接收的参数,第一个参数是node的类型,比如ul,li,第二个参数是node的属性,之后的参数是node的children,假如child又是一个node的话,就会继续调用h函数。

    清楚了Babel会将我们的JSX编译成什么样子后,接下来我们就可以继续在index.js中来写h函数了。

    function flatten(arr) {
      return [].concat(...arr)
    }
    
    function h(type, props, ...children) {
      return {
        type,
        props: props || {},
        children: flatten(children)
      }
    }

    我们的h函数主要的工作就是返回我们真正需要的hyperscript对象,只有三个参数,第一个参数是节点类型,第二个参数是属性对象,第三个是子节点的数组。

    flatten(children)这个操作是因为children这个数组里的元素有可能也是个数组,那样就成了一个二维数组,所以我们需要将数组拍平成一维数组。[].concat(...arr)是ES6写法,传统的写法是[].concat.apply([], arr)

    我们现在可以先来看一下h函数最终返回的对象长什么样子。

     
    function render() {
      console.log(view())
    }
    // 下面我们就可以根据VDOM, 来渲染真实DOM了。先改写render函数:
    
    function render(el) {
      el.appendChild(createElement(view(0)))
    }
    function createElement(node) {
      if (typeof(node) === 'string') {
        return document.createTextNode(node)
      }
    
      let { type, props, children } = node
      const el = document.createElement(type)
      setProps(el, props)
      children.map(createElement)
        .forEach(el.appendChild.bind(el))
    
      return el
    }
    
    function setProp(target, name, value) {
      if (name === 'className') {
        return target.setAttribute('class', value)
      }
    
      target.setAttribute(name, value)
    }
    
    function setProps(target, props) {
      Object.keys(props).forEach(key => {
        setProp(target, key, props[key])
      })
    }


  • 相关阅读:
    [转]翻译:使用.net3.5的缓存池和SocketAsyncEventArgs类创建socket服务器
    强制将IE,Chrome设置为指定兼容模式来解析(转)
    MySQL vs NoSQL 效率与成本之争(转)
    Configure the max limit for concurrent TCP connections
    在as3中Embed(绑定)flash动画元素
    使用ASP.NET Global.asax 文件(转)
    AspExe a small ASP.NET compiler and executor for document generation
    [转]vim + cscope/ctags 查看分析代码
    编译Chromium 遇到的问题
    yum与apt命令比较
  • 原文地址:https://www.cnblogs.com/fengnovo/p/9013296.html
Copyright © 2020-2023  润新知