晓风轻

Results 26 issues of 晓风轻

采用了 jQuery 作者 John Resig 的 HTML Parser ,(VUE也是用了这个),然后生成语法树,非常少的代码,语法树的结构参考了VUE的,目前只用了几个字段,不够后面再加。 生成语法树就是生成一颗树,比较麻烦的是父节点的处理,这里用一个栈来存放(就是一个数组,采用push和pop方法),代码非常简单,自己写的话10行左右就生成了语法树。 type1 表示dom节点,2表示表达式(未实现)3表示文本/注释, ```javascript /* @flow */ import { log } from '../util' import { HTMLParser, HTMLtoXML, HTMLtoDOM } from './htmlparser'...

# 实现思路 插槽看上去很高级很复杂,其实实现起来并不复杂! 插槽的真正内容是在父组件上的,所以创建子组件之前,子组件里面的数据对应的vnode已经存在了。这里使用,我们把它归类到实例的 `$slots` 对象上,它是一个数组的对象。 然后再子组件渲染的时候,再把他的数据(就是vnode)拿出来,当到子组件的child里面,snabbdom自动就会渲染出来了! # 归类子组件到$slots 再创建子组件的时候,增加代码。把 `父组件` 里面的vnode根据插槽归类。 ```javascript /** * 实现组件功能 * * 采用snabbdom的hook,在insert和update的时候更新数据。 * * @param {*} vnode * @param {*} vm */ function...

实现的目标就是把filter的语句生成渲染函数,如 ` message | capitalize | wrap('-') ` 会编译成 ` _f("wrap")(_f("capitalize")(message),'-') ` 。 # 实现 没有看vue怎么实现的,自己实现的,估计有不少bug,但还算宝刀未老啊! util/text-parser 中,表达式的地方都处理一下!如果有|的,表示有filter。然后拆分成数据,防止再递归。代码写起来就容易很多,也有要考虑有参数的filter。 **当前应该没有绑定当前实例** ```javascript /** * 处理filter表达式 * 如:message | capitalize | wrap('===') *...

参考[通过microtasks和macrotasks看JavaScript异步任务执行顺序](http://tuobaye.com/2017/10/24/%E9%80%9A%E8%BF%87microtasks%E5%92%8Cmacrotasks%E7%9C%8BJavaScript%E5%BC%82%E6%AD%A5%E4%BB%BB%E5%8A%A1%E6%89%A7%E8%A1%8C%E9%A1%BA%E5%BA%8F/) 和 [【朴灵评注】JavaScript 运行机制详解:再谈Event Loop](http://blog.csdn.net/lin_credible/article/details/40143961) 和 vue的源码next-tick.js。 # macrotasks和microtasks的划分: ## macrotasks: - setTimeout - setInterval - setImmediate - requestAnimationFrame - I/O - UI rendering ## microtasks: - process.nextTick - Promises...

取得了语法树之后,分三步。 1. 生成render函数字符串 2. 生成render函数 3. 如何调用 # 生成函数字符串 我们使用 `snabbdom` 来产生和处理我们的虚拟dom,所以我们需要把AST生成类似下面的render函数字符串。 ```javascript 产生类似这样的snabbdom函数字符串 h('div#container.two.classes', { on: { click: someFn } }, [ h('span', { style: { fontWeight: 'bold' }...

其实很简单,创建的时候制定render函数,就不需要自己去解析模板生成render了。 然后调用render函数的时候,把渲染函数传入即可。 # 测试代码 ```html Xiao.component('anchored-heading', { props:['level', 'text'], render: function (createElement) { console.log('createElement'); return createElement( 'h' + this.level, this.text ) } }) var app = new Xiao({ el: '#demo',...

其实就是把x-model指令生成的渲染函数改成下面这样生成的一样即可。 ```html ``` # 实现 修改ast2renderstr代码 ```javascript /** * 解析指令 * @param {*} node */ function getDirectiveStr(node: any) { let dirs = node.directives let str = ''; if (dirs &&...

[先看vue的说明](https://cn.vuejs.org/v2/guide/components.html#%E4%BD%BF%E7%94%A8%E8%87%AA%E5%AE%9A%E4%B9%89%E4%BA%8B%E4%BB%B6%E7%9A%84%E8%A1%A8%E5%8D%95%E8%BE%93%E5%85%A5%E7%BB%84%E4%BB%B6) 和 [自定义组件在使用 v-model 时定制 prop 和 event](https://cn.vuejs.org/v2/api/#model) ``` 自定义事件可以用来创建自定义的表单输入组件,使用 v-model 来进行数据双向绑定。要牢记: 这不过是以下示例的语法糖: 所以在组件中使用时,它相当于下面的简写: 所以要让组件的 v-model 生效,它应该 (从 2.2.0 起是可配置的): 接受一个 value prop 在有新的值时触发 input 事件并将新值作为参数 ``` 下面这种分开写的方式,默认当前功能已经支持。 ``` ```...

实现起来很简单,因为之前的代码已经处理了x-on(@),所以直接绑定即可。 # 实现 框架代码增加 _events字段和$emit方法 ```javascript class Xiao{ // 事件 _events : any /** * 调用事件 * * @param {*} event */ $emit(event: String){ // 无需绑定this,方法生成的时候已经绑定了 this._events[event]() } } ```...

# 原因 如果子组件的data不是方法的话,每个组件返回相同的一份数据,那么多个子组件的数据就会冲突。所以子组件的data方法必须是一个function,每个子组件返回独立的数据。 # 测试代码 ```html 子组件data方法测试 Xiao.component('button-counter', { template: '{{ counter }}', data: function () { return { counter: 0 } }, methods: { incrementCounter: function () { console.log('incrementCounter')...