介绍
本次介绍数组的一些扩展方法,都是简单地总结下一些方法的使用,详细的请参考:数组的扩展
上次写过一篇关于webpack入门的博客,当时只是说借助node来完成开发,并用webpack打包以让浏览器识别。其实其主要思想就是实现前端模块化开发。
众所周知,历史上,JavaScript 一直没有模块(module)体系,无法将一个大程序拆分成互相依赖的小文件,再用简单的方法拼装起来。这在开发大型的、复杂的项目时就变得很困难。这就需要一种模块加载机制,在ES6之前,就有一些模块加载方案,比如CommonJS和AMD,上篇文章就是用到CommonJS规范。但现在,ES6已经填补了Module这块空白。下面就简单说下利用webpack实现前端模块化开发。
本文主要介绍webpack的入门,因为我自己也是刚上手webpack,还在学习阶段,所以会讲得很基础。对于没用过webpack的童鞋,看完能懂就是我的目的。你也可以参考我的上篇博客webpack入门。另外关于ES6模块化,我觉得你应该要提前会懂,我就不讲了,这里有更好的文档 ES6 Module
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。
在Vue中,多组件的开发给我们带来了很多的方便,但同时当项目规模变大的时候,多个组件间的数据通信和状态管理就显得难以维护。而Vuex就此应运而生。将状态管理单独拎出来,应用统一的方式进行处理,在后期维护的过程中数据的修改和维护就变得简单而清晰了。这个状态管理模式包含以下三个部分:
简单说,就是用户界面触发动作(Action)进而改变对应状态(State),从而反映到视图(View)上,所以Vuex采用的是单向数据流的方式来管理数据的。官网给出以下图,很好做出示意:
需求:
设计一个列表,包含:地域、百分比、人数、时间。请实现按照 人数 与 时间 的排序算法。
1 | var data = [ |
1 | /* |
1 | mySort(data,'number','ASC'); // 若第三个参数不写,则默认为DESC |
在使用css来给页面添加动画时,如果样式和动画一起写,很容易出错,最后可能在整体上达不到预期的效果,修修改改很费时,可以先写一个js脚本来测试动画效果,再去一次性写好所有动画。
这里举一个小例子,来看看怎么先测试动画效果。
1 | <div class="screen1" style="background-color: #FFFF00;"> |
两个div代表两个屏,分别有不同的动画
指令 (Directives) 是带有 v-
前缀的特殊属性。
它可以写在DOM元素上,对html进行操作。常用的指令比如有:v-if
,v-else
,v-show
,v-for
等。这些都是官方直接给定的,另外Vue也允许注册自定义指令,有时这很有用。
自定义一个指令很简单,官网给出一个简单的例子,自定义一个聚焦指令v-focus
1
2
3
4
5
6
7
8// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
// 当被绑定的元素插入到 DOM 中时……
inserted: function (el) {
// 聚焦元素
el.focus()
}
})
上面几行代码就全局注册了一个指令并可以执行,当给一个输入框加上这个指令时,页面加载就会使该框获得焦点。1
<input v-focus>
说明:
focus:如你所见,是指令的名称,不带v-
前缀;
inserted:这是一个钩子函数,表示被绑定元素插入父节点时调用,指令定义函数提供了多个钩子函数,下面再介绍。
另外,你也可以局部注册指令,组件中也接受一个 directives 的选项:1
2
3
4
5
6
7
8directives: {
focus: {
// 指令的定义
inserted: function (el) {
el.focus()
}
}
}
指令定义函数提供了几个钩子函数(可选)
bind
:只调用一次,指令第一次绑定到元素时调用。
inserted
:被绑定元素插入父节点时调用。
update
:所在组件的VNode更新时调用,但是可能发生在其子 VNode 更新之前。
componentUpdated
:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
unbind
:只调用一次,指令与元素解绑时调用。
他们中每一个都有相同的三个参数:el,binding和vnode,在update和componentUpdated中,还会有参数oldVnode,以区分传递的旧值和新值。
el
:指令所绑定的元素,可以用来直接操作 DOM 。
binding
:一个对象,包含以下属性:name,value,oldValue,expression,arg和modifiers。
vnode
:Vue 编译生成的虚拟节点。
oldVnode
:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。
注意:除了 el 之外,其它参数都应该是只读的。
其中,你注意到binding参数中有多个属性,要搞清楚他们分别代表了什么,这很重要。
1 | <div id="app"> |
1 | Vue.directive('demo',{ |
结果:1
2
3
4
5name:demo; //指令名,不包括 v- 前缀
value:hello; //指令的绑定值
expression:message; //字符串形式的指令表达式
argument:foo; //传给指令的参数,可选。
modifiers:{"a":true,"b":true}; //一个包含修饰符的对象。
还有一个oldValue是指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
到这里,你可能有点糊涂了,东西看起来有点多,其实并不是,你只是不熟悉。这些官网介绍的很清楚,你需要的是一个更具体的例子。
现在来创建一个自定义指令,比如我想创建一个可以操作定位的指令,就叫他 v-position
。1
2
3
4
5
6Vue.directive('position',{
bind(el, binding, vnode){
el.style.position = 'fixed';
el.style.top = binding.value + 'px';
}
});
1 | <div id="app"> |
现在v-position只能控制到顶部的距离,我们还可以自由控制方向:1
<p v-position:left='50'>我距离左侧50px</p>
1 | Vue.directive('position',{ |
另外,你还可以控制多个值:1
<p v-position="{top:'100',left:'50'}">我距离左侧50px,距离顶部100px</p>
1 | Vue.directive('position',{ |
这就是vue自定义指令的一些简单应用,你可以创建出更高级灵活的自定义指令。
这不是一个很系统的教程,但是作为入门,我觉得够够了,至少知道怎么下手使用
为什么要用webpack?答案网上一大堆。我不想说了,好吧,我也说不好,毕竟也才刚接触。
在这里,我觉得还是举个例子说明下吧,看完这个例子,你至少知道webpack还是有用的 (例子简单易懂哦~~)
首先新建一个目录,目录下建3个文件,分别是:
a.js:
1 | (function() { |
b.js:
1 | console.log( msg ) |
index.html:
1 | <!DOCTYPE html> |
你看,代码多简单,肯定懂。其实就是在a中定义一个变量,然后要在b中打印出来,在html文件中先后引入a.js和b.js,这样看起来很合理,其实你又知道,这样根本打印不出来,甚至抛给你一个错误:
这是JavaScript语言性质决定的,我也不说了,很显然a.js和b.js没有关联,如果希望在b.js中访问到msg,办法是将msg定义到全局变量中,即修改a.js为:
1 | (function() { |
这时候再去控制台,绝对打印出来了~~但是问题也很明显,这样定义到全局变量中的做法是不明智,为什么,我也不说了,你应该知道。
就在这时候,nodejs出现了,它解决了这个历史问题。可以用后台知识去写前端,这时分别修改a.js 和 b.js:
a.js:
1 | var msg = 'hello world' |
b.js:
1 | var msg = require('./a').msg |
然后打开命令行工具进入当前目录,用node运行b.js:
结果正常打印了。
虽然问题解决了,不用定义全局变量了,但是更大的问题来了,就是这个是用node运行的,浏览器识别不了它,此时控制台是这样的:
啊哦,白忙活了,浏览器识别不了,玩个啥~ 其实,这才引出主题嘛,没错,到了这里,终于说到正题了,那就是为什么用webpack?
因为webpack就可以将这种好用的,但浏览器识别不了的东西编译成浏览器能够识别的东西,并使用。
1 | //全局安装 |
可以选择全局安装,也可以安装在项目目录里,这里推荐安装到项目目录里:
首先新建一个文件夹,比如叫:webpack_study(即项目文件夹),然后进入文件夹,使用命令:1
npm init -y
这个命令会自动生成一个package.json文件,这是一个标准的npm说明文件,里面蕴含了丰富的信息,包括当前项目的依赖模块,自定义的脚本任务等等。先不管它,这时在目录里安装webpack:1
2// 安装Webpack
npm install --save-dev webpack
安装完成后,目录里多了一个node_modules文件夹。现在将前面例子中的a.js,b.js和index.html等文件放入到目录中:
a.js:
1 | var msg = 'hello world' |
b.js:
1 | var msg = require('./a').msg |
index.html:(注意:这里引用路径改变了,只引用了bundle.js)
1 | <!DOCTYPE html> |
现在整个目录结构如下:
此时执行命令:
1 | // 非全局安装的情况 |
b.js是入口文件,bundle.js是我们要打包成的文件,即是我们在index.html中引用的文件。打包完成后,目录里多了一个bundle.js文件,这个时候再在浏览器里打开控制台,发现可以打印出“hello world了”,说明webpack已经帮我们处理好了依赖关系,浏览器可以正常工作了。当然,webpack的功能远比想像的强大。
现在学会了使用webpack打包文件,但是在终端输入了一堆命令,太复杂也容易出错,现在来看一种简单的打包方法。
通过配置文件来使用webpack:
在目录里新建一个js文件:webpack.config.js。这个是webpack的配置文件,内容为:
1 | module.exports = { |
有了这个配置之后,再打包文件,只需在终端里运行(非全局安装需使用node_modules/.bin/webpack)命令就可以了,这条命令会自动引用webpack.config.js文件中的配置选项,示例如下:
现在打包就不用输入烦人的命令行参数了,是不是感觉很爽,但如果连 node_modules/.bin/webpack 都不用输入,是不是更爽,其实还真可以~
使打包更快捷:
方法就是在package.json文件中对scripts对象进行相关设置,设置方法如下:
1 | { |
现在再执行
1 | npm run start |
就可以打包了,如下:
是不是很方便。其实通过修改配置文件,还可以实现很多webpack的强大功能。都说webpack难,难就难在去配置文件吧。等我们需要用到某种功能时,再去学习怎么配置吧。
这是一段html代码:1
2
3
4
5
6
7
8
9
10<div id="div1">
hello world
<div>
<p>第一个p</p>
</div>
<div>
<p>第二个p</p>
</div>
</div>
1 | console.log(div1.childNodes.length); //5 |
因为childNodes会把文本算入节点,即使文本为空
1 | console.log(div1.children.length); //2 |
1 | console.log(div1.firstChild); |
返回的是第一个文本节点
1 | console.log(div1.firstElementChild); |
在上一篇关于二叉树的js实现的基础上,增加二叉树节点查找与删除操作。
代码如下:
注意:接口写在BinaryTree()
中,部分代码已省略
1 | function BinaryTree(){ |