Vue 组件化开发实践

Andy,javascript

前言:

这是一篇,在开发掘金 (opens in a new tab)的过程中,思考和总结出来,如何使用 Vue.js (opens in a new tab) 和周边工具集合成一套完整舒适的组件化开发流程的文章。

之前有关如何使用 Webpack 和 vue-loader 开发 Vue 应用的文章有:

PS:以下的任何内容都是基于 0.12 以上版本,由于 Vue 作者尤大大 (opens in a new tab)正在不断地加入新特性和推出新版本,1.0正式版本即将推出,不保证下文的任何内容会因新版本的内容而覆盖掉。假如本文有任何令你不爽的地方,请拍砖。

组件化模块化开发

在 Vue 当中,组件被当作是一等公民,所以设计和完成一个 Web App 之前,最好先构思好如何构建各个组件,哪些组建需要被复用到,哪些页面是要切换的。在组件化和模块化的原则上,Vue 提供了一些现有流行的预编译工具的扩展, 管理 vue 可预编译文件。分别是 Webpack (opens in a new tab) 派的 vue-loader (opens in a new tab)Gulp (opens in a new tab) 派的 vueify (opens in a new tab)

Vue 希望每个单页应用都可以通过组建系统简化为各个 component。

使用 Webpack 和 vue-loader 开发的例子

在 vue 后缀文件当中,定义了三个 tag,templatescriptstyle

<template lang="jade">
</template>
 
<script lang="babel">
 
export default {
 
}
 
</script>
 
<style lang="sass">
</style>

从开发的角度看,维护和开发这样的一个 vue 文件,既可以作为一个主页面引用其他的 vue 组建或者切换页,又可以作为一个 component 被其他 vue 文件引用,所有需要的 html,css,javascript 代码都在里面,结合 MVVM 的概念,使用起来非常清爽和简单。

三个 tag 中,各自可以声明自己的预编译语言,安装 Webpack 和自己所需要的 loader 之后,在 webpack.config.js 文件下配置好 loader 和文件出入口就可以了。Webpack 会将所有内容和资源预编译并打包成一个 js 文件。Webpack 的详细使用请看官网 (opens in a new tab)

Webpack 的前端哲学和观点就是将一切资源(HTML,CSS,Javascirpt,图片)用 importrequire 模块化引入,并对资源进行所需要的预处理,最终打包一个 js 文件被单页应用引入。Webpack 中有大量的特性和插件可以用来构建大型单页应用,坑略深。下面使用几个简单的 loader 来展示如何使用 Webpack 和 vue-loader 来管理一个初期的单页应用。

npm install --save-dev 安装 babel-loaderjade-loadersass-loadervue-loader 即可:

安装好依赖就可以构思如何设置目录了。由于一切资源都被编译成一个 js 文件,所以 public 目录下只需要保存 build 目录即可。

nodemodule // 各种 npm 库
  xxx
  xxx
public
  build
    index.js // Webpack 预编译之后的文件,最终被 HTML 引入
  index.html // 引入 build 目录中的 index.js
vue
  assets // scss 和图片资源
    scss
      uuu.scss
    images
      ooo.png
  helper
    xxx.js // 一些 helper
  index
    components
      zzz.vue // 各种组件
    views
      xxx.vue // xxx页
      yyy.vue // yyy页
    main.js // Webpack 预编译入口
    app.vue // 被 main.js 引用的主页文件
webpack.config.js // Webpack 配置文件

在 webpack.config.js 中的配置:

module.exports = {
    entry: {
        'index': './vue/index/main.js',
    },
    output: {
        path: './public/bulid',
        filename: '[filename].js' // 可以多点切入
    },
    module: {
        loaders: [
            {
              test: /\.vue$/,
              exclude: /node_modules/,
              loader: vue.withLoaders({
                  js: 'babel?optional[]=runtime'
              })
            },
            { test: /\.scss$/, loader: 'style!css!sass },
            { test: /\.css$/, loader: "style!css" },
            { test: /\.js$/, loader: 'babel-loader' }
        ]
    },
    resolve: { // 解决 npm 的依赖问题
        modulesDirectories: ['node_modules'],
        extensions: ['', '.js', '.json']
    },
}

有关 Webpack 的详细使用,可移步官网 (opens in a new tab)

PS:调试的时候在 Chrome 中安装 vue-devtools (opens in a new tab) 实时查看 Vue 实例中的绑定数据。

父子模版之间通讯

组件化开发第二个问题是,如何最佳地在父子模版和各个页面之间通讯?

考虑到子模版的可复用性,子模版最好将需要从父模版中继承的数据和自己独立的数据都区分定义好。

在 Vue 中,父子模版之间绑定了数据和方法。而在父子模版之间进行通讯,或者相互触发事件,有三种情况对应发生:

而在 Vue 中,提供了两种方式来使父子模版相互触发事件:

对于这三种情况,Vue 提供了两个方法在父子,子父,子父子之间通讯和事件触发,已经可以应对相对复杂的情况。

PS:通过 watch 来观察双向绑定的变量然后触发某个父子方法,使父子模版之间的耦合度加强,在不得已的情况下最好不要用。只用在自身组件的变量触发事件的情况下是非常不错的。

SPA的路由切换

在构建一个 SPA 页面的时候,通常需要用到一个 Router 库 。官方的 vue-router 刚刚推出,使用起来更加复杂。而使用 director (opens in a new tab),跟 components 属性进行结合,就可以做到简单并且完美的切换页面功能。

配合 Vue 提供的 component keep alive 特性,可以在切换的过程中提供缓存,真是太爽不过。需要注意的是,0.12 版本中,将 component 的 replace 属性默认设为 true,假如你没有根节点提供给子模版,子模版会自动消失。

周边工具

Vue 是个非常年轻的 View 层框架,仍然有很多地方需要开发和改进,周边的工具和扩展也很少。在这里附上 vue 周边工具的地址:

vue-loader (opens in a new tab):与 Webpack 结合进行组件化开发

vueify (opens in a new tab):与 Gulp 结合进行组件化开发

vue-router (opens in a new tab):路由

vue-validator (opens in a new tab):表单验证库

vue-resource (opens in a new tab):网络请求库

vue-component-complier (opens in a new tab):与其他预编译器结合

vue-touch (opens in a new tab):事件模拟

meteor-vue (opens in a new tab):meteor 与 vue 结合开发

vue-syntax-hightlight (opens in a new tab):sublime text 的 vue 文件的高亮插件

vue-typeahead (opens in a new tab):搜索输入提前查询补全

vue-i18n (opens in a new tab):i18n

vue-devtools (opens in a new tab):配合 chrome 的开发插件,调试时可用

© FTAndy.RSS