NBA 球馆巡礼:亚特兰大老鹰 - 菲利普斯球馆

基本信息

  • 球队:布鲁克林篮网(Brookyln Nets)
  • 城市:布鲁克林,纽约州
  • 球馆名称:巴克莱中心(Barclays Center)
  • 第一次现场看球日期:
  • 对阵双方: @ 布鲁克林篮网

现场感受

萨克拉门托国王的主场可谓科技感十足!因为是新建的球馆,整个球馆的设备都是相当先进的。就拿球馆中央的大屏幕来说,一般球馆就是四个大屏幕拼接而成,可以让球馆四面的观众都可以看到,但萨克拉门托黄金一号的球馆还在每个大屏幕中间镶嵌了小屏幕作为数据板,小屏幕上是全是数据,大屏幕是只有比赛画面,观球体验可谓 100 分。

除了科技感十足之外,暂停间隙的时间也十分活跃,现场主持人非常会调动观众情绪,安排的各种小游戏、小节目也是非常走心的。对比来看,国王的暂停时间是我见过最有意思的,最不觉得无聊的,甚至还有些期待。所以这也导致观看球迷情绪也非常好,加油声音也是此起彼伏。

说个小插曲,大家都知道,NBA 每场比赛开始前都会演唱国歌,因为我之前没有看过多伦多猛龙的现场比赛,所以以为国歌都是美国国歌。这一次是第一次现场看有多伦多猛龙的比赛,在比赛开始前是首先演奏「加拿大国歌」,然后再是「美国国歌」。由于没有听过加拿大国歌的缘故,一开始演奏的时候一脸蒙圈,不知道这是什么,听了一会儿歌词也猛然发觉,原来这是「加拿大国歌」。

评价

  • 球馆整体评价:好
  • 观球气氛:好

注意事项

  • 我是从机场直接打车到了黄金一号球馆,所以对于自驾和公共交通不是很熟悉,但我看到附近也有公共交通可以抵达。
  • 进入球馆是不能带大包的,而且他们也不提供存包的服务,我只是把包寄存在球馆对面的一个酒店大堂里,这一点的确很麻烦。
  • 萨克拉门托看起来有点落魄,特别是球馆附近的 downtown 地区,人丁稀少而且几乎没有什么商业,如果把一个城市比作一个人的话,萨克拉门托已经是一个耄耋老者了。

现场图片


本文完

电影经典对白

芳华

一代人的芳华已逝,面目全非,虽然他们谈笑如故,但是不难看出岁月对每个人的改变和难掩的失落,倒是刘峰和小萍显得更知足,话虽不多,却待人温和,原谅我不想让你们看到我们老去的样子,就让荧幕留着我们芬芳的年华吧。

我是你爸爸

我清楚地认识到,我这样做不是偶然的,是自己一贯不注意思想改造,忽视了自身的精神文明建设,不能自觉抵制资产阶级思想的侵袭,个人主义恶性膨胀所导致的必然结果。后果是严重的,不但破坏了正常的教学秩序,也伤害了辛勤培育我们的刘老师和广大的教职员工、家长、领导以及全社会对我们寄予殷切期望的工人、农民、知识分子和解放军们的感情。教训是深刻的,也是沉痛的,发人深省的,我要对自己大喝一声:“马车同学,你危险了!”

一地鸡毛

「你失去理智了!」


本文完

我的 NBA 球馆巡礼挑战

这是一篇 NBA 球馆巡礼的汇总,希望自己可以在未来的两到三年的时间里,可以到 NBA 29 个球馆现场观看 30 支球队的比赛。

东部联盟

中部赛区

球队名称 球馆名称 是否去过 第一次日期 日志链接
芝加哥公牛队 United Center N/A N/A
克利夫兰骑士队 Quicken Loans Arena N/A N/A
密尔沃基雄鹿队 BMO Harris Bradley Center N/A N/A
印第安纳步行者队 Bankers Life Fieldhouse N/A N/A
底特律活塞队 Little Caesars Arena N/A N/A

东南赛区

球队名称 球馆名称 是否去过 第一次日期 日志链接
亚特兰大老鹰队 Philips Arena N/A N/A
华盛顿奇才队 Capital One Arena N/A N/A
迈阿密热火队 American Airlines Arena N/A N/A
奥兰多魔术队 Amway Arena N/A N/A
夏洛特黄蜂队 Spectrum Center N/A N/A

大西洋赛区

球队名称 球馆名称 是否去过 第一次日期 日志链接
多伦多猛龙队 Air Canada Centre N/A N/A
布鲁克林篮网 Barclays Center N/A N/A
波士顿凯尔特人队 TD Garden N/A N/A
纽约尼克斯队 Madison Square Garden N/A N/A
费城 76 人队 Wells Fargo Center N/A N/A

西部联盟

西南赛区

球队名称 球馆名称 是否去过 第一次日期 日志链接
孟菲斯灰熊队 FedEx Forum N/A N/A
达拉斯小牛队 American Airlines Center N/A N/A
休斯敦火箭队 Toyota Center N/A N/A
圣安东尼奥马刺队 AT&T Center N/A N/A
新奥尔良鹈鹕队 Smoothie King Center N/A N/A

西北赛区

球队名称 球馆名称 是否去过 第一次日期 日志链接
波特兰开拓者队 Moda Center N/A N/A
俄克拉荷马城雷霆队 Chesapeake Energy Arena N/A N/A
丹佛掘金队 Pepsi Center N/A N/A
犹他爵士队 Vivint Smart Home Arena N/A N/A
明尼苏达森林狼队 Target Center N/A N/A

大西洋赛区

球队名称 球馆名称 是否去过 第一次日期 日志链接
金州勇士队 Oakland Arena N/A N/A
洛杉矶快船队 Staples Center N/A N/A
菲尼克斯太阳队 Talking Stick Resort Arena N/A N/A
萨克拉门托国王队 Golden 1 Center N/A N/A
洛杉矶湖人队 Staples Center N/A N/A

本文完

Vue 学习笔记

Vue.js 介绍

Vue.js 也称为 Vue,读音类似 view。

Vue 有以下特点:

  • 是一个构建用户界面的框架
  • 是一个轻量级 MVVM(Model-View-ViewModel)框架,和 angular、react 类似
  • 数据驱动 + 组件化的前端开发(核心思想)
  • 通过简单的 API 实现响应式的数据绑定和组合的视图组件
  • 更容易上手、小巧

参考:官网文档

第一个 vue 程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<div id="main">
{.{msg}.} //字符串模板
</div>

<script src="./js/vue.js"></script> //引入vue文件
<script>
new Vue({ //创建vue实例
el: '#main', //绑定元素
data: {
msg: 'hello Vue.js'
},
methods:{ //用于存放方法
}
})
</script>

以上就是一个非常简单的 vue 程序。绑定元素这里不但可以使用 id 选择器,我们还可以使用类选择器或者标签选择器。但是,vue2.0 中不允许将 vue 实例挂在到 html 或者 body 元素上。

常用指令

指令用来扩展 HTML 功能。vue 内置了很多指令。

v-model

实现双向数据绑定,实时监控数据变化,一般用于表单。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 <div id="main">
<input type="text" v-model="content">

<br> {.{ content111 }.}
</div>

<script src="./js/vue.js"></script>
<script>
new Vue({
el: '#main',
data: {
content: ''
}
})
</script>

在这里,使用v-model指令将输入框的值与 vue 实例中的 content 进行绑定。此后,二者中的任一值发生变化,另一个值都会跟随变化。

v-for

用于遍历数组、对象等。

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
<div id="main">
<ul>
<li v-for="item in arr"> //遍历数组
{.{item}.}
</li>
</ul>

<ul>
<li v-for="item in obj"> //遍历对象
{.{item}.}
</li>
</ul>

<ul>
<li v-for="(value,key) in obj"> //键值循环,数组也适用,注意key在后面
{.{key}.}----{.{value}.}
</li>
</ul>
</div>

<script src="./js/vue.js"></script>
<script>
new Vue({
el: '#main',
data: {
arr: [1, 2, 3, 4, 5, 6],
obj: {
name: 'hedawei',
age: 22,
gender: 'man'
}
}
})
</script>

v-on

用于绑定事件,用法:v-on: 事件 =”函数”。

示例:点击事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<div id="main">
<button type="button" v-on:click="showHello()">点击显示</button>
<br>
{.{msg}.}
</div>

<script src="./js/vue.js"></script>
<script>
new Vue({
el: '#main',
data: {
msg:''
},
methods: {
showHello() {
this.msg = 'Hello Vue.js';
}
}
})
</script>

this指向当前 vue 实例,由此可获取实例的其他属性。除了点击事件外还有很多其他事件,具体参考官网 API。

v-show

用来显示或隐藏元素,v-show 是通过 display 实现。当v-show的值为 true 时显示,为 false 时隐藏。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<div id="main">
<button type="button" v-on:click="change()">隐藏</button>
<div style="width:100px;height:100px;background:red" v-show="flag"></div>
</div>

<script src="./js/vue.js"></script>
<script>
new Vue({
el: '#main',
data: {
flag: true
},
methods: {
change() {
this.flag = !this.flag;
}
}
})
</script>

事件

之前说了一些关于事件的指令,这里详细学习一下事件的相关知识。

事件简写

之前的事件都是这样的写法:v-on:click="showHello()"`,vue 提供了一种简写方式:
@click="showHello()"

事件对象 $event

我们可以通过事件对象取得事件相关信息,如事件源、事件类型、偏移量。

下面这个例子通过事件对象取得按钮的值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<div id="main">
<button type="button" @click="print($event)">点击显示按钮的值</button>
<br> {.{msg}.}
</div>

<script src="./js/vue.js"></script>
<script>
new Vue({
el: '#main',
data: {
msg: ''
},
methods: {
print(e) {
this.msg = e.target.innerHTML;
}
}
})
</script>

事件冒泡与事件默认行为

这里需要讨论阻止事件冒泡与阻止默认行为,原生 js 阻止事件冒泡首先得取得事件对象,然后调用事件对象的stopPropagation方法。在 vue 里,则不需要依赖于事件对象,只需要调用相应的事件修饰符stop即可:

1
@click.stop = "print()"

阻止事件默认行为和阻止事件冒泡基本一致,在 vue 里也有十分便利的操作方法:

1
@click.prevent = "print()"

键盘事件

vue 里内置了一些键盘事件,便于开发者操作。语法如下:

1
2
@keydown.13 = "print()"
@keydown.enter = "print()"

除了回车事件外,还有很多其他键盘事件,例如下:`@keydown.38=”print()”`。还有一些其他键盘事件,具体参考官方文档。

默认没有 @keydown.a/b/c… 事件,可以全局自定义键盘事件,也称为自定义键码或自定义键位别名:

1
2
3
4
5
6
7
8
9
Vue.config.keyCodes = {
v: 86,
f1: 112,
// camelCase 不可用
mediaPlayPause: 179,
// 取而代之的是 kebab-case 且用双引号括起来
"media-play-pause": 179,
up: [38, 87]
}

除了stoppreventkeyCode这些事件修饰符以外,还有一些比较常用:

  • .native - 监听组件根元素的原生事件。
  • .once - 只触发一次回调。

属性

vue 提供了绑定属性的方法:v-bind:属性名="",这样我们即可动态的改变属性值。

属性简写

属性和事件一样,也有简写方式::属性名=""

class 属性和 style 属性

绑定 class 和 style 属性时的语法比较复杂。

变量形式

html 部分:

1
<p :class="myClass">Hello vue.js</p>

对应的 vue 的 data 部分:

1
2
3
data:{
myClass:className
}

数组形式,同时引入多个类

html 部分:

1
<p :class="[myClass1,myClass2]">Hello vue.js</p>

对应的 vue 的 data 部分:

1
2
3
4
data:{
myClass1:className1,
myClass2:className2,
}

JSON 形式(常用)

html 部分:

1
<p :class="{className1:true,className2:false}">Hello vue.js</p>

变量引用 JSON 形式

html 部分:

1
<p :class="myClass">Hello vue.js</p>

对应的 vue 的 data 部分:

1
2
3
4
5
data:{
myClass:{
className:true
}
}

style 的用法和 class 的用法基本一致,但是不常用。

模板

Vue.js 使用基于 HTML 的模板语法,可以将 DOM 绑定到 Vue 实例中的数据。模板就是{.{ }.},用来进行数据绑定,显示在页面中,也称为 Mustache 语法。

数据绑定的方式

双向数据绑定

使用v-model指令,前面已经学习过。

单向数据绑定
使用两对大括号 {.{}.}

这个在之前也经常使用,但是有一个缺点,就是 vue 实例需要长时间编译时会在页面中出现{.{}.}(闪烁现象)。vue 提供了一个解决办法:使用v-cloak配合 css。

1
2
3
4
5
6
7
8
9
//html内容
<div id="app" v-cloak>
{.{msg}.}
</div>

//css内容
[v-cloak] {
display: none;
}

使用指令 v-text、v-html

v-text也可达到与使用v-cloak相同的效果。

1
2
3
//html内容
<div id="app" v-text="msg">
</div>

v-html会将文本中的 html 解析为 html 标签,然后渲染到页面中。

1
2
3
4
5
6
7
8
//html内容
<div id="app" v-html="msg">
</div>

//vue实例中data部分内容
data: {
msg: 'hello<mark>vue.js<mark>'
},

这里的 vue.js 会有一个黄色的背景颜色。

过滤器

过滤器用来过滤模型数据,在显示之前进行数据处理和筛选。语法:{.{ data | filter1(参数) | filter2(参数)}.}

vue1.0 中内置了很多过滤器,但是在 2.0 中全部删除了。使用过滤器我们可以通过使用第三方库:lodash、date-fns 日期格式化、accounting.js 货币格式化。或者我们可以自定义过滤器。

自定义过滤器

过滤器分为全局过滤器和局部过滤器。

全局过滤器

使用全局方法 Vue.filter(过滤器ID,过滤器函数)。

示例:

1
2
3
4
5
<p>{.{8|addZero}.}</p>//数据会自动作为传过去

Vue.filter('addZero', data => {
return data > 10 ? data : '0' + data;
});

有时过滤器也要传递自己的参数:

1
2
3
4
5
<p>{.{12.3456|number(3)}.}</p>

Vue.filter('number', (data,n) => {
return data.toFixed(n);
});

局部过滤器

局部过滤器的使用方法与全局过滤器的使用方法一致。

不过过滤器写在 vue 实例中 filters 选项中。

1
2
3
4
5
6
7
8
9
new Vue({
el:'#app',
data:{},
filters:{
number:data => {
//具体操作
}
}
})

vue 生命周期

vue 实例从创建到销毁的过程,称为生命周期,共有八个阶段。

这八个阶段里分别有一个叫做钩子函数的实例选项。供用户在相应的阶段对其进行操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
beforeCreate(){  //组件实例刚刚创建,还未进行数据观测和事件配置

},
created(){ //实例已经创建完成,并且已经进行数据观测和事件配置

},
beforeMount(){//模板编译之前,还没挂载

},
mounted(){ //模板编译之后,已经挂载,此时才会渲染页面,才能看到页面上数据的展示

},
beforeUpdate(){//组件更新之前

},
updated(){//组件更新之后

},
beforeDestroy(){//组件销毁之前

},
destroyed(){ //组件销毁之后

}

这几个钩子中,最常用的是created()mounted()

计算属性

计算属性也是用来存储数据,但具有以下几个特点:

  • 数据可以进行逻辑处理操作
  • 对计算属性中的数据进行监视

基本用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<div id="app">
{.{addZero}.}
</div>

new Vue({
el: '#app',
data: {
num: 8
},
computed: {
//这是计算属性的get方法,用于取值
addZero() {
return this.num > 10 ? this.num : '0' + this.num;
}
}
})

这里的addZeronum一样,都是属性。不过addZero是依赖于num、进行计算后的值。一旦num的值发生变化,addZero的值也会随之变化。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<div id="app">
{.{num}.}----{.{addZero}.}
<br>
<button type="button" @click="change">点击改变num</button>
</div>

new Vue({
el: '#app',
data: {
num: 8
},
methods: {
change: () => {
this.num++;
}
},
computed: {
addZero:() => {
return this.num > 10 ? this.num : '0' + this.num;
}
}
})

一旦我们点击按钮改变num的值,那么因为计算属性实时监测依赖项,addZero也会跟着发生变化。

计算属性 vs 方法

将计算属性的 get 函数定义为一个方法也可以实现和计算属性类似的功能。那么二者之间有什么区别?

  • 区别一:计算属性是基于它的依赖进行实时更新的,方法则是调用才更新
  • 区别二:计算属性是有缓存的,只要相关依赖没有改变,多次访问计算属性得到的值是之前缓存的计算结果,不会多次执行。操作一个没有依赖项的值也是如此。
    官方文档给出了下面这个例子:
    1
    2
    3
    4
    5
    computed: {
    now: function () {
    return Date.now()
    }
    }

计算属性存在缓存,这里的now值不会发生变化。

get 和 set

计算属性由两部分组成:get 和 set,分别用来获取计算属性和设置计算属性。默认只有 get,如果需要 set,要自己添加。

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
     <div id="app">
{.{num}.}----{.{addZero}.}
<br>
<button type="button" @click="change(5)">点击改变num</button>
</div>

new Vue({
el: '#app',
data: {
num: 8
},
methods: {
change(newNumber) {
this.addZero = newNumber;
}
},
computed: {
addZero: {
get() {
return this.num > 10 ? this.num : '0' + this.num;
},
set(newNum) {
this.num = newNum
}
}
}
})

我们再change方法中改变addZero属性的值的时候会自动调用它的 set 方法。

实例属性和方法

vue 中给实例和属性提供了若干属性和方法。

属性

获取属性的语法:实例名.属性名
以下是常用的属性:

  • vm.$el: 获取 vue 实例关联的元素 DOM,进而可以对其进行操作
  • vm.$data: 获取数据对象 data
  • vm.$options:获取选项,自定义的选项也可以在这里获取。
  • vm.$refs:获取所有添加 ref 属性的元素 dom 对象,进而可以对其进行操作

方法

vm.$mount()

手动挂载 vue 实例

1
2
3
4
5
var vm=new Vue({
data:{
msg:'Hello vue.js'
}
}).$mount('#app');

vm.$destroy()

销毁实例

1
vm.$destroy(); //销毁实例所占的内存空间

vm.$nextTick(callback)

在 DOM 更新完成后再执行回调函数,一般在修改数据之后使用该方法,以便获取更新后的 DOM

1
2
3
4
5
6
7
8
9
10
11
12
13
var vm=new Vue({
data:{
msg:'Hello vue.js'
}
}).$mount('#app');

//修改数据
vm.msg='foo';

console.log(vm.$refs.title.textContent); //Hello vue.js
vm.$nextTick(function(){
console.log(vm.$refs.title.textContent); //foo
});

DOM 还没更新完,Vue 实现响应式并不是数据发生改变之后 DOM 立即变化,需要按一定的策略进行 DOM 更新,需要时间!使用$nextTick方法等 DOM 更新完再获取数据。

vm.$set(target,key,value)

通过 vue 实例的 $set 方法为对象添加属性,可以实时监视。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<div id="app">
{.{user.name}.}<br> {.{user.age}.}
<br>
<button type="button" @click="addAge">添加属性</button>
</div>

var vm = new Vue({
data: {
msg: 'Hello vue.js',
user: {
name: 'hedawei',
gender: 'man'
}
},
methods: {
addAge() {
/* this.user.age = 22; */
this.$set(this.user, 'age', 22);
}
}
}).$mount('#app');

方法中使用原始的添加属性方法的话不会在模板中显示。使用$set方法会实时监控数据,然后添加。

vm.$watch(监听的属性,callback)

监控 vue 实例的变化

1
2
3
vm.$watch('msg', (newValue, oldValue) => {
console.log('msg被修改啦,原值:' + oldValue + ',新值:' + newValue);
});

如果需要监控深度数据变化(例如监控一个对象中的某个属性),则需要在选项中添加{deep:true}

自定义指令

自定义指令分为自定义全局指令和自定义局部指令。

自定义全局指令

使用全局方法 Vue.directive (指令ID,定义对象)。注:使用指令时必须在指名名称前加前缀 v-,即v-指令名称`

简单示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Vue.directive('hello',{
bind(){ //常用!!
alert('指令第一次绑定到元素上时调用,只调用一次,可执行初始化操作');
},
inserted(){
alert('被绑定元素插入到DOM中时调用');
},
update(){
alert('被绑定元素所在模板更新时调用');
},
componentUpdated(){
alert('被绑定元素所在模板完成一次更新周期时调用');
},
unbind(){
alert('指令与元素解绑时调用,只调用一次');
}
});

这里定义了一个名为hello的指令,指令定义函数提供了几个钩子函数,分别在不同的时期生效。我们像下面这样使用这个指令:

1
<p v-hello>hello vue.js</p>

大多数情况下,我们只需要使用bindupdate钩子函数。vue 里提供了函数的简写形式:

1
2
3
Vue.directive('hello', function () {
alert("hello vue.js");
})

钩子函数有两个常用的参数elbindingel是绑定的 DOM 对象,binding是一个对象,包含若干属性。

拿到 DOM 对象,我们就可以对 DOM 进行一些操作。

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
<p v-hello="msg">hello vue.js</p>

Vue.directive('hello', function (el,binding) {
el.style.color = "red";

//属性name是指令的名字(不带v-)
console.log(binding.name); //hello
//属性value是传递给指令的值
console.log(binding.value); //alice
//属性expression是指令值的字符串形式(个人感觉就是类似变量名)
console.log(binding.expression); //msg
//属性arg是传递给指令的参数(和传值写在一起容易令初学者困惑,下面分开写
//合在一起写的写法是<p v-hello:123="msg">hello vue.js</p>)
//<p v-hello:123>hello vue.js</p>
console.log(binding.arg); //123
//属性modifiers是一个包含修饰符的对象。
//与传参传值合在一起的写法是 <p v-hello:123.bar="msg">hedawei</p>
//<p v-hello.bar>hello vue.js</p>
console.log(binding.modifiers); //{bar:true}
})

var vm = new Vue({
el: '#app',
data: {
msg: 'alice'
}
})

局部自定义指令

局部自定义指令写在实例的directives选项中。

1
2
3
4
5
6
7
8
9
10
11
12
13
 var vm = new Vue({
el: '#app',
data: {
msg: 'alice'
},
methods: {
},
directives: {
word: function(el, binding) {
console.log(binding.name);
}
}
})

其他用法与全局自定义指令一致。

过渡(动画)

Vue 在插入、更新或者移除 DOM 时,提供多种不同方式的应用过渡效果。本质上还是使用 CSS3 动画:transition、animation 属性。

基本用法

使用 transition 组件,将要执行动画的元素包含在该组件内:

1
2
3
<transition name="fade">
运动的元素
</transition>

我们需要为其定义一个name属性,以便后面为其添加 css 样式。

动画有 6 个 CSS 类名,下面结合的例子说明:

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
<style>
button {
display: block;
margin: 20px auto;
}

p {
width: 100px;
height: 100px;
background-color: red;
margin: 0 auto;
}

.fade-enter-active,
.fade-leave-active { //定义整个过渡期间的效果
transition: all 2s ease;
}

.fade-enter-to { //定义过渡进入的最终效果
opacity: 1;
width: 100px;
height: 100px;
}

.fade-leave-to { //定义过渡离开的最终效果
opacity: 0;
width: 50px;
height: 50px;
}

.fade-enter { //定义过渡进入的开始效果
opacity: 0;
width: 50px;
height: 50px;
}
</style>

<div id="app">
<button type="button" @click="flag = !flag">点 击</button>
<transition name="fade">
<p v-show="flag">
</p>
</transition>
</div>

<script>
new Vue({
el: '#app',
data: {
flag: false
}
});
</script>

钩子函数

vue 中给过渡的不同时期提供了不同的钩子函数。

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
<transition name="fade" @before-enter="beforeEnter" @enter="enter" @after-enter="afterEnter" @before-leave="beforeLeave" @leave="leave" @after-leave="afterLeave">
<p v-show="flag">
</p>
</transition>

new Vue({
methods: {
beforeEnter(el) {
alert('动画进入之前');
},
enter(el) {
alert('动画进入');
},
afterEnter(el) {
alert('动画进入之后');
},
beforeLeave(el) {
alert('动画离开之前');
},
leave(el) {
alert('动画离开');
},
afterLeave(el) {
alert('动画离开之后');
}
}
});

在这不同的时期,我们可以取到过渡元素的 DOM 对象,从而对其进行操作。

多元素过渡

上面的标签只适用于单元素过渡。若要对多元素进行过渡,则需要使用标签,并且绑定key属性,设置不同的值。

1
2
3
4
5
6
7
<button type="button" @click="flag = !flag">点 击</button>
<transition-group name="fade">
<p v-show="flag" :key="1">
</p>
<p v-show="flag" :key="2">
</p>
</transition-group>

结合第三方库一起使用(animate.css)

我们可以使用 vue 的自定义过渡类名结合第三方动画库实现自定义动画效果。这六个自定义类名和 vue 内置的类名类似:

  • enter-class
  • enter-active-class
  • enter-to-class
  • leave-class
  • leave-active-class
  • leave-to-class

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
p {
width: 300px;
height: 300px;
background-color: red;
margin: 0 auto;
}

<div id="app">
<button type="button" @click="flag = !flag">点 击</button>
<transition enter-active-class="animated tada" leave-active-class="animated bounceOutRight">
<p v-show="flag">
</p>
</transition>
</div>

<script>
new Vue({
el: '#app',
data: {
flag: false
}
});
</script>

组件

什么是组件

组件(Component)是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码组件是自定义元素(对象)。

创建组件的两种方式

官方推荐组件标签名是使用-连接的组合词,例如:<my-hello></my-hello>

使用构造器创建组件

使用这种方式创建组件首先需要使用Vue.extend()创建一个组件构造器,然后使用Vue.component(标签名,组件构造器),根据组件构造器来创建组件。

1
2
3
4
5
6
7
8
9
10
11
//1.创建构造器
var MyComponent=Vue.extend({
template:'<h3>Hello World</h3>'
});
//2.创建组件
Vue.component('my-hello',MyComponent);

//3.使用组件
<div id="app">
<my-hello></my-hello>
</div>

这种创建组件的方式比较麻烦,使用的较少。

直接创建组件

使用Vue.component(标签名,组件模板)`,根据组件构造器来创建组件。

1
2
3
4
5
6
7
8
9
//1.创建组件
Vue.component('my-world', {
template: '<h2>hello vue.js</h2>'
});

//2.使用组件
<div id="app">
<my-world></my-world>
</div>

组件的分类

组件分为全局组件和局部组件。

全局组件

使用Vue.component()创建的组件都是全局组件。这样的组件在任何组件内都能使用。上面我们创建就是全局组件。

局部组件

局部组件一般都是定义在实例的选项中,称为实例的子组件。相应的,实例也被称为父组件。

1
2
3
4
5
6
7
8
9
10
11
12
13
//1.定义组件
new Vue({
el: '#app',
components: {
dawei: {
template: '<h2>my name is dawei</h2>'
}
}
});
//2.使用组件
<div id="app">
<dawei></dawei>
</div>

引用模板

很多时候我们的template模板中需要存放很多标签内容,这样的话写起来会很麻烦。这时候我们可以使用template标签。

用法如下:

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
<template id="wbs">    //使用template标签
<div>
<h2>hello {.{msg}.}</h2>
<ul>
<li v-for="value in arr">
{.{value}.}
</li>
</ul>
</div>
</template>

new Vue({
el: '#app',
components: {
'my-dawei': {
template: '#wbs', //选择template标签
data() {
return {
msg: 'vue.js',
arr: ["a", "b", "c", "d"]
}
}
}
}
});

这里涉及到的几个知识点得着重提一下:

  • template模板中,所有的元素必须放置在一个根元素中,要不然会报错。例子中我们将元素放置在了<div>标签中。
  • 组件中的data选项必须是一个函数类型,使用return返回所有的数据。

动态组件

很多时候项目中需要在某一个地方动态的使用不同的组件,这时候就需要使用动态组件。
动态组件的使用需要绑定is属性:

1
<component :is="flag"></component>

简单示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//点击按钮显示不同的组件
<div id="app">
<button type="button" @click="flag='my-a'">显示a组件</button>
<button type="button" @click="flag='my-b'">显示b组件</button>

<component :is="flag"></component> //传入flag
</div>

new Vue({
el: '#app',
data: {
flag: 'my-a' //给flag赋值
},
components: {
'my-a': {
template: '<p>我是a组件</p>',
},
'my-b': {
template: '<p>我是b组件</p>'
}
}
});

keep-alive 组件

使用keep-alive组件缓存非活动组件,可以保留状态,避免重新渲染,默认每次都会销毁非活动组件并重新创建。

使用范例:

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
<keep-alive>
<component :is="flag"></component>
</keep-alive>

<div id="app">
<button type="button" @click="flag='my-x'">x</button>
<button type="button" @click="flag='my-y'">y</button>
<keep-alive>
<component :is="flag"></component>
</keep-alive>
</div>

new Vue({
el: '#app',
data: {
flag: 'my-x'
},
components: {
'my-x': {
template: '<p>{.{x}.}</p>',
data() {
return {
x: Math.random()
}
}
},
'my-y': {
template: '<p>{.{y}.}</p>',
data() {
return {
y: Math.random()
}
}
}
}
});

这样的话,第一次产生的随机数就会被缓存,再次切换的时候也不会发生改变。

组件间数据传递

父子组件

在一个组件内部定义另一个组件,那么这对组件称为父子组件。子组件只能在父组件内部使用。默认情况下,每个组件实例的作用域是独立的,子组件无法访问父组件中的数据,同样,父组件也无法访问子组件中的数据。

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
<div id="app">
<my-a></my-a>
<!-- 父组件 -->
</div>

<template id="a">
<div>
<p>{.{msg}.}</p>
<my-b></my-b> <!-- 在父组件中调用子组件 -->
</div>
</template>

<template id="b">
<div>
<p>{.{mydata}.}</p>
</div>
</template>

<script>
new Vue({ //根组件
el: '#app',
components: { //子组件写在components选项中
"my-a": { //b组件的父组件
template: "#a",
data() {
return {
msg: '我是父组件',
}
},
components: { //子组件写在父组件的components选项中
"my-b": {
template: "#b",
data() {
return {
mydata: "我是子组件"
}
}
}
}
}
}
});
</script>

组件间数据传递(通信)

子组件访问父组件的数据

步骤:

  • a、调用子组件时,绑定想要获取的父组件中的数据
  • b、在子组件内部,使用 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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<div id="app">
<my-a></my-a>
</div>

<template id="a">
<div>
<p>{.{msg}.}</p>
<p>这是要传递给子组件的值:{.{myname}.}</p>
<my-b :name="myname"></my-b> <!-- 绑定子组件想要获取的数据 -->
</div>
</template>

<template id="b">
<div>
<p>{.{mydata}.}</p>
<p>这是父组件传递过来的数据:{.{name}.}</p>
</div>
</template>

<script>
new Vue({
el: '#app',
data: {},
components: {
"my-a": {
template: "#a",
data() {
return {
msg: '我是a组件',
myname: '子组件b你好,我是父组件a'
}
},
components: {
"my-b": {
template: "#b",
data() {
return {
mydata: "我是b组件"
}
},
props: ["name"] //子组件使用props声明想要获取的数据
}
}
}
}
});
</script>
父组件访问子组件的数据

步骤:

  • a 在子组件中使用 vm.$emit(事件名, 数据) 触发一个自定义事件,将数据发送给父组件,事件名自定义
  • b 父组件在使用子组件的地方监听子组件触发的事件,并在父组件中定义方法,用来获取数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//子组件‘my-b’内部
methods:{
send(){//使用$emit()触发一个事件,发送数据,this指当前子组件实例
this.$emit('e-world', this.senddata);
}
}

//在调用子组件的地方监听子组件触发的事件,调用自己的方法获取数据
<my-b @e-world="getData"></my-b>


methods: {
getData(data) { //参数是子组件传递过来的数据
this.revicedata = data;
}
}
单向数据流

props 是单向数据绑定的,当父组件数据发生变化时,将传递给子组件,但是不会反过来。而且不允许子组件直接修改父组件中的数据,强制修改会报错。

解决方案:

  • 如果子组件想把它作为局部数据来使用,可以将数据存入另一个变量中再操作,不影响父组件中的数据
  • 如果子组件想修改数据并且同步更新到父组件,两个方法:
  • 使用.sync显式地触发一个更新事件(1.0 版本中支持,2.0 版本中不支持,2.3 版本又开始支持)
1
2
3
4
5
//使用.sync
<my-b :name.sync="myname"></my-b>

//子组件修改父组件传入的值name,触发update更新事件
this.$emit('update:name', "vuejs");
  • 可以将父组件中的数据包装成对象,然后在子组件中修改对象的属性 (因为对象是引用类型,指向同一个内存空间),推荐使用这种方式。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 data() {
return { //将要传递的数据放入message对象中
message: {
hello: '子组件b你好,我是父组件a'
}
}
}

<my-b :message="message"></my-b> //传递这个对象给子组件

methods: { //在子组件内部修改这个值,这样就会同步传递给父组件。
edit() {
this.message.hello = "hahahahh";
}
}
非父子组件间的通信

非父子组件间的通信,可以通过一个空的 Vue 实例作为中央事件总线(事件中心),用它来触发事件和监听事件,从而实现非父子组件间的通信。

1
2
3
4
5
6
7
8
9
10
11
12
13
var Event = new Vue();    //空vue实例

methods: {
send() { //触发emit事件
Event.$emit("hello", this.asmsg);
}
}

mounted() { //在子组件的钩子函数中监听该事件
Event.$on('hello', data => { //获取值
this.bsmsg = data;
})
}

slot 内容分发

用来获取组件中的原内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var vm = new Vue({
el: '#app',
components: {
'my-hello': {
template: '#hello'
}
}
});

<div id="app">
<my-hello>hello vue.js</my-hello>
</div>


<template id="hello">
<div>
<slot>如果没有原内容,则显示该内容</slot>
</div>
</template>

如果组件标签中没有内容就会显示 slot 中的内容,这也就是所谓的单个插槽。

还可以对显示的内容进行分组,这就是具名插槽,可以操作标签组中的内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<div id="app">
<my-hello>
<ul slot="s1">
<li>aaa</li>
<li>bbb</li>
<li>ccc</li>
</ul>
<ol slot="s2">
<li>111</li>
<li>222</li>
<li>333</li>
</ol>
</my-hello>
</div>

<template id="hello">
<div>
<slot name="s2"></slot> //为插槽指定名称 将名为s2的内容放置在这里
<p>hello vue.js</p>
<slot name="s1"></slot> //将名为s1的内容放置在这里
</div>
</template>

这样,就可以对组件中的内容实时操作。

vue-router

简介

我们经常使用 vue 开发单页面应用程序(SPA)。在开发 SPA 过程中,路由是必不可少的部分,vue 的官方推荐是 vue-router。单页面应用程序看起来好像是一个页面,其实是在一个页面中切换不同的 html 部分,从而达到所谓的单页面, 在这切换之中,就需要使用路由来实现不同的页面内容的展现。

基本用法

使用步骤

vue-router 的基本使用步骤如下:

  • 定义需要切换的组件
  • 配置路由,规定路径到组件的映射关系
  • 创建路由实例
  • 将路由挂载到 vue 实例
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
//1.定义组件,用于路由切换
var Home = {
template: '<div>我是主页</div>'
}
var News = {
template: '<div>我是新闻</div>'
}

//2.配置路由
const routes = [{
path: '/home',
component: Home
},{
path: '/news',
component: News
},{ //这一路由配置用于首次访问或者找不到所请求路由,自动跳转home页
path: '*',
redirect: '/home'
}];

//3.创建路由实例
var router = new VueRouter({
routes //传入配置好的路由信息
});

//4.挂载路由到根组件
new Vue({
el: '#app',
router
});

这样我们就配置好了一个完整的路由。在切换组件的时候会根据路由加载不同的组件。我们使用类似 a 标签的<router-link to="url"></router-link>触发组件的切换,to属性存放的是路径。使用<router-view></router-view>来显示所切换组件。

1
2
3
4
5
6
<div id="app">
<router-link to="/home">主页</router-link>
<router-link to="/news">新闻</router-link>

<router-view></router-view>
</div>

这样我们就可以实现主页和新闻组件间的切换。

参数传递

可能我们需要向所切换组件传递参数。vue 提供了两种向组件传递参数的方式。

  • 查询字符串的形式
  • /home?name=dawei&pwd=666
  • 在组件内部使用{.{$route.query}.}接收参数
  • rest 风格
  • /news/param1/param2
  • 在组件内部使用{.{$route.params}.}接收参数
路由嵌套

路由还可以多层嵌套使用,使用children属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
path:'/user',
component:User,
children:[
{
path:'login',
component:Login
},
{
path:'regist',
component:Regist
}
]
}

子路由项路径不要使用/开头,以/开头的嵌套路径会被当作根路径。

在组件中就可以使用该路由:

1
2
3
4
5
6
7
8
<div>
<h3>用户信息</h3>
<ul>
<router-link to="/user/login">用户登陆</router-link>
<router-link to="/user/regist">用户注册</router-link>
</ul>
<router-view></router-view>
</div>

注意路径的写法。

路由实例的方法

这里学习两个路由实例的方法:router.push()router.replace()

  • router.push():添加路由,功能上与相同
  • router.replace(): 替换路由,不产生历史记录
1
2
router.push({path:'home'})
router.replace({path:'user'})

路由结合动画

路由结合动画使用很简单,我们可以用 组件给它添加一些动画效果:

1
2
3
<transition>
<router-view></router-view>
</transition>

单文件组件

.vue 文件

.vue文件称为单文件组件,是 Vue.js 自定义的一种文件格式,一个. vue 文件就是一个单独的组件,在文件内封装了组件相关的代码:html、css、js 代码。

.vue文件由三部分组成:<template><style><script>:

1
2
3
4
5
6
7
8
9
10
11
<template>
//html
</template>

<script>
//js
</script>

<style>
//css
</style>

vue-loader

浏览器本身并不认识. vue 文件,此时需要 vue-loader 对. vue 文件进行加载解析,。类似的 loader 还有许多,如:html-loader、css-loader、style-loader、babel-loader 等。需要注意的是 vue-loader 是基于 webpack 的。

webpack

webpack 是一个前端资源模板化加载器和打包工具,它能够把各种资源都作为模块来使用和处理。实际上,webpack 是通过不同的 loader 将这些资源加载后打包,然后输出打包后文件。简单来说,webpack 就是一个模块加载器,所有资源都可以作为模块来加载,最后打包输出。

vue-cli

简介

vue-cli 是一个 vue 脚手架,可以帮助我们快速构造项目结构,减少开发人员开发阻力。vue-cli 集成了多种版本:

  • simple :比较简单
  • webpack :包含 ESLint 代码规范检查和 unit 单元测试等
  • webpack-simple: 没有代码规范检查和单元测试
  • browserify: 使用的也比较多
  • browserify-simple

安装、操作步骤

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//安装vue-cli,配置vue命令环境 
cnpm install vue-cli -g
vue --version
vue list

// 初始化项目,生成项目模板
vue init 模板名 项目名

//进入生成的项目目录,安装模块包
cd vue-cli-demo
cnpm install

//运行
npm run dev //启动测试服务
npm run build //将项目打包输出dist目录,项目上线的话要将dist目录拷贝到服务器上

文件介绍

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
.
|-- build // 项目构建(webpack)相关代码
| |-- build.js // 生产环境构建代码
| |-- check-version.js // 检查node、npm等版本
| |-- dev-client.js // 热重载相关
| |-- dev-server.js // 构建本地服务器
| |-- utils.js // 构建工具相关
| |-- webpack.base.conf.js // webpack基础配置
| |-- webpack.dev.conf.js // webpack开发环境配置
| |-- webpack.prod.conf.js // webpack生产环境配置
|-- config // 项目开发环境配置
| |-- dev.env.js // 开发环境变量
| |-- index.js // 项目一些配置变量
| |-- prod.env.js // 生产环境变量
| |-- test.env.js // 测试环境变量
|-- src // 源码目录
| |-- components // vue组件
| |-- store // 状态管理
| |-- App.vue // 页面入口vue文件
| |-- main.js // 程序入口文件,加载各种公共组件
|-- static // 静态文件
| |-- data
|-- .babelrc // ES6语法编译配置
|-- .editorconfig // 定义代码格式
|-- .gitignore // git上传需要忽略的文件格式
|-- README.md // 项目说明
|-- favicon.ico //网页图标
|-- index.html // 入口页面
|-- package.json // 项目配置信息
.

此列表拷贝自: 这里

Reference


This is the end of post

HTML & CSS design and build websites

Introduction

This post is the note for book HTML & CSS design and build websites.

Chapter 1: Structure

  • HTML pages are text documents.
  • HTML uses tags, which are characters that sit inside angled brackets. They act like containers and tell you something about the information that lies between them.
  • Tags are often referred to as elements.
  • Tags usually come in pairs. The opening tag denotes the start of a piece of content; the closing tag denotes the end.
  • Opening tags can carry attributes, which tell us more about the content of that element.
  • Attributes require a name and a value.
  • To learn HTML you need to know what tags are available for you to use, what they do, and where they can go.

Chapter 2: Text

  • HTML elements are used to describe the structure of the page (e.g. headings, subheadings, paragraphs).
  • They also provide semantic information (e.g. where emphasis should be placed, the definition of any acronyms used, when given text is a quotation).

Chapter 3: Lists

  • There are three types of HTML lists: ordered, unordered, and definition.
  • Ordered lists use numbers.
  • Unordered lists use bullets.
  • Definition lists are used to define terminology.
  • Lists can be nested inside one another.
  • Links are created using the <a> element.
  • The <a> element uses the href attribute to indicate the page you are linking to.
  • If you are linking to a page with your own site, it is best to use relative links rather than qualified URLs.
  • You can create links to open email programs with an email address in the “to” field.
  • You can use the id attribute to target elements within a page that can be linked to.

Chapter 5: Images

  • The <img> element is used to add images to a web page.
  • You must always specify and an src attribute to indicate the source of an image and an alt attribute to describe the content of an image.
  • You should save images at the size you will be using them on the web page and in the appropriate format.
  • Photographs are best saved as JPEGs; illustrations or logos that use flat colors are better saved as PNGs.

Chapter 6: Tables

  • The <table> element is used to add tables to a web page.
  • A table is drawn out row by row. Each row is created with the <tr> element.
  • Inside each row there are a number of cells represented by the <td> element (or <th> if it is a header).
  • You can make cells of a table span more than one row or column using the rowspan and colspan attributes.
  • For long tables you can split the table into a <thead>, <tbody>, and <tfoot>.

Chapter 7: Forms

  • Whenever you want to collect information from visitors you will need a form, which lives inside a <form> element.
  • Information from a form is sent in name/value pairs.
  • Each form control is given a name, and the text the user types in or the values of the options they select are sent to the server.
  • HTML5 introduces new form elements which make it easier for visitors to fill in forms.

Chapter 8: Extra Markup

  • DOCTYPES tell browsers which version of HTML you are using.
  • You can add comments to your code between the <! -- and --> markers.
  • The id and class attributes allow you to identify particular elements.
  • The <div> and <span> elements allow you to group block-level and inline elements together.
  • <iframes> cut windows into your web pages through which other pages can be displayed.
  • The <meta> tag allows you to supply all kinds of information about your web pages.
  • Escape characters are used to include special characters in your pages such as <, >, and ©.

Chapter 9: Flash, Video & Audio

  • Flash allows you to add animations, video and audio to the web.
  • Flash is not supported on iPhone and iPad.
  • HTML5 introduces new <video> and <audio> elements for adding video and audio to web pages, but these are only supported in the latest browsers.
  • Browsers that support the HTML5 elements do not all support the same video and audio formats, so you need to supply your files in different formats to ensure that everyone can see/hear them.

Chapter 10: Introducing CSS

  • CSS treats each HTML element as if it appears inside its own box and uses rules to indicate how that element should look.
  • Rules are made up of selectors (that specify the elements the rule applies to) and declarations (that indicate what these elements should look like).
  • Different types of selectors allow you to target your rules at different elements.
  • Declarations are made up of two parts: the properties of the element that you want to change, and the values of those properties. For example, the font-family property sets the choice of font, and the value arial specifies Arial as the preferred typeface.
  • CSS rules usually appear in a separate document, although they may appear within an HTML page.

Chapter 11: Color

  • Color not only brings your site to life, but also helps convey the mood and evokes reactions.
  • There are three ways to specify colors in CSS: RGB values, hex values, and color names.
  • Color pickers can help you find the color you want.
  • It is important to ensure that there is enough contrast between any text and the background color (otherwise people will not be able to read your content).
  • CSS3 has introduced an extra value for RGB colors to indicate opacity. It is known as RGBA.
  • CSS3 also allows you to specify colors as HSL valued, with an optional opacity value. It is known as HSLA.

Chapter 12: Text

  • There are properties to control the choice of font, size, weight, style, and spacing.
  • There is a limited choice of fonts that you can assume most people will have installed.
  • If you want to use a wider range of typefaces there are several options, but you need to have the right license to use them.
  • You can control the space between lines of text, individual letters, and words. Text can also be aligned to the left, right, center, or justified. It can also be indented.
  • You can use pseudo-classes to change the style of an element when a user hovers over or clicks on text, or when they have visited a link.

Chapter 13: Boxes

  • CSS treats each HTML element as if it has its own box.
  • You can use CSS to control the dimensions of a box.
  • You can also control the borders, margins and padding for each box with CSS.
  • It is possible to hide elements using the display and visibility properties.
  • Block-level boxes can be made into inline boxes, and inline boxes made into block-level boxes.
  • Legibility can be improved by controlling the width of boxes containing text and the leading.
  • CSS3 has introduced the ability to create image borders and rounded borders.

Chapter 14: Lists, Tables & Forms

  • In addition to the CSS properties covered in other chapters which work with the contents of all elements, there are several others that are specifically used to control the appearance of lists, tables, and forms.
  • List markers can be given different appearances using the list-style-type and list-style-image properties.
  • Table cells can have different borders and spacing in different browsers, but there are properties you can use to control them and make them more consistent.
  • Forms are easier to use if the form controls are vertically aligned using CSS.
  • Forms benefit form styles that make them feel more interactive.

Chapter 15: Layout

  • <div> elements are often used as containing elements to group together sections of a page.
  • Browsers display pages in normal flow unless you specify relative, absolute, or fixed positioning.
  • The float property moves content to the left or right of the page and can be used to create multi-column layouts. (Floated items requires a defined width.)
  • Pages can be fixed width or liquid (stretchy) layouts.
  • Designers keep pages within 960 - 1000 pixels wide, and indicate what the site is about within the top 600 pixels (to demonstrate its relevance without scrolling).
  • Grids help create professional and flexible designs.
  • CSS Frameworks provide rules for common tasks.
  • You can include multiple CSS files in one page.

Chapter 16: Images

  • You can specify the dimensions of images using CSS. This is very helpful when you use the same sized images on several pages of your site.
  • Images can be aligned both horizontally and vertically using CSS.
  • You can use a background image behind the box created by any element on a page.
  • Background images can appear just once or be repeated across the background of the box.
  • You can create image rollover effects by moving the background position of an image.
  • To reduce the number of images you browser has to load, you can create image sprites.

Chapter 17: HTML5 Layout

  • The new HTML5 elements indicate the purpose of different parts of a web page and help to describe its structure.
  • The new elements provide clearer code (compared with using multiple <div> elements).
  • Older browsers that do not understand HTML5 elements need to be told which elements are block-level elements.
  • To make HTML5 elements work in Internet Explorer 8 (and older versions of IE), extra JavaScript is needed, which is available free from Google.

Chapter 18: Process & Design

  • It’s important to understand who your target audience is, why they would come to your site, what information they want to find and when they are likely to return.
  • Site maps allow you to plan the structure of a site.
  • Wireframes allow you to organize the information that will need to go on each page.
  • Design is about communication. Visual hierarchy helps visitors understand what you are trying to tell them.
  • You can differentiate between pieces of information using size, color, and style.
  • You can use grouping and similarity to help simplify the information you present.

Chapter 19: Practical Information

  • Search engine optimization helps visitors find your sites when using search engines.
  • Analytics tools such as Google Analytics allow you to see how many people visit your site, how they find it, and what they do when they get there.
  • To put your site on the web, you will need to obtain a domain name and web hosting.
  • FTP programs allow you to transfer files from your local computer to your web server.
  • Many companies provide platforms for blogging, email newsletters, e-commerce and other popular website tools (to save your writing them from scratch).

Reference


This is the end of post

波多黎各六天五夜游

波多黎各

波多黎各自由邦是美国在加勒比海地区的一个自由邦(境外领土),首府为圣胡安。在西班牙语里波多黎各的意思是「富裕之港」,可惜事与愿违。

签证

波多黎各「自古以来」是美国领土不可分割的一部分,入境需要「美国签证」。这里没有从中国直飞的飞机,需要从美国本土进行转机才能到达。如果你持有美国的学生即 F1 签证,即使在已经过期的情况下,如果你仍在美国境内,也可以直接去波多黎各,因为从美国本土飞入的航班不需要过关。

行程安排

第几天 上午 下午 晚上 地点
Day 1 New York 飞到 San Juan 开车前往 Fajardo,游玩酒店的独有岛屿 住在 El Conquistador 酒店 Fajardo
Day 2 开车前往 El Yunque National Forest 游玩热带雨林 住在 El Conquistador 酒店 Fajardo
Day 3 坐船前往 Culebra Island 浮潜和划船 住在 El Conquistador 酒店 Fajardo
Day 4 飞往 Vieques Island 傍晚去 Bio Bay 住在 W Retreat & Spa 酒店 Vieques Island
Day 5 开车前往 San Juan 游玩老城区 住在 Ritz-Carlton 酒店 San Juan
Day 6 退租车 飞回 New York 抵达 New York New York

花费表

项目 商家 价格
纽约到圣胡安往返机票 Delta 340*2=680
Vieques Island 往返机票 Air Flamenco 68*2=136
租车 五天 Charlie Car Rental 200
Fajardo 酒店三晚 El Conquistador Resort, A Waldorf Astoria Resort 800
Vieques Island 酒店一晚 W Retreat & Spa - Vieques Island 360
San Juan 酒店一晚 The Ritz-Carlton, San Juan 380
浮潜以及 Kayak Kayaking Puerto Rico 93*2=186
Bio Bay Tour Fun Brothers 55*2=110

上表只包含机票、酒店以及游玩项目花费,不包括其他费用。

租车点评

Charlie Car Rental(推荐指数:☆☆☆☆☆

这次选择 Charlie Car Rental 是通过 Yelp 查看 Review 选到的,我也是推荐这家租车公司。在 San Juan 机场的确也有类似 Enterprise Rent-A-Car, National Car Rental 之类的大公司,但普通的车并多,我准备预定的时候只有 SUV 和 Jeep 之类的大车了,而且很贵。同时,你也会发现还有很多小的汽车租赁公司价格十分便宜,网上查看的时候也是备货充足,如果预定的话,在网上是不需要交定金的,要到现场再交钱。但根据 Yelp 的评论来看,很多这样小公司在你到了之后会告诉你,你预定那款车型没有了,然后推荐你选择更贵的车。

Charlie Car Rental 也是网上预约不需要提前交钱,但 Yelp 上的评价很好,去了之后也是提供了同款车。

另外提一下租车保险问题,在美国租车需要包含两项保险,第一个是 Liability Insurance,第二个是 Collision/Loss and Damage Waiver。简单来说,在出事故时,Liability Insurance 只赔付事故中造成的对方车辆和人员损失,而 Collision/Loss and Damage Waiver 只赔付保险人驾驶的车辆相关的损失。在租车的时候,租车公司需要你购买这两项保险。

在 Charlie Car Rental 购买 Liability Insurance 价格是 15刀/天,同时使用 Chase Sapphire Preferred 信用卡所附赠的 Collision/Loss and Damage Waiver 的保险。

Tips:

  1. 网上预约,不需要提前缴费。
  2. 最好是使用信用卡来 cover 所需要的 Collision/Loss and Damage Waiver 保险。
  3. Google Map 上下载好离线地图,不是所有地方都是有信号的。

酒店点评

El Conquistador Resort(推荐指数:☆☆☆☆

add

这是一家非常大的 Resort,隶属于 Hilton 集团下。

El Conquistador 酒店集各种餐饮娱乐于一身,有露天游泳池、水上公园、网球场、跳舞池、沙滩以及一个私人岛屿。私人岛屿需要通过酒店的轮渡坐船过去,大约15分钟的海上航向就到了,私人岛屿上也有很多游玩项目,如果入住这里,一定要去一次。同时这里还有水上公园,有时间的话也可以过去玩玩,水上公园不是很大,只有几个水上项目可以玩。

El Conquistador 酒店的缺点就是房间一般,湿度比较大,一进入房间就能感觉到一股多年的湿气迎面扑来,但毕竟这里坐落于海边,游客玩的项目都全部涉水,把「水」带回房间也可以理解。

Tips:

  1. 地址是 1000 El Conquistador Avenue, Fajardo, 00738 PR。快到的时候会看到 El Conquistador Resort 的标志,从标志旁边的正路开进去就行了。
  2. Palomino Island: 要从客房先穿过大堂,然后一路往下走,乘坐电梯缆车到达码头,码头的左边是去私岛的轮渡,码头的右边是水上公园。

W Retreat & Spa(推荐指数:☆☆☆☆☆

add

W Retreat & Spa 坐落于 Vieques Island,隶属于 Starwood 酒店旗下,因为 Starwood 被 Marriott 全额收购,因此它也算是 Marriott 集团下的酒店。

这家酒店不算很大,但很精致。当坐的小飞机降落到 Vieques Island 的机场后,隔壁就有 W 酒店的候机室,你可以在这里等待酒店的 Shuttle 车过来接你,在第二天离开的时候也可以在这里稍作休息。W 酒店有两个沙滩,同时还有几个露天游泳池,其中一个是无边游泳。 W 酒店装修非常出色,服务也非常到位。要知道,在 Vieques Island 这个小岛上,连锁的酒店就只有 W 酒店这一家,其他的全是民宿即 Airbnb。

房间也很华丽,浴缸干净地想让人马上泡个澡,床当然也没话说,睡得非常舒服。

W 酒店没有什么缺点,如果需要在 Vieques Island 上过夜,强烈推荐入住这里,你不会后悔的。

Tips:

  1. 如果你是坐飞机到 Vieques Island 的,下飞机后出门左边就是 W 酒店候机室,等一会儿就有 shuttle 来接你。
  2. 酒店会帮你预定 Taxi ,见到司机的时候,需要把往返的车费都付了,然后告知大概什么时候结束,他们会来接的。
  3. 租的车需要在机场过夜,没问题。

The Ritz-Carlton, San Juan(推荐指数:☆☆

add

The Ritz-Carlton, San Juan 是隶属 Marriott 旗下的酒店。坐落于 San Juan 机场附近。

The Ritz-Carlton, San Juan 也有一个大沙滩和若干个游泳池,酒店内部还有一个赌场与酒吧。因为这家酒店历史悠久,整体布局和装修稍显老派,感觉让人一般,房间也是一般的布局,并没有什么心意。

如果你需要在 San Juan 住一晚,不是很推荐住在这里,380刀一晚的房价与其包含的东西有所出入,这个价格我觉得会有更好的选择。

Tips:

  1. 地址是 6961 Ave Gobernadores, Carolina, PR 00797
  2. 酒店有赌场,可以去玩几把,哈哈。

游玩项目点评

El Yunque National Forest 热带雨林之行(推荐指数:☆☆☆

add

由于 Puerto Rico 属于美国的缘故,这个 El Yunque National Forest 成为美国唯一一个在热带雨林中的国家公园。在里面,你可以走 Trail 来体验热带森林多变的气候,冷不丁地给你来一场不期而遇的暴雨,同时还有观望台可以瞭望大片大片的森林,也有个小型瀑布供游人嬉戏。

Tips:

  1. El Yunque National Forest - El Portal Visitor Center,这是最开始的接待中心,有卖一些小纪念品的。从这个就开始热带雨林之旅了。
  2. 这里是一些景点的里程指示牌,一路往山上开车,看到路牌就知道了景点了。
  3. 带雨衣,防虫喷雾剂,雨鞋,换洗的干衣服干袜子。
里程牌 景点
4.2km El Portal Visitors Center
7.8km Gift shop and little roadside restaurant “La Muralla”
8.3km La Coca Fall The falls can be seen from the road
9.1km Yokahu Oberservation Tower
10.4 km Big tree trail to La mina falls
11.6 km Sierra Palms Recreation area
12km Palo Colorado Visitor Center and other trail heads

Culebra Island 的浮潜及 Kayak(推荐指数:☆☆☆☆☆

add

来波多黎各怎么能不浮潜呢? Culebra Island 有着世界顶级的沙滩,具体排名第几记不清了,但这里的沙子真是又细又划。Kayak 和浮潜加起来有好几个小时。预定是在 Kayaking Puerto Rico 这个网上上找到的。包含主岛往返 Culebra Island 的船票,和到 Culebra Island 后的游玩项目。

主岛到 Culebra Island 可以选择做小型飞机和轮渡,这次选择 Kayaking Puerto Rico 团后,他们提供轮渡船票,船票并不贵,往返船票也就十几块钱,但数量非常有限,每天早上就只有两班从主岛到 Culebra Island 的轮渡,如果要选择自己去排队买船票的话,需要六七点钟就得到码头排队买票,并不是很值得。

坐船大概半个小时就能到 Culebra Island, 然后 Kayaking Puerto Rico 的工作人员会直接接上我们上 Bus,开到他们在岛上的基地,简单地吃点东西后,换上装备就直接去 Kayaking 了。

在 Kayak 的小船上,他们会提供给你浮潜的装备,当然如果你想使用自己的,也可以带上自己提前买好的。一般会有两次浮潜的机会,他们会让你划到指定的地方,然后进行浮潜,可以看到各种鱼类,海藻以及海龟,他们也会帮你拍摄照片。当然,推荐带上自己的 GoPro,然后让他们帮你用 GoPro 拍几张浮潜的照片,从水底往上拍的照片美极了!

大概下午四五点钟的时候,本次活动就结束了,冲洗下身上的泥沙,换上带来的替换衣服,他们会直接送到码头,坐上轮渡就返回主岛了。

Tips:

  1. 带一套换洗的干衣服
  2. 带毛巾,因为玩完沙子后需要冲个凉,把身上的沙子洗净,这时候需要毛巾擦干身上的水。
  3. 注意防晒,浮潜很晒的。如果有必要,可以穿长袖和长裤款的潜水衣。
  4. 轮渡周围有很多停车的地方,一天大概十几块钱。

Vieques Island 的 Bio Bay Tour(推荐指数:☆☆☆☆☆

Bio Bay 应该属于来波多黎各的必备项目,绝对不能错过!这次预定是在 Fun Brothers 上订 Bio Bay Tour,体验非常好,也是非常满意的!

主岛到 Vieques Island 也是有轮渡和小型飞机的选项,我们选择是坐小型飞机到小岛上。在 Air Flamenco 上买了主岛到 Vieques Island 的往返机票,每人 68 美元,飞机很快,大概 13 分钟就能飞到了,同时也可以领域空中俯瞰岛屿的美景。

因为只需要天非常黑的情况下,才能领略到荧光海的魅力,所以我们预定的是晚上 9 点到 11 点的 Tour。到达 W 酒店后,酒店人员可以帮你安排往返 Bio Bay 的出租车,下午稍微休息了一会儿后,五六点就准备出发去集合区域。虽说那里是 Vieques Island 上的一个商业聚居区,其实是一个很小的地方,几家餐馆,几个卖工艺品的摊位,还有几户民宿。在好好地吃了一顿晚饭后,九点就坐上了 Fun Brothers 接我们去 Bio Bay 的 Bus。

前往 Bio Bay 的道路异常曲折,由于全是坑坑洼洼的泥地,全程几户是坐过山车式的方式上下颠簸才到达。到达后,天已经完全漆黑,坐上 Kayak 后就在荧光湖上游荡了。这是一次非常别致的体验,每当浆在水里划下的时候,水就会泛起淡淡的亮光,加上 Kayak 的小船底部是纯玻璃制的,你就可以看到湖中泛起的点点荧光,异常美丽又惊奇。

Tips:

  1. 因为环保的需要,去 Bio Bay 不能喷防虫的喷雾,如果喷的话,他们的工作人员会制止你的,不过蚊子也不是很多,没什么问题。
  2. 去 Bio Bay 的路十分颠簸,注意保护屁股。

San Juan 老城区(推荐指数:☆☆☆☆

add

坐上返航的飞机会后主岛后,就直接驱车一小时回到 San Juan,利用下午和晚上的时间游览下 San Juan 老城区。在快进入老城区的时候,找个停车场把车停了,然后步行进去。因为老城区的街道很狭窄,基本没法停车。

San Juan 的老城区犹如一道道彩虹,各种各样的颜色涂在不同的西班牙式建筑的墙壁,让人忍不住按下相机的快门。当然,这里是非常理想的拍照之地,多拍点照片准备发朋友圈吧,绚丽多姿的图片不会让你失望的。

Tips:

  1. 老城区很难停车,需要把车停的城外,然后步行进去,可以选择的停车场是 Estacionamiento Covadonga,PR-38, San Juan, 00901 或者是 Dona Fela Parking,如果都没有,附近可以随便找一个,走路大概 5~10 分钟就能到老城区了。
  2. 可以参观两个古堡:Castillo de San Cristóbal 和 SAN CRISTOBAL CASTLE

This is the end of post

Few Tips while using Alamofire Library

What’s Alamofire?

Alamofire is an HTTP networking library written in Swift.

Alamofire can solve most HTTP problems while you are building Apple applications with Swift. It’s really super powerful library if you need to handle any HTTP problems.

POST with a string as body

If you want to make a POST request, and you also have a string as body to send this request. Here is the way to do in Alamofire.

1
2
3
4
5
6
7
let URL = "https://www.google.com"
let params : Parameters = ["foo" : "bar", "bar" : "foo"]
let headers : HTTPHeaders = ["content-type": "application/x-www-form-urlencoded"]

Alamofire.request(URL, method: .post, parameters: params, encoding: URLEncoding.httpBody, headers: headers).responseString { response in
print(response)
}

Read cookies from response

Through API provided from Apple, we can get cookies from the response by using HTTPCookieStorage.shared.cookies.

Here is the example from code above.

1
2
3
4
5
6
7
8
let URL = "https://www.google.com"
let params : Parameters = ["foo" : "bar", "bar" : "foo"]
let headers : HTTPHeaders = ["content-type": "application/x-www-form-urlencoded"]

Alamofire.request(URL, method: .post, parameters: params, encoding: URLEncoding.httpBody, headers: headers).responseString { response in
let cookie = HTTPCookieStorage.shared.cookies
print(cookie)
}

Reference


This is the end of post

How to convert integer into time format with Swift?

Question

There is an integer represents duration time in seconds, I want to convert it into 4:34:54 and 4 Hours 34 Minutes 54 seconds format. Is there any way to solve this problem?

Answer

The following code is based on Swift 3.

Format One

1
2
3
4
let interval = 27005
let formatter = DateComponentsFormatter()
formatter.allowedUnits = [.hour, .minute, .second]
let formattedString = formatter.string(from: TimeInterval(interval))!

In this way, formattedString will be 7:30:05

Format Two

1
2
3
4
let interval = 27005
let formatter = DateComponentsFormatter()
formatter.unitsStyle = .full
let formattedString = formatter.string(from: TimeInterval(interval))!

In this way, formattedString will be 7 hours, 30 minutes, 5 seconds

Reference


This is the end of post

How to shrink long text in label with Swift?

Question

I want to show a long text in label, and it seems too long to fit. Is there any way to shrink those text into this label box?

Answer One - Storyboard

add

Change the label property Autoshrink to whichever you like.

Answer Two - Programmingly

labelName.adjustsFontSizeToFitWidth = true

In this way, you can also adjust text in the label.

Reference


This is the end of post

HTTP Status Messages

What’s HTTP Status Messages?

When a browser requests a service from a web server, and an error might occur. We call this error as HTTP Status Messages.

This is a list of HTTP status messages.

1xx: Information

2xx: Successful

3xx: Redirection

4xx: Client Error

5xx: Server Error

Reference


This is the end of post