Vue教程--使用官方脚手架构建实例(上篇)

本文基于工作项目开发,做的整理笔记
因工作需要,项目框架由最初的Java/jsp模式,逐渐转移成node/express模式。现在新项目又因为业务流程中的交互操作,会使页面dom根据数据data不断显示变化,便觉得此时是否是最佳实际,应该尝试一下vue框架。因为之前也偷偷的进行了一些vue框架的踩坑工作,已经填了一些坑或者有一些解决方案了,这也才敢用上。依然由后台Java提供API。本文就是做个笔记,说明如何使用Vue官方脚手架开始构建项目。

前提条件:
你已经听过、了解过Vue,至少一点点。

编码环境:
系统:OS X EI Capitan
版本:10.12.2

共2篇:
上篇:http://www.jianshu.com/p/ee2464501c65(当前)
下篇:http://www.jianshu.com/p/9baa03eb31fc

Vue教程--使用官方脚手架构建实例(上篇)_第1张图片
vue.jpg

目录
| - 0.传送门
| - 1.安装
| - 2.项目初始化
| - 3.项目构建
  | - Step1.阅读结构
  | - Step2. 阅读代码(泛读)
| - 4.项目实操
  | - Step1. 修改eslint配置
  | - Step2. 调整结构
  | - Step3. 添加登陆页面
  | - Step4. 模版嵌套
  | - (上下篇分割线)
  | - Step5. 引入mockjs独立开发
  | - Step6. 调用API接口
  | - Step7. 状态管理(store仓库)
  | - Step8. 抽离公共方法
  | - Step9. 剥离组件
  | - Finish. 生成打包
| - 5.项目部署
  | - a)本地部署
  | - b)服务器部署
| - 6.结束

0.传送门

如果你是直接

4)router/index.js

看一下路由index.js文件,它引入了vue-router路由管理,还引入了一个Hello组件。
我们需要做的就是将组件(components)映射到路由(routes),然后告诉 vue-router 在哪里渲染它们。routes数组里就是放着N对映射关系。

import Vue from 'vue'
import Router from 'vue-router'
import Hello from '@/components/Hello'   // 引入Hello组件

Vue.use(Router)

export default new Router({
  routes: [
    /******  一对映射 start  *******/
    {
      path: '/',
      name: 'Hello',
      component: Hello
    }
    /******  一对映射 end  *******/
    // 下一对,如果有的话,别忘了逗号
    // ...
  ]
})
5)components/Hello.vue

最后,看一下Hello.vue文件,【template】代码和平时我们写的html基本是一样的,除了用到一些变量、语法,比如这样:

  • {{ msg }} // msg是变量
  • :class="myclass" // myclass是变量
  • :ref="'mass.'+index+'.detail' // index是变量
  • v-if="flag" // flag是变量
  • v-show="page=='Hello'" // page是变量
  • v-for="(item, index) in list" // list是变量
  • v-html="myHtml" // myHtml是变量
  • ...


那接着看一下【script】,这个项目初始化的例子代码比较简单,只有一个data(name忽视,没什么特别的)。这里其实需要了解很多方法,他们都是用来干什么的,怎么用,什么时候用。我们稍后来看一下。



那接着看一下【style】,和平时写的没什么区别。这里重点留意下这个关键字scoped,代码这里有一个注释,说“添加这一关键字表示这些样式被限制在这个组件内,不会污染其他组件”。




大多时候,基本都会添加scoped关键字,不过比如我们在使用elementUI(或者其他UI)的时候,我们需要覆盖它的样式,那可能需要添加多一个,注意这个不带scoped关键字。一般把覆盖的样式独立成一个单独的css文件,通过每个组件的一个个性化class去区分设置多个同样ui的不同样式。



6)常用方法

先看一下官网的这张“生命周期图示”,正如官网所说,一时看不懂,但是用一用就看懂了,记得回来再看看。

Vue教程--使用官方脚手架构建实例(上篇)_第3张图片
lifecycle.png

如果你看得懂这张图,你就会发现App.vue刚好是黄色棱形判断的一种,然后其他components的xxx.vue(比如这里只有一个Hello.vue)就是判断的另外一种。先不多说这张图,在玩的过程中实现你的demo就清楚了。

我们常用的方法有如下一些:

  • props,页面不会有,但是组件基本都会有,主要用于传数据
// 举例
props:{
      id: {
        type: String,
        default: ''
      },
      status: {
        type: Number,
        default: 0
      }
},

  • watch,监视页面某一个值的变化,由它变化可以导致其他变化
// 举例
watch:{
      status(val) {
        if(val == 1) {
              this.value = 'aaaa';
        } else {
              this.value = 'bbbb';
        }
      }
},
  • components,引入组件的时候,我们要在这里声明
// 举例
components: {
      AddDialog,    // 组件1
      ContainerFooter    // 组件2
},
  • beforeRouteEnter,在页面进入前要执行的一些操作放在这里,比如请求数据
// 举例
beforeRouteEnter (to, from, next) {
      getActData(params).then(response => {
           // 拿回结果后才next()
           ...
           next(vm => {
                // 赋值
                ....
           });
      }).catch(err => {
           ....
      });
},
  • created,在页面创建后执行的操作,有些请求也可以放这里
// 举例
created() {
      // 加载列表数据
      this.status = this.$route.query.status == undefined ? 1 : this.$route.query.status;
      this.fetchData();
},
  • computed,比如我根据某个变量做的不同显示、判断,都可以变成一个方法放这里,以便调用
// 举例
computed: {
      confirmText() {
          return this.edit?'立即修改':'立即创建';
      },
 },
  • filters,过滤器,用来将一些值格式化输出显示,比如枚举
// 举例
filters: {
        toDateShort(val) {
          return val.substring(0,11);
        }
},
  • methods,整个页面调用的方法,click事件、change事件都在这里
// 举例
methods: {
        showLoading() {
          this.loading = true
        },
        hideLoading() {
          this.loading = false
        },
},

浏览vue.js的api文档https://cn.vuejs.org/v2/api/,还是有好多东西在不断的开发过程中会被用到。比如slot也是一个很值得研究的东西。

4.项目实操

接下来,我们就一起实现一个小demo,但它的结构应该是比较完善的,至少可以较好的满足大部分场景和功能需求。

Step1. 修改eslint配置

试了一下,standard标准检查出现的错误提示实在太多了,换一下自定义标准,这个没那么严格,不会那么尴尬。

# 新的配置,用来替换原来的标准
module.exports = {
  root: true,
  parser: 'babel-eslint',
  "evn": {
    "node": true,
    "commonjs": true,
    "shared-node-browser": true,
    "browser": true
  },
  parserOptions: {
    sourceType: 'module'
  },
  env: {
    browser: true,
    "es6": true,
    "node": true
  },
  // https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style
  extends: 'eslint:recommended',
  // required to lint *.vue files
  plugins: [
    'html'
  ],
  // add your custom rules here
  'rules': {
    // allow paren-less arrow functions
    'arrow-parens': 0,
    // allow async-await
    'generator-star-spacing': 0,
    // allow debugger during development
    'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
    // allow console
    'no-console': ["error", { allow: ["warn", "error"] }]
  }
}

Step2. 调整结构

先调整一下结构吧,因为后面会陆续用到。考虑到后面一个个添加,会没有一个整体直观的印象,感觉有点乱吧,我个人不太喜欢,就先整体了解一下。

注意:有注释的说明是刚刚新添加的。

vue-demo
| - build
| - config
| - dist
| - node_modules
| - src
  | - api (api接口文件夹)
  | - assets
  | - components (组件文件夹,原来保留)
     | - Hello.vue (转移到views目录下------>)

| - mock (mock.js假数据接口文件夹)
  | - router
  | - store (仓库文件夹)
  | - styles (样式文件夹)
  | - utils (公共方法文件夹)
  | - vendor (第三方库文件夹)
  | - views (页面文件夹)
     | - dashboard (看板页面)
     | - tablelist (列表页面)
     | - error (错误页面)
     | - layout (模版)
     | - login (登陆页面)
     | - hello (原demo的Hello页面)
        | - Hello.vue (------>转移后的位置)
  | - App.vue
  | - main.js
| - static
| - .babelrc
| - .editorconfig
| - .eslintignore
| - .eslintrc.js
| - .gitignore
| - .postcssrc.js
| - index.html
| - package.json
| - README.md

让我们使用npm run dev运行一下demo,会发现报错“在./src/router/index.js里找不到引用的Hello.vue文件”,如下:

Yuxinde-MacBook-Pro:vue-demo yuxin$ npm run dev

> [email protected] dev /Users/yuxin/Documents/Season/Project/Vue/vue-demo
> node build/dev-server.js

> Starting dev server...


 ERROR  Failed to compile with 1 errors                                             09:49:17

This dependency was not found:

* @/components/Hello in ./src/router/index.js

To install it, you can run: npm install --save @/components/Hello
> Listening at http://localhost:8080

这里你需要改一下引用路径,因为刚刚我们调整过结构。修改之后,发现页面正常了,OK。后面我们不会用到Hello.vue这一块,但暂时保留吧。

# ./src/router/index.js
# 将这句
import Hello from '@/components/Hello'
# 改为
import Hello from '@/views/hello/Hello'

Step3. 添加登陆页面

从这里开始,后面的每一步可能会涉及到使用npm install xxx去安装一些模块,来服务项目的创建、运行。

安装element-ui,官方网站:http://element.eleme.io/#/zh-CN/component/installation。

Yuxinde-MacBook-Pro:vue-demo yuxin$ npm install element-ui --save
npm WARN skippingAction Module is inside a symlinked module: not running update [email protected] node_modules/fsevents/node_modules/node-pre-gyp
npm WARN skippingAction Module is inside a symlinked module: not running move [email protected] node_modules/ajv-keywords/node_modules/ajv/node_modules/co
npm WARN skippingAction Module is inside a symlinked module: not running move [email protected] node_modules/ajv-keywords/node_modules/ajv/node_modules/json-stable-stringify
npm WARN skippingAction Module is inside a symlinked module: not running add [email protected] node_modules/ajv-keywords/node_modules/ajv
[email protected] /Users/yuxin/Documents/Season/Project/Vue/vue-demo
└─┬ [email protected] 
  ├── [email protected] 
  ├── [email protected] 
  ├── [email protected] 
  └── [email protected] 

# 然后把项目跑起来
Yuxinde-MacBook-Pro:vue-demo yuxin$ npm run dev

./src/views/login下添加login.vue(也可以index.vue,但是为了清晰,先不这么写)文件,等下编写login.vue的代码。先修改一下路由配置./src/router/index.js,因为等下要访问:

vue-demo
| -

-

| - src
  | -
  | - views
     | -
     | - login
        | - login.vue (新增)

-
# ./src/router/index.js
import Login from '@/views/login/login'   // 新增
...
  routes: [
    {
      path: '/',
      name: 'Hello',
      component: Hello
    },  // 注意逗号
    // 新增
    {
      path: '/login',
      name: 'Login',
      component: Login
    }
  ]

因为我们已经跑起来了项目,在浏览器里访问login看看,http://localhost:8080/#/login 。我们看到一个图片,还发现有个错误,大概说template找不到,先不理它,因为我们的login.vue还是空白的。

我们注意到这样一个问题,为何路由是/#/login这个样子的,这里你的项目可以继续保持这样,但不喜欢也可以改变它。这里我们改变路由router的模式,由默认的hash变为history
相关阅读:https://router.vuejs.org/zh-cn/api/options.html#mode。

# ./src/router/index.js
export default new Router({
  mode: 'history',  // 新增
  routes: [
     ...

之后的访问路径就变为http://localhost:8080/login。刚刚我们发现登陆页面出现了一个大大的logo图片,现在把它去掉,修改./src/App.vue文件,如下:

# ./src/App.vue