盒子
盒子
文章目录
  1. 获取歌曲的外链
    1. 几点要注意的
  2. CSS布局以及HTML结构划分
    1. CSS的一些小技巧
  3. 模块化和MVC的设计
    1. 发布订阅模式
    2. 几个注意要点

云音乐-2

获取歌曲的外链

通过七牛的文档说明,先去js官方文档,然后通过里面的js源码地址,选择1.0的版本,进入之后,选择示例网站,在获得代码里面,可以发现下面代码

1
2
3
4
5
6
7
8
9
10
11
12
13
 'FileUploaded': function(up, file, info) {
// 每个文件上传成功后,处理相关的事情
// 其中 info.response 是文件上传成功后,服务端返回的json,形式如
// {
// "hash": "Fh8xVqod2MQ1mocfI4S4KpRL6D98",
// "key": "gogopher.jpg"
// }
// 参考http://developer.qiniu.com/docs/v6/api/overview/up/response/simple-response.html

// var domain = up.getOption('domain');
// var res = parseJSON(info.response);
// var sourceLink = domain + res.key; 获取上传成功后的文件的Url
},

很明显最后三行与我的目的有关,打开注释,改造成我所需要的

1
2
3
var domain = up.getOption('domain');
var response = JSON.parse(info.response);
var sourceLink = 'http://' + domain + '/' + encodeURIComponent(response.key);

几点要注意的

  1. response的key就是我拖曳或者上传的歌曲

response.key是啥

  1. 为什么要用encodeURIComponent

因为你上传的时候必然会有中文吧,浏览器和服务器端都不会懂你问的这些中文是什么鬼,我们要用URL编码处理一下这个response.key(也就是歌曲的名字),之所以不用encodeURI,是因为它会把一个东西当做一个整体的,如果含有&,还是会把&传给你,而这个很有可能会有歧义。

使用了encodeURIComponent

如果我想把带有&的一串东西放到查询参数里面,需要使用encodeURIComponent。

CSS布局以及HTML结构划分

初步规划是左边第一栏是new-song,中间是song-list,底部是upload-song,右面是song-form部分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<page>
<aside class="sidebar">
<div class="newSong">
</div>
<div id="songList-container">

</div>
<div class="uploadArea">
<div id="uploadContainer" class="draggable">
<div id="uploadButton" class="clickable">
<p>点击或者拖曳文件</p>
<p>文件大小不能超过 40MB</p>
</div>
</div>
</div>
</aside>
<main>

</main>
</page>

page区域使用flex布局,是的aside和main区域左右分布,然后aside在使用flex布局并使用flex-direction=column。使之上下排列。

CSS的一些小技巧

  1. border: dashed是把阴影虚线化。
  2. git commit -v查看更改的内容是什么。
  3. 属性选择器 .form input[type=button]
  4. 为了实现选中label激活里面的input可能会选择label包裹input的布局,可是存在风险。比如如果label的文字过多,你加了宽度是没有用的,只是会换行而已(显然不是我想看到的),因为label是inline元素,可是改成inline-block又会有bug(一道空隙)。所以只能选择不用label去包裹input了。

对不齐了

优化的代码如下

1
2
3
4
5
6
7
8
9
10
.form > .row > label{
display: flex;
justify-content: flex-end;
align-items: center;
width: 4em;
margin-right: 5px;
}
.form > .row.actions{
margin-left: calc(4em + 5px);
}
  1. input的字体应该继承才行,不然字体大小不对。input{font: inherit;}

  1. 背景色是在border里面的,margin上没有背景色

模块化和MVC的设计

如果一个模块变化了,如何通知另外的模块我变了呢,最简单的是使用一个全局的js,告诉其他的js,我变了。

先写一个全局的app.js

1
2
3
{
window.app = {}
}

在要发起通信的js文件上写上下面的代码

1
2
3
4
window.app.newSong.active()
window.app.songForm.reset()
...
window.app.uploadSong = controller

也就是说其他的js模块只是往外暴露他们对应的js就可以了。但是这种方式的通信耦合度有点高,不利于后期更改。

模块间通信

因为假如3变了要去通知1和4的话,1和4还是知道3的存在,所以不应该让1和4知道3的存在。采取中间环节来转换,那就是发布订阅模式。

发布订阅模式

发布订阅模式

使用全局的eventHub模块

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
window.eventHub = {
events: {
// '遗憾': [fn],
// '追光者': [],
},
/**
* 发布
* @param {*事件名字} eventName
* @param {*数据} data
*/
emit(eventName, data) {
for(let key in this.events) {
if(key === eventName) {
let fnList = this.events[key]
fnList.map((fn) => {
fn.call(undefined, data)
})
}
}
},
/**
*
* @param {*订阅的事件名字} eventName
* @param {*订阅事件之后执行的函数} fn
*/
on(eventName, fn) {
if (this.events[eventName] === undefined) {
this.events[eventName] = []
}
this.events[eventName].push(fn)
}
}

其他模块的js使用的时候就可以使用

1
2
3
4
window.eventHub.emit('upload', {
'url': sourceLink,
'name': response.key
})

几个注意要点

  1. ES6的一个特性
1
2
3
render(data = {}) {

}

如果你传值的时候,没有传值或者传的值是undefined就给你一个空对象。

  1. 省略一点代码

在view里面写上

1
2
3
init(){
this.$el = $(this.el)
}
  1. Vue框架里面V-for出现的必要性

如果直接用template的话

1
2
3
4
5
6
7
8
9
10
11
12
<ul class="songList">
<li>歌曲1</li>
<li class="active">歌曲233333</li>
<li>歌曲3</li>
<li>歌曲4</li>
<li>歌曲52222222</li>
<li>歌曲6</li>
<li>歌曲7</li>
<li>歌曲8</li>
<li>歌曲9</li>
<li>歌曲1033</li>
</ul>

很显然这种template很难看,所以使用如下的代码改造。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
let view = {
el: '#songList-container',
template: `
<ul class="songList">
</ul>
`,
render(data) {
let $el = $(this.el)
$el.html(this.template)
let {songs} = data
let liList = songs.map((song) => $('<li></li>').text(song.name))
$el.find('ul').empty()
liList.map((domLi) => {
$el.find('ul').append(domLi)
})
},

而以上的仍然麻烦,所以Vue发明了V-for的语法,不过人家是使用了正则表达式去实现的。

4.深拷贝与浅拷贝的阴影

1
2
3
4
let string = JSON.stringify(this.model.data)
let object = JSON.parse(string)
// window.eventHub.emit('create', this.model.data) //一开始用的是这句代码,明显this.model.data会被多次篡改
window.eventHub.emit('create', object)