No pay no gain.

line-height

w3c标准

  1. line-height确定line-box的高度
  2. 同一行内,各line元素的line-height共同确定该行的line-boxes的高度
  3. block元素没有定高度,由block元素内的block元素和inline元素共同确定该元素的高度。
1
2
3
4
<div style="line-height:1.5; border:1px solid #34538b;font-size: 16px;">
<span style="font-size:60px; border:1px solid #a0b3d6; vertical-align: baseline; line-height: 100px;">大大的文字</span>
后面是静止的文字。
</div>

vertical-align

w3c标准
元素内vertical对齐顺序,分为两类:

  1. 非top,bottom对齐方式,根据行内框高度,行内文字来进行对齐。
  2. 对齐后,取top,bottom对齐元素的最大值的元素,来对齐以确定该元素的行框的top或bottom。之后再分别对齐。

vertical-algin & line-height

w3c标准

阅读此文
post @ 2016-03-13

前段时间研究了下,inline元素的格式化,感觉有点复杂,还没完全弄明白,今天看了下block元素的格式化,原本以为很简单的概念,但是我错了,block元素的格式化也不是很简单,所以很多前辈说css难学,现在看来不无道理。很多前端工程师,都轻视css,在重学了css后,理解这一块真的一点也不轻松。

垂直格式化

  • 块级元素heightauto
    高度从最高子元素的上外边距到其最低子元素下外边距

    书上写的与这不一致 以上表现为chrome v50.0.2661.94下的表现

  • 块级元素height有固定值时 情况稍微有点复杂
    1. 没有上边距,下边距(上边框,下边框无关)
      高度为最高元素的上外边距到该元素的下外边距
    2. 有上边距,上边框(上边框,下边框无关)
      高度为该元素的上外边距到该元素的下外边距
阅读此文
post @ 2015-12-22
阅读此文
post @ 2015-12-11

搭建babel-es2015环境

安装babel

1
npm install --save-dev babel-cli

配置babelrc

  • 基础配置
1
npm install --save-dev babel-preset-es2015 babel-preset-stage-0

新建 .babelrc 文件加入字段

1
2
3
4
{
"presets": ["es2015", "stage-0"],
"plugins": []
}

  • polyfill配置
    1
    npm install --save babel-polyfill

文件引入

1
import "babel-polyfill";

  • runtime 环境配置
    1
    2
    $ npm install --save-dev babel-plugin-transform-runtime
    $ npm install --save babel-runtime

.babelrc 加入

1
2
3
{
"plugins": ["transform-runtime"]
}

阅读此文
post @ 2015-11-11

React

React.createClass()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var NewClass = React.createClass({

getDefaultProps: function(){
return: {
prop1: "a",
prop2: "b"
}
},
getInitialState: function(){
return {
data: {}
}
},
render: function(){

},
componentDidMount: function(){
return (
<div className="newClass">
hello {this.props.name}!
</div>
)
}
})

ReactDOM.render()

1
2
3
4
ReactDOM.render(
<NewClass name="galen" />,
document.getElementById("example")
)

顶层方法

1
2
3
4
5
React.PropType.Array.isRequired

propTypes: {
name: React.PropTypes.Array.isRequired
}

参见Reuseable Component Prop Validation

1
2
React.findDOMNode(this.refs.xxx)
this.refs.xxx.getDOMNode()

双向数据绑定

1
2
3
4
mixin: [Reat.addons.LinkStateMixin]

valueLink={this.linkState("xxxx")}
checkedLink={this.linkState("xxxx")}

valueLink之后可以被props传递

组件生命周期

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
getDefaultProps: function(){
return {

}
},
getInitialState: function(){
return {

}
},
componentWillMount: function(){

},
componentDidMount: function(){

},
shouldComponentUpdate: function(nextProp, nextState){

},
componentWillUpdate: function(){

},
componentDidUpdate: function(){

},
componentWillReceiceProps: function(){

}


unmountComponentAtNode(this)
阅读此文
post @ 2015-10-21

es6 Module

export

export 输出方式一:

1
2
3
export var firstName = "Galen";
export var lastName = "Jiang";
export var year = "1985";

export 输出方式二:

1
2
3
4
var firstName = "Galen";
var lastName = "Jiang";
var year = "1985";
export {firstName, lastName, year};

输出重命名

1
2
3
4
5
export {
firstName as fN,
lastName as lN,
year as y
}

import

输入命令

1
2
3
import { firstName, lastName, year } from './app'

console.log(firstName)

输入重命名

1
import { firstName as fN } from './app'

整体输入

1
2
3
import * as person from './app';
console.log(person.firstName);
console.log(person.lastName);

export default默认输出输入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
export default function(){
console.log("foo")
}
或者
export default function foo(){
console.log("foo")
}
或者
function foo() {
console.log("foo");
}
export default foo;

import foo from './app';
foo()
阅读此文
post @ 2015-09-25

gulp 入门指南
node.js环境下:

1
npm install -g gulp  //全局安装

1
npm install —-save-dev gulp  //本地安装
1
gulp  --save-dev //--save保存至package.json -dev 部署到开发环境,不加入生产环境
1
npm install gulp-uglify   //本地安装uglify
  • 压缩js gulp-uglify 示例

    1
    2
    var gulp = require("gulp");
    var uglify = require("gulp-uglify");
  • 手动执行压缩任务

    1
    2
    3
    4
    5
    6
    7
    gulp.task("script",function(){
    //1. 找到文件
    gulp.src("js/*.js")
    .pipe(uglify())
    .pipe(gulp.dest("dist/js"));
    });
    gulp.task("auto",function(){
  • 监听文件修改,当文件被修改时执行操作

    1
    2
    3
      gulp.watch("js/*.js",["script"]);
    })
    gulp.task("default",["script","auto"])
1
2
cmd
gulp //回车执行。

sass模块

1
npm install gulp-ruby-sass

  • 获取 gulp

    1
    var gulp =require('gulp')
  • 获取 gulp-ruby-sass 模块

    1
    var sass = require('gulp-ruby-sass');
  • 编译sass// 在命令行输入 gulp sass 启动此任务

    1
    2
    3
    4
    5
    6
    7
    gulp.task('sass', function() {
    return sass('sass/')
    .on('error', function (err) {
    console.error('Error!', err.message);
    })
    .pipe(gulp.dest('dist/css'))
    });
  • 在命令行使用 gulp auto 启动此任务

    1
    2
    3
    4
    gulp.task('auto', function () {
    // 监听文件修改,当文件被修改则执行 images 任务
    gulp.watch('sass/**/*.scss', ['sass'])
    });
  • 使用 gulp.task(‘default’) 定义默认任务// 在命令行使用 gulp 启动 sass 任务和 auto 任务

    1
    gulp.task('default', ['sass', 'auto'])
阅读此文
post @ 2015-09-15
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
 v-bind:href 缩写
:href
v-on:click 缩写
@click

class指令
v-bind:class=""
对象语法
v-bind:class="json"
json = {'classA': true, 'classB':false }
v-bind:class="{ 'classA': isA, 'classB':isB }"
data: {
isA: true,
isB: false
}
数组语法
v-bind:class="[ classA, classB ]"
data: {
classA: 'class-a',
classB: 'class-b'
}
v-bind:class="[classA, isB ? classB : '']"
isB: true

v-bind:style=""
对象语法
<divv-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
数组语法
<divv-bind:style="[styleObjectA, styleObjectB]">

组件
var mytemplate = Vue.extend({
template: "<div class='div'></div>"
})
Vue.component("my-component", mytemplate);


父子组件

标准写法

var child = Vue.extend({
template: "<div class='child'></div>"
})
var parent = Vue.extend({
template: "<div class='parent'><child></child></div>",
components: {
"child": child
}
})
Vue.component("parent", parent);

简单写法
Vue.component("parent", {
template: "<div class='parent'><child></child></div>",
components: {
"child": {
template: "<div class='child'></div>"
}
}
});

子组件用父组件的数据

var child = Vue.extend({
props: ['a'],
template: "<div class='child'>{{ a }}</div>",
data: function(){
return
// {
// a: "child's data"
// }
}
})
var parent = Vue.extend({
template: "<div class='parent'><child v-bind:a='a' ></child></div>",
components: {
"child": child
},
data: function(){
return {
a: "parent's data"
}
}
})

模板

<!-- 父组件-->
<script type="x-template" id="parent">
<div class='parent'>
<child></child>
<child></child>
</div>
</script>
<!-- 子组件-->
<script type="x-template" id="child">
<div class='child'>{{ a }}</div>
</script>
定义
var child = Vue.extend({
template: "#child",
data: function(){
return {
a: "child's data"
}
}
})
var parent = Vue.extend({
template: "#parent",
components: {
"child": child
},
data: function(){
return {
a: "parent's data"
}
}
})
// Vue.component("child", child)
Vue.component("parent", parent);

props 数据往子组件传递

props 为对象时,作为组件验证

$.on() 监听自定义事件
$.emit()触发,$.dispath() 向上冒泡 $.broadcast() 向下传递

过滤器 2.0废弃

{{ msg | filter }}
第一个字大写
capitalize
全部大写
uppercase
全部小写
lowercase
货币化
currency “¥”默认 $
复数
pluralize "item"
pluralize "st" "nd" "rd" "th" 再往后以最后面一个为准
源代码
json 4 缩进为4 default:2
延迟执行
debounce 500 default:300
@keyup="onKeyup | debounce 500"
限制循环
limitBy n m
n:限制几位 m:限制从m位开始,0为第一位
过滤
<input v-model="index" type="text" name="name" >
<ul>
<li v-for="item in msg | filterBy index in 'name' ">{{ item.name }} {{ item.age }} {{ item.sex }}</li>
</ul>

多字段搜索
<liv-for="user in users | filterBy searchText in 'name' 'phone'"></li>

插值表达式
{{}}
{{*value}}只更新一次

增加v-cloak属性,防止闪烁
[v-cloak]{ display: none }
数据遍历之前 用v-show 防止显示不正常数据

v-for 在tr里面不正常



组件:

1. 一般定义
<div id="example">
<my-component></my-component>
</div>

// 定义
var MyComponent = Vue.extend({
template: '<div>A custom component!</div>'
})

// 注册
Vue.component('my-component', MyComponent)

// 创建根实例
new Vue({
el: '#example'
})
2.局部注册
var Child = Vue.extend({ /* ... */ })

var Parent = Vue.extend({
template: '...',
components: {
// <my-component> 只能用在父组件模板内
'my-component': Child
}
})
3. 简化注册 注册语法糖
// 在一个步骤中扩展与注册
Vue.component('my-component', {
template: '<div>A custom component!</div>'
})

// 局部注册也可以这么做
var Parent = Vue.extend({
components: {
'my-component': {
template: '<div>A custom component!</div>'
}
}
})

利用模板穿的属性来构造模板
Vue.component('child', {
// 声明 props
props: ['msg'],
// prop 可以用在模板内
// 可以用 `this.msg` 设置
template: '<span>{{ msg }}</span>'
})
props 驼峰写法如:myMsg 在模板外属性应该写成 my-msg

v-bind:my-msg="abc" 可以简写为:my-msg="abc
:my-msg="1" 数字1作为一个属性来传递的,用:my-msg

冒泡事件“child-msg” 父组件接受事件function(msg){}对参数进行处理

this.$dispatch('child-msg', this.msg)
获取子组件的方式: 在自组件上定义 v-ref属性 用$refs属性获取自组建
<div id="parent">
<user-profile v-ref:profile></user-profile>
</div>
var parent = new Vue({ el: '#parent' })
// 访问子组件
var child = parent.$refs.profile

第一个程序
<divid="app">
{{ message }}
</div>
new Vue({
el: '#app',
data: {
message: 'Hello Vue.js!'
}
})
双向绑定 v-model
<divid="app">
<p>{{ message }}</p>
<inputv-model="message">
</div>
new Vue({
el: '#app',
data: {
message: 'Hello Vue.js!'
}
})

todo

<divid="app">
<ul>
<liv-for="todo in todos">
{{ todo.text }}
</li>
</ul>
</div>
new Vue({
el: '#app',
data: {
todos: [
{ text: 'Learn JavaScript' },
{ text: 'Learn Vue.js' },
{ text: 'Build Something Awesome' }
]
}
})
综合案例
<div id="app">
<input v-model="newtodo" v-on:keyup.enter="addtodo" type="text" name="" >
<ol>
<li v-for="todo in todos">
{{todo.text}}
<button v-on:click="removetodo($index)" type="button" name="button">X</button>
</li>
</ol>
</div>
<script type="text/javascript">
new Vue({
el: "#app",
data: {
newtodo: "",
todos: [
]
},
methods: {
addtodo: function(){
var text = this.newtodo.trim();
if(text){
this.todos.push({text: text});
this.newtodo = "";
}
},
removetodo: function(index){
this.todos.splice(index,1);
}
}
})
</script>


插值表达式 {{}} {{* msg }}单次不更新

指令 v-*

循环
v-for="item in items"
<div>{{ $index($key) }}: {{ item }}</div>

<div>
<spanv-for="n in 10">{{ n }} </span>
</div>

methods

计算属性
computed

v-model
双向绑定
阅读此文
post @ 2015-09-13

全面理解面向对象的 JavaScript
ECMAScript 5.1简介

对象属性的操作和获取

返回对象obj的名为propName的自身属性(非继承来的)的属性描述符.如果没有这个自身属性,则返回undefined.

1
Object.getOwnPropertyDescriptor(obj, propName)

获取原型

1
Object.getPrototypeOf(obj)

是否有属性

1
obj.hasOwnProperty("string")

for,keys受枚举属性影响不可被枚举

1
2
for (var x in obj)
Object.keys(obj)

获取所有自有属性,不受枚举影响

1
Object.getOwnPropertyNames()

操作自有属性

1
Object.defineProperty(obj, propName, desc)

阅读此文
post @ 2015-09-08

参考网址

传统检测由于侦测到更改所有文件都进行编译,导致性能问题低下,策略改为根据变动路径更改相关文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
gulp-watch-path

var watchPath =require('gulp-watch-path')

gulp.task('watchjs', function () {
gulp.watch('src/js/**/*.js', function (event) {
var paths = watchPath(event, 'src/', 'dist/')
/* paths { srcPath: 'src/js/log.js', srcDir: 'src/js/', distPath: 'dist/js/log.js', distDir: 'dist/js/', srcFilename: 'log.js', distFilename: 'log.js' } */
gutil.log(gutil.colors.green(event.type) +''+ paths.srcPath)
gutil.log('Dist '+ paths.distPath)

gulp.src(paths.srcPath)
.pipe(uglify())
.pipe(gulp.dest(paths.distDir))
})
})

gulp.task('default', ['watchjs'])

编辑文件时,如果文件中有语法错误时,

会终止运行并报错。
1
2
3
4
5
6
7
8
9
10
11
12
13
```javascript
stream-combiner2

var combined = combiner.obj([
gulp.src(paths.srcPath),
uglify(),
gulp.dest(paths.distDir)
])
combined.on('error', handleError)
// 代替
gulp.src(paths.srcPath)
.pipe(uglify())
.pipe(gulp.dest(paths.distDir))

压缩后的代码不存在换行符和空白符,导致出错后很难调试,好在我们可以使用 sourcemap 帮助调试

1
2
3
4
5
6
7
8
9
var sourcemaps =require('gulp-sourcemaps')
// ...var combined = combiner.obj([
gulp.src(paths.srcPath),
sourcemaps.init(),
uglify(),
sourcemaps.write('./'),
gulp.dest(paths.distDir)
])
// ...

阅读此文
⬆︎TOP