天天看点

Vue组件

组件可以扩展 ​<code>​HTML​</code>​ 元素,封装可重用的代码。

vue.js的核心组件:

模板(template)——模板声明了数据和最终展现给用户的DOM之间的映射关系。

初始数据(data)——一个组件的初始数据状态。对于可复用的组件来说,通常是私有的状态。

接受的外部参数(props)——组件之间通过参数来进行数据的传递和共享。参数默认是单向绑定(由上至下),但也可以显式声明为双向绑定。

方法(methods)——对数据的改动操作一般都在组件的方法内进行。可以通过​<code>​v-on​</code>​指令将用户输入事件和组件方法进行绑定。

生命周期钩子函数(lifecycle hooks)——一个组件会触发多个生命周期钩子函数,比如​<code>​created​</code>​、​<code>​attached​</code>​、​<code>​destroyed​</code>​等。在这些钩子函数中,我们可以封装一些自定义的逻辑。和传统的MVC相比,这可以理解为​<code>​Controller​</code>​的逻辑被分散到了这些钩子函数中。

私有资源(assets):Vue.js当中将用户自定义的指令、过滤器、组件等统称为资源。由于全局注册资源容易导致命名冲突,一个组件可以声明自己的私有资源。私有资源只有该组件和它的子组件可以调用。

除此之外,同一棵组件树之内的组件之间还可以通过内建的事件API来进行通信。Vue.js提供了完善的定义、复用和嵌套组件的API,让开发者可以像搭积木一样用组件拼出整个应用的界面。这个思路的可行性在Facebook开源的React当中也得到了印证。

Vue.js的核心库只提供基本的API,本身在如何组织应用的文件结构上并不做太多约束。但在构建大型应用时,推荐使用 ​<code>​Webpack+vue-loader​</code>​ 这个组合以使针对组件的开发更高效。

Webpack是由Tobias Koppers开发的一个开源前端模块构建工具。它的基本功能是将以模块格式书写的多个JavaScript文件打包成一个文件,同时支持CommonJS和AMD格式。但让它与众不同的是,它提供了强大的loader API来定义对不同文件格式的预处理逻辑,从而让我们可以将CSS、模板,甚至是自定义的文件格式当做JavaScript模块来使用。Webpack 基于loader还可以实现大量高级功能,比如自动分块打包并按需加载、对图片资源引用的自动定位、根据图片大小决定是否用base64内联、开发时的模块热替换等等,可以说是目前前端构建领域最有竞争力的解决方案之一。

Vue.js还有几个值得一提的特性:

异步批量DOM更新:当大量数据变动时,所有受到影响的​<code>​watcher​</code>​会被推送到一个队列中,并且每个​<code>​watcher​</code>​只会推进队列一次。这个队列会在进程的下一个 “tick” 异步执行。这个机制可以避免同一个数据多次变动产生的多余DOM操作,也可以保证所有的DOM写操作在一起执行,避免DOM读写切换可能导致的layout。

动画系统:Vue.js提供了简单却强大的动画系统,当一个元素的可见性变化时,用户不仅可以很简单地定义对应的CSS ​<code>​Transition​</code>​或​<code>​Animation​</code>​效果,还可以利用丰富的JavaScript钩子函数进行更底层的动画处理。

可扩展性:除了自定义指令、过滤器和组件,Vue.js还提供了灵活的mixin机制,让用户可以在多个组件中复用共同的特性。

组件实例的作用域是孤立的。这意味着不能(也不应该)在子组件的模板内直接引用父组件的数据。要让子组件使用父组件的数据,我们需要通过子组件的 ​<code>​props​</code>​ 选项。

子组件要显式地用 ​<code>​props​</code>​ 选项声明它期待获得的数据。

Vue 中子组件可以通过通过事件和父组件进行通信的。向父组件发消息是通过 ​<code>​this.$dispatch​</code>​,而向子组件发送消息是通过 ​<code>​this.$boardcast​</code>​。

Vue 把双向绑定称作 reactive,可以翻译为响应式数据绑定。内部是通过 ES5 定义的 ​<code>​getter​</code>​ 和 ​<code>​setter​</code>​ 方法实现的,所以不支持 IE8 及以下浏览器,这种实现方式有两个容易犯错的地方:

如果在 data 上直接添加和删除属性是无法被检测到的,一般删除是不会的,但是可能会动态添加,这个时候应该通过 ​<code>​vm.$set(“name”, value)​</code>​ 的方式来添加。

无法检测到对象内部的变化,也就是只能检测 data 的属性变化,如果 ​<code>​data.a​</code>​ 是一个对象,那么 ​<code>​data.a.b = 1​</code>​ 这种变化是无法被检测到的。这种情况下应该创建一个新的对象并赋值给 data.a 就行了。

Vue 对DOM的更新是异步的! 这个异步是在一个异步队列中进行的,不过这个异步队列会在当前的 ​<code>​Event Loop​</code>​ 中执行完,所以如果修改了 Data 立刻去DOM中做查询操作是不对的,这个时候DOM还没有更新,正确的做法是这样做:

或者这样:

继续阅读