Vue項目的搭建

前言:爲公司前端項目搭建整理的一份文檔javascript

1、項目環境

一、node安裝

 

下載地址:http://nodejs.cn/download/css

 

 

安裝檢查:html

命令:
node -v
npm -v

注:若需更改node模塊(node_modules)的安裝目錄自行百度,因爲建立的Vue項目中node模塊是安裝在項目文件夾下就不作更改了。前端

 若使用淘寶npm鏡像(cnpm)經過如下命令安裝:vue

$ npm install -g cnpm --registry=https://registry.npm.taobao.org

二、Vue-Cli安裝

1)、vue-cli@2.X版本

官方文檔:https://github.com/vuejs/vue-cli/tree/v2#vue-cli--java

注:使用的一些UI組件不適配vue-cli@3.x,因此須要安裝vue-cli@2.xnode

 

好比VUXwebpack

 

安裝命令:ios

$ npm install -g vue-cli

查看版本:git

$ vue –version
使用:
$ vue init <template-name> <project-name>

例如:
$ vue init webpack my-project

將從vuejs-templates/webpack中提取模板信息,根據此模板信息生成項目(./my-project/)

 2)、@vue/cli 3.x 版本

官方文檔:https://cli.vuejs.org/zh/guide/

安裝命令:

$ npm install -g @vue/cli

查看版本:

$ vue --version

使用:

$ vue create <project-name>

2、項目建立

本項目使用的vue-cli版本:2.9.6

一、建立本地項目

在本地/d/Projects目錄下建立名爲project-demo的項目

 

Vue build

第一個選項能夠不基於.vue文件開發,在運行時會進行編譯

第二個選項基於.vue文件開發,比第一個選項小6KB

使用vue-router

使用ESLint進行代碼檢測(ESLint 是一個語法規則和代碼風格的檢查工具,能夠用來保證寫出語法正確、風格統一的代碼。)

ESLint代碼檢測規則(本項目使用Standard),官方文檔鏈接:

Standard:https://github.com/standard/standard/blob/master/docs/README-zhcn.md

Airbnb:https://github.com/airbnb/javascript

安裝完成後運行上述命令:

$ cd project-demo
$ npm run dev

根據運行成功後的地址在瀏覽器進行訪問

二、目錄結構以下:

 

.
|-- README.md
|-- build
|   |-- build.js
|   |-- check-versions.js
|   |-- logo.png
|   |-- utils.js
|   |-- vue-loader.conf.js
|   |-- webpack.base.conf.js
|   |-- webpack.dev.conf.js
|   `-- webpack.prod.conf.js
|-- config
|   |-- dev.env.js
|   |-- index.js
|   `-- prod.env.js
|-- index.html
|-- package-lock.json
|-- package.json
|-- src
|   |-- App.vue
|   |-- assets
|   |   `-- logo.png
|   |-- components
|   |   `-- HelloWorld.vue
|   |-- main.js
|   `-- router
|       `-- index.js
`-- static

 

三、將本地倉庫與線上倉庫關聯:

$ cd /project-demo
$ git init
$ git remote add origin <線上git倉庫地址(SHH)>
$ git add .
$ git commit
$ git push -u origin master

3、項目初始化配置

附:使用Visual Studio Code推薦安裝如下擴展程序

1)    Vetur
2)    ESLint
3)    Beautify
4)    GitLens — Git supercharged
5)    Git History
6)    HTML CSS Support
7)    HTML Snippets
8)    Vue 2 Snippets
9)    Debugger for Chrome

附:目錄結構

項目結構多采用vue-element-admin項目結構:https://panjiachen.gitee.io/vue-element-admin-site/zh/guide/

|-- README.md
|-- build                            # 項目打包配置
|-- config                           # 項目配置
|-- index.html                       # html模板
|-- package-lock.json                # postcss 配置
|-- package.json                     # package.json
|-- src                              # 源代碼
|   |-- App.vue                      # 入口頁面
|   |-- api                          # 全部請求
|   |-- assets                       # 主題 字體等靜態資源
|   |-- axios                        # axios通用配置
|   |-- components                   # 全局公用組件
|   |-- directive                    # 全局指令
|   |-- filters                      # 全局 filter
|   |-- layout                       # 全局 layout
|   |-- main.js                      # 入口文件 加載組件 初始化等
|   |-- router                       # 路由
|   |-- store                        # vuex配置,全局 store管理
|   |-- styles                       # 全局樣式、自定義主題等
|   |-- utils                        # 全局公用方法
|   `-- views                        # 全部頁面
`-- static

 

一、ESLint規則配置

修改.eslintrc.js文件配置,在rules對象中添加如下配置(其餘配置默認):

// 在函數括號以前不容許空格
'space-before-function-paren': ['error', 'never']

 

修改package.json文件配置:

 

添加後運行如下命令能夠快速修復ESLint報錯:

$ npm run lint

二、UI組件安裝

1)、PC端(element-ui)

官方文檔https://element.eleme.cn/#/zh-CN/component/installation

npm安裝:

$ npm i element-ui -S

Element完整引入

main.js 中寫入如下內容:

import Vue from 'vue'

import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'

import App from './App'
import router from './router'

Vue.config.productionTip = false

Vue.use(ElementUI)

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  render: h => h(App)
})

2)、移動端(VUX/Mint UI)

VUX文檔https://doc.vux.li/zh-CN/

Mint UI文檔https://mint-ui.github.io/docs/#/zh-cn2

三、css預處理器安裝(less/sass/stylus)

本項目安裝sass預處理器

Sass文檔:https://www.sass.hk/docs/

安裝:

$ npm install node-sass --save-dev
$ npm install sass-loader --save-dev

四、axios配置

文檔https://www.kancloud.cn/yunye/axios/234845

1)、npm安裝:

$ npm install axios

2)、請求攔截配置

src目錄下建立axios文件夾,並於其中建立index.js文件,內容以下(PC端配置了element-ui的一個加載組件):

import axios from 'axios'
import { Notification, Loading } from 'element-ui'

// 根據環境設置請求baseURL
axios.defaults.baseURL = process.env.API_ROOT
// 請求超時時間
axios.defaults.timeout = 6000
// post請求頭
axios.defaults.headers.post['Content-Type'] = 'application/json;charset=utf-8'

let loading
// 請求攔截器
axios.interceptors.request.use(
  config => {
    // 加載提示
    loading = Loading.service({
      lock: true,
      text: '拼命加載中',
      spinner: 'el-icon-loading',
      background: 'rgba(0, 0, 0, 0.7)'
      // background: 'rgba(255, 255, 255, 0)'
    })
    return config
  },
  error => {
    return Promise.reject(error)
  }
)

// 響應攔截器
axios.interceptors.response.use(
  response => {
    // 關閉加載提示
    loading.close()
    return response
  },
  error => {
    // 關閉加載提示
    loading.close()
    if (error && error.response) {
      switch (error.response.status) {
        case 400:
          Notification.error({
            message: '請求錯誤'
          })
          break

        case 403:
          Notification.error({
            message: '拒絕訪問'
          })
          break

        case 404:
          Notification.error({
            message: '請求地址出錯'
          })
          break

        case 408:
          Notification.error({
            message: '請求超時'
          })
          break

        case 500:
          Notification.error({
            message: '服務出錯'
          })
          break

        case 501:
          Notification.error({
            message: '網絡未實現'
          })
          break

        case 502:
          Notification.error({
            message: '網絡錯誤'
          })
          break

        case 503:
          Notification.error({
            message: '服務不可用'
          })
          break

        case 504:
          Notification.error({
            message: '網絡超時'
          })
          break

        default:
      }
    } else if (error.message === 'Network Error') {
      Notification.error({
        message: '網絡錯誤'
      })
    } else if (error.code === 'ECONNABORTED' && error.message.indexOf('timeout') !== -1) {
      Notification.error({
        message: '請求超時,請重試'
      })
    }

    return Promise.reject(error)
  }
)

export default axios

3)、API請求管理

src目錄下新建api文件夾,文件夾中根據API類型新建對應的js文件模塊以便管理。

例如用戶信息請求API新建userApi.js文件

文件內容格式以下:

import request from '@/axios'

/**
 * 用戶登陸
 * @param {Object} data 用戶帳號信息對象
 */
export function login(data) {
  return request({
    url: '/user/login',
    method: 'post',
    data
  })
}

/**
 * 獲取用戶信息
 * @param {String} token token
 */
export function getInfo(token) {
  return request({
    url: '/user/info',
    method: 'get',
    params: { token }
  })
}

4)、js中調用

//script標籤內進行導入
import * as userApi from '@/api/userApi'

//使用:
userApi.login({username: '張三', password: '123456'})
    .then(res => {
        const { data } = res
        console.log(data)
})

五、Vue Router配置

1)、router/index.js配置文件修改

文檔https://router.vuejs.org/zh/installation.html

|-- src
…
|   |-- layout
|   |   `-- index.vue
…
|   |-- router
|   |   |-- index.js
|   |   `-- modules
|   |       `-- userCenter.js
import Vue from 'vue'
import Router from 'vue-router'

import Layout from '@/layout'

/* Router Modules */
import userRouter from './modules/userCenter'

Vue.use(Router)

const router = new Router({
  // 路由跳轉後從新定位到頂部
  scrollBehavior: () => ({ y: 0 }),
  routes: [
    userRouter,
    {
      path: '/',
      name: 'Layout',
      component: Layout,
      meta: {title: '主頁'}
    },
    { path: '*', component: () => import('@/components/404') }
  ]
})

export default router

能夠根據項目須要可配置導航守衛、路由模塊等相關配置

2)、全局layout

src目錄下新建layout文件夾,其中新建index.vue文件

<template>
  <div>
    Layout
    <router-view/>
  </div>
</template>

<script>
export default {
  name: 'Layout'
}
</script>

<style lang="scss" scoped>

</style>

六、Vuex配置

文檔:https://vuex.vuejs.org/zh/

1)、Vuex安裝

$ npm install vuex --save

2)、vuex-persistedstate安裝

文檔:https://github.com/robinvdvleuten/vuex-persistedstate

vuex-persistedstate是一個將vuex持久化的插件

$ npm install --save vuex-persistedstate

3)、配置

src目錄下新建store文件夾,其下新建index.js、mutation-types.js文件modules文件夾

-- store
   |   |-- index.js
   |   |-- modules
   |   |   `-- user.js
   |   `-- mutation-types.js

store 分割成模塊(module),每一個模塊擁有本身的 state、mutation、action、getter、甚至是嵌套子模塊——從上至下進行一樣方式的分割。

使用常量替代 mutation 事件類型(使用 ES2015 風格的計算屬性命名功能來使用一個常量做爲函數名),把這些常量放在單獨的文件中可讓你的代碼合做者對整個 app 包含的 mutation 一目瞭然。

新建mutation-types.js文件存放常量,例如:

// mutation-types.js
// user modules
export const SET_USER_NAME = 'SET_USER_NAME'
// user.js
import * as types from '../mutation-types'

const state = {
  userName: ''
}

const mutations = {
  [types.SET_USER_NAME](state, str) {
    state.userName = str
  }
}

const actions = {
  saveUserName({ commit }, str) {
    commit(types.SET_USER_NAME, str)
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}

index.js配置以下:

vuex-persistedstate插件僅將須要持久化的狀態值進行持久化。

import Vue from 'vue'
import Vuex from 'vuex'
import CreatePersistedState from 'vuex-persistedstate'

Vue.use(Vuex)

// webpack v4.35.2 依賴管理
// https://webpack.js.org/guides/dependency-management/#requirecontext
const modulesFiles = require.context('./modules', false, /\.js$/)

// 自動請求modules目錄下的模塊文件
const modules = modulesFiles.keys().reduce((modules, modulePath) => {
  // 模塊名爲modules目錄下的js文件名
  const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')

  // value 爲請求到的模塊文件內容 {default:{state:{...},mutations:{...},actions:{...}}, __esModule: true}
  const value = modulesFiles(modulePath)
  modules[moduleName] = value.default
  return modules
}, {})

const vuexPersisted = new CreatePersistedState({
  key: 'VuexPersisted',
  storage: window.localStorage,
  reducer: state => ({
    user: {
      userName: state.user.userName
    }
  })
})

const store = new Vuex.Store({
  modules,
  plugins: [vuexPersisted]
})

export default store

4)、組件中使用

使用方式就不一一列舉了,如下僅列舉其中一種,其餘的能夠去看官方文檔。

訪問state值時,使用對象展開運算符將此對象混入到局部計算屬性中。

import { mapState } from 'vuex'

export default {
    computed: {
        ...mapState('user', ['userName'])
    },

      mounted() {
        console.log(this.userName)
}
}

 

訪問actions,使用對象展開運算符將此對象混入到局部 methods 中。

import { mapActions } from 'vuex'

export default {
  methods: {
    ...mapActions('user', ['saveUserName']),

    // 登陸時存儲用戶名
    login() {
      this.saveUserName('80xxxxx06@qq.com')
    }
  }
}

七、自定義樣式/主題配置

src目錄下新建styles文件夾

|-- src
…
|   |-- styles
|   |   |-- border.css                  #app一像素邊框解決
|   |   |-- element-ui.scss             #自定義的element-ui組件樣式
|   |   |-- element-variables.scss      #經過element-ui樣式變量修改通用主題
|   |   |-- index.scss                  #全局通用樣式引入/定義
|   |   |-- mixin.scss                  #自定義的scss混合指令
|   |   |-- reset.css                   #css樣式重置文件
|   |   |-- transition.scss             #自定義過渡樣式
|   |   `-- variables.scss              #自定義樣式變量

main.js中引入

import '@/styles/index.scss' // 全局 css 樣式

八、打包相關配置修改

1)、config/index.js文件修改

將文件中build對象中assetsPublicPath值改成’./’

assetsPublicPath: './',

2)、build/utils.js文件修改

if (options.extract) {
return ExtractTextPlugin.extract({
       use: loaders,
       publicPath: '../../',
       fallback: 'vue-style-loader'
})
} else {
return ['vue-style-loader'].concat(loaders)
}

以上配置中添加了 publicPath 配置 ’../../’

此配置解決打包後圖片讀取路徑錯誤問題

九、多環境打包配置

一)、配置方式一:

http://www.javashuo.com/article/p-seozhmxf-bp.html

二)、配置方式二:

注:因爲我以前寫文檔一的配置方式稍顯繁瑣,現將文檔一的配置進行簡化。這次文檔就只配置開發、測試、生產三個環境,添加其餘環境的配置方式同樣。

一、安裝依賴:cross-env

$ npm i --save-dev cross-env

二、修改項目 package.json 文件

"scripts": {
    "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
    "start": "npm run dev",
    "lint": "eslint --fix --ext .js,.vue src",
    "build:dev": "cross-env NODE_ENV=production ENV_CONFIG=dev node build/build.js",
    "build:test": "cross-env NODE_ENV=production ENV_CONFIG=test node build/build.js",
    "build:prod": "cross-env NODE_ENV=production ENV_CONFIG=prod node build/build.js"
},

三、修改項目 config 配置文件

目錄結構
|-- config
|   |-- dev.env.js
|   |-- index.js
|   |-- prod.env.js
|   `-- test.env.js
1)、修改 dev.env.js 文件
'use strict'
const merge = require('webpack-merge')
const prodEnv = require('./prod.env')

const env = process.env.NODE_ENV

module.exports = merge(prodEnv, {
  NODE_ENV: '"development"',
  ENV_CONFIG: '"dev"',
  API_ROOT: env === 'production' ? '"http://(線上開發環境請求地址)"' : '"/apis"'
})
2)、添加 test.env.js 文件

 

'use strict'
const merge = require('webpack-merge')
const prodEnv = require('./prod.env')

module.exports = merge(prodEnv, {
  NODE_ENV: '"testing"',
  ENV_CONFIG: '"test"',
  API_ROOT: '"http://(線上測試環境請求地址)"'
})

 

3)、修改 prod.env.js 文件
'use strict'
module.exports = {
  NODE_ENV: '"production"',
  ENV_CONFIG: '"prod"',
  API_ROOT: '"http://(線上生產環境請求地址)"'
}
4)、修改 index.js 文件

解決本地開發啓動後瀏覽器跨域問題,在此處配置服務代理。

dev對象參數下修改以下配置:

proxyTable: {
  '/apis': {
        target: 'http://(本地開發環境請求地址)',
       changeOrigin: true, // 是否容許跨域
       pathRewrite: {
         '^/apis': '' // 重寫
 } },
},

 

build 對象參數下添加以下參數

devEnv: require('./dev.env'),
testEnv: require('./test.env'),
prodEnv: require('./prod.env'),

 

四、修改 build.js 文件

// process.env.NODE_ENV = 'production'  // 將此行代碼註釋

// const spinner = ora('building for production...')
const spinner = ora('building for ' + process.env.NODE_ENV + ' of ' + process.env.ENV_CONFIG + ' production...')

 

 

五、修改 webpack.prod.conf.js 文件

原代碼
const env = require('../config/prod.env')


修改後
const env = config.build[process.env.ENV_CONFIG+'Env']

三)、項目中 HTTP 請求設置

配置文檔一中是在 API 文件中獲取配置的請求地址,也能夠在 axios 配置中設置統一的默認請求地址

詳見 axios 配置中,axios 文件夾下的 index.js 配置文件

// 根據環境設置請求baseURL
axios.defaults.baseURL = process.env.API_ROOT
相關文章
相關標籤/搜索