Giter Club home page Giter Club logo

alex2wong.github.io's Issues

最近书单,技术总结

不知不觉已经五月了,2018年已经过去三分之一。
周末宅家突然想起自己费尽心思做的slider有另外一种简单一万倍的方法实现。。整个人都不好了。那一个多周写的代码几乎都付诸东流,这都怪做slider 前没有好好调研前人的方法 : (

看图:
flexbox 实现的slider 布局,线框

flexbox 实现的slider 布局

最后发现用原生的input[type=range] ,隐藏浏览器原生样式,直接改css 就可以。。还可以改造为垂直效果,HollyShiiiiit !

基于vue的 input range组件 Github代码
把代码放这里,希望有帮助, 基于原生组件直接修改样式是最简单的办法。
基于vue的slider组件,支持主题,垂直slidrer

最近书单

今年看书也比较慢,不过也算是看到几本不错的。

**《刷新:重新发现商业与未来》**下载地址:https://sobooks.cc/books/7821.html
作者:萨提亚·纳德拉,微软现任CEO。书中记录了作者在上任后对微软改革的思考,也是对技术的思考。作者也是是微软的云技术专家,曾经负责Bing搜索。跳出编程本身,看看大佬对于未来技术的思考,结合微软近几年的巨大进步,还有IBM 等大公司对云计算,量子技术的看好。
部分笔记:

  • 对于领导而言,通过命令达成的共识并不是真正的共识。任何机构建设都源于清晰的, 既能自上而下也能自下而上推动进步的愿景与文化。
  • 我们的世界已经不再是以个人计算机为中心的世界。计算变得无所不在

《把生命浪费在美好的事物上》
作者:吴晓波。书中记录了许多作者对当代社会问题的看法,自己的经历。特别是一些对社会问题的一击即中,简明地指出问题的本质,也记录了许多社会经济往事。很赞。
部分笔记:

  • 现代社会的复杂和规模使得一般人难以对他有清楚的把握。现代人一般从事一种单一的工作,... 他们很少认真涉入公众事务讨论。... 摘自书中《我的偶像李普曼》
  • 一切以经济为中心,一切以财富为标杆,所谓的智慧、快乐与价值都似乎是可以被量化的,而伦理道德则成为一种可有可无的奢侈品,他们的底线往往可以被轻易击穿。

作者提到了很多现实问题,作为一个程序员,更作为一名有觉悟的市民。我们有理由和责任去全面理智地思考

  • 我们的公立教育能否保证教育公平,教育减负是否推高了私立教育
  • 我们的塑料垃圾能否有效地控制?外卖行业如何合理控制塑料消耗?

最近计划

由于已经开始基于Vue 的项目,而Vue的生态足够丰富,有很多可以把vue app 封装为PWA,hybrid移动app 或者微信小程序的 工具或者框架,要感谢开源社区让我们可以简单地做出兼容更多平台的应用。

准备以最近写的贷款计算器为demo,改造为小程序或者native app.
还有就是写一两篇文章记录下 做UI 组件的心路历程。
最后准备看看吴军的书,和吴晓波一样关心社会经济的运行规律,也许技术人对于世界的思考方式有所不同。

吴军的书目录

vue.js 实践总结(二)Render 函数

上一篇说了项目搭建和结构,这篇说说vue 的render 函数,比较核心的概念。去年写过一点react,所以知道render 函数是用来创建虚拟dom 的,那个时候写 jsx 还是不亦乐乎的。列出几个问题作为这篇的结构:

  • render 函数的作用?
  • 组件中的render 函数什么时候执行?
  • 什么时候需要在组件中写 jsx ?

常遇到这个问题:

[Vue warn]: Failed to mount component: template or render function not defined

这个问题是由于当前写的组件没注册为vue 组件,或者组件定义中没有template/render,所以组件没法和具体的element 挂载到一起,无法完成渲染。

render 的作用

render 函数实际上是template 的底层方法,通过调用createElement(h)来创建dom节点,实际上作用就是负责组件视图渲染的!createElement是render的核心方法。Vue编译的时候会把template 编译为对应的render 方法,所以有了render方法就可以不写template 了!

看实例:

<template>
  <div class="right-panel">
     <div class="right-panel-header">{title}</div>
     <div class="right-panel-content">
        {content}
     </div>
  </div>
</template>

如果不写template,对应的render 则是

render(h) {
  return (
      <div class="right-panel">
        <div class="right-panel-header">{this.title}</div>
        <div class="right-panel-content">
          {this.content}
        </div>
      </div>
    );
}

从生命周期出发,render执行时机

与render 相关的生命周期

还是得把组件的生命周期搬出来,created 钩子函数是组件injection和reactivity 属性初始化后,比如props、data 初始化,后面关键的:如果有template,则把视图编译为render function,如果没有则直接调用被override 的render 方法创建虚拟dom节点,并且把组件对应的 htmlElement 替换为 组件的dom 结构和数据,最后触发mounted 钩子。

所以执行顺序是 beforeMount -- render(h, data) -- mounted .

什么时候需要定义render

上面那个实例,panel content 内容可以是外部传入的一段内容(this.$props.content),假如内容很复杂呢,假如这个panel 组件需要接受用户自定义的复杂content 呢? 这时候就需要接受外部传入的函数来渲染一段dom。 这样panel 只是个容器,把内容渲染交给外部模块,实际上是组件拆分和模块化的**,使得panel 组件可以更好的复用。

我们把panel 的render 函数改为可以接受外部函数:

render(h) {
    let contentNode = (<div>default content</div>);
    if (this.contentRender && this.contentRender instanceof Function) {
      contentNode = this.contentRender(h, this.data); 
// 把数据用外部函数来渲染成用户想要的结构
    }
    console.warn(`rendering...`);
    return (
      <div class="right-panel">
        <div class="right-panel-header">Panel Header</div>
        <div class="right-panel-content">
          {contentNode}
// 插入dom 结构
        </div>
      </div>
    );
  }

contenRender 的定义可以是这样的:

contentRender (h, data) { 
   return (<div>Current Data: {data['app']}</div>); 
},

总结

render 真的很有趣,其实际上就是jquery 时代的 创建dom,构建dom tree 的过程,但是更加的智能化、更优雅。 掌握了render ,就可以自由构建可复用的组件容器。建议详细阅读官方文档,非常有用。

一些思考:

开发一个前端项目,不仅仅是视图和组件逻辑,更重要的是数据服务,现代化前端几乎都是数据驱动的。因为一个app 在组件初始化时完成了数据和视图绑定,对视图的监听,随着app 的运行,实际上是不断变化的数据在驱动视图的变化。

基于MVC 的架构或 MVVM的架构,在不断写组件的过程中,我们不断反思该如何写一个组件,怎么把多个组件集成到一个复杂组件中,组件中的逻辑部分是否应该合理拆分出其他几个通用的模块/类

比如api service 单独处理api相关的,api service 里面的网络请求有可以单独出 network 层,为了方便替换net 请求库,还有许多通用的数据格式转换层,都是可以单独成类或者service的概念。

参考文章:
官方文档:渲染函数 & JSX
支持 jsx 语法的插件,transform-vue-jsx
被误解的MVC和被神化的MVVM,rethinking-mvc-mvvm

babel 修改抽象语法树——入门与实践

问题由来

最近有个想法,之前用Angular2.x 的时候,官方提供了ng-cli 可以一键生成component、service、directive 等代码文件,并且还可以修改对应的routes 配置文件,使得组件自动加入app 的前端路由中(一键生成或修改数个文件)。这使得前端开发效率大为提高,我们不必再手动去创建那么多文件夹、文件,并且手动修改route 配置。但是vue-cli 没有提供这种功能,所以我们想要写个node.js 脚本去做这个工作。除了用正则替换的解决办法,更科学的实际上就需要用到修改代码抽象语法树的方法。

babel 编译过程

我们通常用 babel 去编译ES6/ES7 为ES5,以便于 js 脚本运行在各种浏览器上。这个编译的过程实际上是语法转换的过程,比如箭头函数转为函数表达式,this 的显式绑定等等。那么babel 在做这个工作的时候实际上经历了几个步骤,parse => transform (AST) => generate

https://www.sitepoint.com/understanding-asts-building-babel-plugin/

所以要想完成这几个步骤,babel 提供了几个实用工具(Babylon,babel-traverse,babel-generator),我们的思路就是找到route 配置表中该插入新路由的地方,插入新路由并且保存文件。
babel.transform 核心函数接受源代码字符串和options 作为输入,返回一个Object 包含几个属性:新的代码字符串,sourcemap,ast 语法树对象。

babel.transform("code();", options, function(err, result) {
  result.code;
  result.map;
  result.ast;
});

实践新增一个route对象

以下是等待修改的路由配置文件,

// './src/router.ts'
export default new Router({
  routes: [
    {
      path: '/',
      name: 'home',
      component: Home
    },
    {
      path: '/about',
      name: 'about',
      component: About
    }
    // to be append new route.
  ]
})

以下是通过 babel 修改route 配置文件的过程

var fs = require('fs');
let babel = require('babel-core');
let t = require('babel-types');
let template = require('@babel/template');
// 读取需要修改的源代码内容
var content = fs.readFileSync('./src/router.ts').toString();

const newRoute = {
  path: '/list',
  name: 'list'
  // component: ListComponent
};

// 定义一个 babel 插件,拦截并修改 routes 的数组表达式
let visitor = {
  ArrayExpression(path) {
    const elements = path.node.elements;
    console.warn(`routes number:  ${elements.length}`);
    // 新增一个构建出来的 route 对象
    elements.push(t.objectExpression([
      t.objectProperty(t.identifier('path'), t.stringLiteral(newRoute.path)),
      t.objectProperty(t.identifier('name'), t.stringLiteral(newRoute.name)),
      t.objectProperty(t.identifier('component'), t.identifier('ListComponent'))
    ]));
  }
}

// 通过 plugin 转换源代码 parse 出来的AST 抽象语法树,并且返回结果
let result= babel.transform(content, {
   plugins: [
     { visitor }
   ]
 });

 console.warn(`res: ${result.code}`);
 // 把新代码写入新文件.
 fs.writeFileSync('newRoute.ts', result.code);

比较关键的部分就是在visitor 这个自定义的插件中,拦截ArrayExpression,这是routes: [] 对应的路由数组。而这个数组表达式包含了一个elements 数组,每个对象在AST 中都是ObjectExpression 类型。不论是数组表达式,还是对象表达式,都是对应 babel-types 中不同的节点(node)类型。所以我们在构建新的 AST 节点时,可以参考AST explorer 中已有的节点类型。

例如这里我们要新增一个route 对象,则是用babel-types 中的 types.objectExpression(objectProperty[]) 生成一个,根据智能提示传入参数,要求是objectProperty 数组,那么我们又利用 types.objectProperty(key: identifier, value: string) 生成一个。

t.objectExpression([ 
  // 对象中的第一个属性 path: string;
  t.objectProperty(t.identifier('path'), t.stringLiteral(newRoute.path)),
  // ...
]);

AST explorer 中源代码和AST的对应关系

根据官方docs,也可以利用 AST explorer 去寻找对应关系,结合 IDE 的智能提示来构建你所需要的 AST 语法树,就可以自动转换成你想要的代码了。实际上,搞懂了babel ,就可以做出ng-cli generate 这样智能高效的功能了。

参考文章:
https://www.sitepoint.com/understanding-asts-building-babel-plugin/
http://welefen.com/post/understanding-asts-by-building-your-own-babel-plugin.html
babel 官方文档
AST Explorer

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.