JadeStrong' Blog
  • Home
  • Archives
  • Tags
  • About
  • jQuery源码分析1

    Sep 14, 2016

    该部分分析一下jquery的选择器这块,试着分析一下,在实战中好像经常会考查这部分知识。

    先从一个正则开始:/^[^<]*(<[\w\W]+>)[^>]*$/这个正则表达式所要匹配的是包含html元素的字符串。

    • 符合条件的字符串必须包含一个<>标签,对于位置并没有限定,前后都可以有其他非<、>字符。
      此处是前后结尾并没有任何限制,虽然指定了^[^<]和[^>]$,但是后面都跟了一个*表示可以有任意数量,当然包括0个,而里面则是一个标准的模式,必须是以<和>来开头和结尾的字符串,所以即使后面多跟一个>也无所谓,因为它会匹配[\w\W]+,所以这个正则匹配的是一个包含html元素的字符串。

    再来看另一个正则表达式:/^#([\w-]+)$/,该表达式很明显是匹配一个ID选择器。该选择规定了选择器的规则,必须是由字母和-组成,且以#开头。

  • Git的基本指令

    Sep 14, 2016

    当我们在本地拥有多个分支时,需要知道我们当前是在哪一个分支,此时使用命令:

    1
    2
    3
    4
    5
    git branch -a
    //输出如下
    * source
    remotes/origin/master
    remotes/origin/source

    上面的输出显示,在远程端拥有两个分支,其一是master,这个是我们在创建Repo时生成的;
    之后,我们又在远程端创建了一个source分支,在本例中是存放的Blog项目的源码,而master分支中则是我们博客的静态文件。

    所以,当我们创建了新的博客并部署之后,其实是将文件部署到了master的分支中,而对源码的备份则需要将代码push到source分支。

    而在远程端进行操作之后,又如何将远程分支同步到本地分支呢?

    1
    git pull origin source // 将远程指定分支source拉取到本地当前分支

    使用pull会拉取并合并,而使用fetch则只会拉取,然后需要使用merge来合并。

    当将本地代码提交时,如过远程存在多个分支的话,也需要指定提交到那个分支:

    1
    git push origin source // 将本地分支提交到远程分支

  • 配置Emacs为Markdown编辑器

    Sep 13, 2016

    配置Markdown编辑器

    首先是安装markdown-mode,这个可以参考该文档;
    然后,如果本地没有配置markdown命令来将.md文件转换成.html文件的话,会爆出bash error: no markdown commond等错误,此时需要在本地安装一个markdown编译器,例如pandoc(由于该编译器的原生命令为pandoc,所以还需要配置需要的markdown命令),如下配置:

    1
    2
    3
    4
    5
    6
    7
    8
    //创建一个markdown名称的文件,不要文件名
    touch markdown
    //编辑它,此处$1是占位符,用于需要处理的文件
    pandoc -f markdown -t html -s --mathjax --highlight-style pygments --from markdown-yaml_metadata_block $1
    //然后将该文件放到/usr/bin目录中
    su -c 'mv markdown /usr/bin'
    //并为它添加可执行权限
    su -c 'chmod a+x /usr/bin/markdown

    经过上面的配置,现在应该已经可以使用emacs或调用浏览器来预览md文件了。

    另外,我们还可以使用emacs支持的eww浏览器来在emacs中实现预览:C+c C+c l即可。

    此时,并不能实现实时预览,只有我们按下保存按钮之后,才能后更新预览,在这可以配置emacs的自动保存,需要下载auto-save.el文件:https://github.com/manateelazycat/deepin-emacs/blob/master/site-lisp/extensions/lazycat/auto-save.el

    并修改.emacs文件,该文件存放在~/路径下,如果没有可以创建,另外也可以修改~/.emacs.d/init.el文件,这两个文件都是等价的,emacs启动时会读取这些文件并加载定义的插件。
    文件配置如下:

    1
    2
    3
    4
    5
    6
    7
    //这一句是必须的,用于指定扩展插件的路径
    (add-to-list 'load-path (expand-file-name {path to package directory} user-emacs-directory))
    //下面是加载模块的代码
    (require 'auto-save) ;; 加载自动保存模块
    (auto-save-enable) ;; 开启自动保存功能
    (setq auto-save-slient t) ;; 自动保存的时候静悄悄的, 不要打扰我

    至此,已经配置好了自动保存功能,当编辑markdown文件时,可以实现自动保存并刷新展示。

  • React之Alt架构分析

    Sep 12, 2016

    在使用Alt时,首先需要实例化一个alt实例,将其定义为一个单例模块,然后对其做一些必要的配置,然后就可以将它导出,当在项目中需要时可以执行引入,而不用每次都实例化了。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    import Alt from 'alt';
    import makeFinalStore from 'alt-utils/lib/makeFinalStore';
    class Flux extends Alt {
    constructor(config) {
    super(config);
    this.FinalStore = makeFinalStore(this);
    }
    }
    const flux = new Flux();
    export default flux;

    在上面我们还使用了alt-utils的makeFinalStore,这个是用来监视所有的store都修改完毕之后,可以做最后处理。 ?

    当定义好了alt实例,下面是需要将它配置到React项目中去,需要在Provider中配置,首先介绍下Provider的概念,这是Alt架构的两个概念之一,另一个是connect负责将action等连接到组件中去。至于Provider更多的是一个可扩展接口,其实可以将其直接嵌入到组件中,但是区分开来更加容易定制。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    import React from 'react';
    import AltContainer from 'alt-container';
    import chromeDebug from 'alt-utils/lib/chromeDebug';
    import alt from '../../libs/alt';
    import setup from './setup';
    setup(alt); //这个用来对alt做一些通用的配置
    chromeDebug(alt); //这个是一个debug组件,结合chrome插件调试alt
    React.Pref = require('react-addons-perf'); // 这个好像是性能分析工具
    export default ({children}) =>
    <AltContainer flux={alt}>
    {children}
    </AltContainer>

    在导出部分,使用了AltContainer,这个东西可以为子组件传入this.props属性信息,可以分开定义,也可以使用我们定义的alt。

    在传入alt之前,我们需要将store绑定到alt中,这个操作就是在setup.js中做的:

    1
    2
    3
    4
    5
    import NoteStore from '../../stores/NoteStore';
    export default alt => {
    alt.addStore('NoteStore', NoteStore);
    }

    这样就会将NoteStore通过alt实例,在AltContainer中传入{children}中,在组件中可以通过this.props来访问。

    注意:此处在参数传递中还有困惑,即:是将NoteStore直接传入了组件的props属性,还是通过connect函数来做的? 在后面看来这些都是在connect中做的处理。这一点在主组件文件app.jsx中也可以看,组件App是作为参数传入了connect函数,而最后导出的是connect函数最终执行的结果,即将修订后的App组件返回并在后续进行渲染

    分析下connect函数所起的作用:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    import React from 'react';
    export default (state, actions) => {
    if (typeof state === 'function' ||
    (typeof state === 'object' && Object.keys(state).length)) {
    return target => connect(state, actions, target);
    }
    return target => props =>(
    <target {...Object.assign({}, props, actions)} />
    );
    }
    function connect(state = () => {}, actions = {}, target) {
    class Connect extends React.Component {
    constructor() {
    super();
    this.handleChange = this.handleChange.bind(this);
    }
    componentDidMount() {
    const {flux} = this.context;
    flux.FinalStore.listen(this.handleChange);
    }
    componentWillUnMount() {
    const {flux} = this.context;
    flux.FinalStore.unlisten(this.handleChange);
    }
    render() {
    const {flux} = this.context;
    const stores = flux.stores;
    const composedStores = composeStores(stores);
    return React.createElement(target,
    {...Object.assign({}, this.props, state(composedStores), actions)});
    }
    handleChange() {
    this.forceUpdate();
    }
    }
    Connect.contextTypes = {
    flux: React.PropTypes.object.isRequired
    }
    return Connect;
    }
    function composeStores(stores) {
    let ret = {};
    Object.keys(stores).forEach(k => {
    const store = stores[k];
    ret = Object.assign({}, ret, store.getState());
    });
    return ret;
    }

    首先,这是一个高层函数,即它会根据参数的不同而返回另一个不同的函数,当参数state是一个函数或者对象时,会返回一个生成新组件的新函数,否则会返回一个函数,直接将传入的组件添加上属性进行返回。
    新组件在渲染时会将传入的React 类使用React.createElement进行渲染处理,这其实是一层包装,用于为组件绑定响应的属性,如this.props、store、action等,当返回时就可以在组件中直接访问这些属性了。

    流程:
    <Provider><App /></Provider>(index.jsx) =>
    {childre} => <AltContainer flux={alt}> {children} </AltContainer>(Provier.dev.jsx) =>
    export default connect(({notes}) => ({notes}), {NoteActions})(App);(app.jsx) =>
    React.createElement(target, {...Object.assign({}, this.props, state(composedStores), actions)});(connect.jsx) =>

    首先是将App(此时的App其实是connect的返回,是一个包装之后的全新的组件)作为参数传入Provider,Provider通过AltContainer将alt传给connect返回的组件Connect,在Connect组件渲染时中可以通过this.context访问传入的alt,从中拿到flux,以及flux中的NoteStore,然后就可以将store和之前传入的action等绑定到该新创建的组件中。

    至此,基本是React集成Alt的一个基本的过程,这些也就是对思路的一个基本梳理,后面还需要理解以及修补。

  • 备份Blog源码--git学习

    Sep 12, 2016

    在使用Hexo进行博客部署时,仅将生成的静态博客文件上传到了github中,通过GitHub Page进行展示,但是项目的源码都是存储到本地的,所以这样做不是很安全,完全有可能发生源码丢失这种问题,所以在这里建立github分支来存储源码。

    命令如下:

    1
    2
    3
    4
    5
    git init // 默认这个文件夹是没有进行git初始化的
    git remote add origin {your-git-repo-url} //这个是添加一个新的远程仓库
    git checkout -b source //这是检出一个分支么?
    git push origin source //这个是将谁推给谁呢,目前看可能是origin -> source?

    在这里曾出现一个问题:error: src refspec {branch name,如source} does not match any:

    这个是因为推送的目录中没有文件,应该先将当前目录的文件都添加上去:

    1
    2
    3
    git add .
    git commit -m 'some thing'
    git push origin source //即可成功
Prev

Powered by Hexo and Theme by Even

©2017JadeStrong