Vue 新手學習筆記:vue-element-admin 之入門開發教程(v4.0.0 之前)

樂之終曲發表於2019-03-19

說實話都是逼出來的,對於前端沒幹過ES6都不會的人,vue視訊也就看了基礎的一些
但沒辦法,接下來做微服務架構,前端就用 vue,這塊你負責。。。。說多了都是淚,腳手架框架布了都沒看過
幹就完事,不過好在做好了,這裡寫下給和我一樣苦逼的同學能快點適應入門下,當然一些基礎的東西還是要知道的

v4.0.0 版本的調整後講解:Vue 新手學習筆記:vue-element-admin 之 入門開發教程(v4.0.0 之後)

主要分為幾個部分

  • 安裝

  • 準備工作

  • mock 假資料頁面

  • axios 連線後臺真資料

  • 正式環境部署

  • 前端完整程式碼

肯定有地方不太對的,麻煩大家指出來

安裝

前端我推薦用 vscode 就是好用

vscode官網

安裝node.js及npm

npm官網地址

下載node,安裝很簡單一直下一步就可以了。

win+R 輸入cmd進入命令列 輸入

node -v
npm -v

出現以上資訊說明node.js及npm安裝成功

下載 vue-element-admin,並啟動

官方:https://github.com/PanJiaChen/vue-element-admin

框架裡的元件樣式可以從 element 上找 

element:http://element-cn.eleme.io/#/zh-CN/component/table

可以直接下載壓縮包解壓,也可以通過 git 下載

# 克隆專案
git clone https://github.com/PanJiaChen/vue-element-admin.git

# 安裝依賴
npm install

#設定淘寶倉庫
npm install --registry=https://registry.npm.taobao.org

# 啟動服務
npm run dev

 

├── build                      // 構建相關  
├── config                     // 配置相關
├── src                        // 原始碼
│   ├── api                    // 所有請求
│   ├── assets                 // 主題 字型等靜態資源
│   ├── components             // 全域性公用元件
│   ├── directive              // 全域性指令
│   ├── filtres                // 全域性 filter
│   ├── icons                  // 專案所有 svg icons
│   ├── lang                   // 國際化 language
│   ├── mock                   // 專案mock 模擬資料
│   ├── router                 // 路由
│   ├── store                  // 全域性 store管理
│   ├── styles                 // 全域性樣式
│   ├── utils                  // 全域性公用方法
│   ├── vendor                 // 公用vendor
│   ├── views                   // view
│   ├── App.vue                // 入口頁面
│   ├── main.js                // 入口 載入元件 初始化等
│   └── permission.js          // 許可權管理
├── static                     // 第三方不打包資源
│   └── Tinymce                // 富文字
├── .babelrc                   // babel-loader 配置
├── eslintrc.js                // eslint 配置項
├── .gitignore                 // git 忽略項
├── favicon.ico                // favicon圖示
├── index.html                 // html模板
└── package.json               // package.json

準備工作

漢化

開啟vscode後
Windows、Linux 快捷鍵是:ctrl+shift+p

macOS 快捷鍵是:command + shift + p
搜尋 Configure Language,選擇下圖第一個選項。

將"locale":“en” 修改為 “locale”:“zh-CN” ,儲存檔案。
選擇左側左下方的擴充套件按鈕,搜尋chinese 安裝下圖的外掛

安裝成功以後重啟vscode,語言就改成中文了。


推薦安裝一些好用的擴充套件

Auto Close Tag 自動閉合HTML標籤
Auto Rename Tag 修改HTML標籤時,自動修改匹配的標籤
Beautify 程式碼美化
ESLint ESLint 外掛,高亮提示
File Peek 根據路徑字串,快速定位到檔案
HTML CSS Support css提示(支援vue)
HTMLHint HTML格式提示
JavaScript (ES6) code snippets ES6語法程式碼段
Vetur Vue程式碼高亮及補全
VS Color Picker vs顏色選擇器
Vue 2 Snippets Vue2程式碼補全
open in browser 在瀏覽器中預覽

ESLint

剛開始很難用,瘋狂報錯,那是因為沒配好,配好後一些小的問題,會自動修正,在儲存的時候

檔案 ➡ 首選項 ➡ 設定 ➡ 搜尋 ESLint ➡ 點選在 setting.json 中編輯 ➡ 粘進去,儲存,完事

{
  "files.autoSave": "off",
  "eslint.validate": [
    "javascript",
    "javascriptreact",
    "vue-html",
    {
      "language": "vue",
      "autoFix": true
    }
  ],
  "eslint.run": "onSave",
  "eslint.autoFixOnSave": true
}

dev.env.js

先來看下 config 資料夾下的 dev.env.js

這個資料夾裡的 BASE_API 後臺介面的就是公共路徑,調後臺的時候要記得改,這是本地的,剩下的 prod 和 sit 分別是正式環境打包和 測試環境打包的

/src/router/index.js

先來看下目錄

詳細的解釋在這個目錄檔案的上面有,每個屬性什麼意思,可以在上面看

mock 假資料頁面

mock 主要是幫助前後分離的專案為前端提供資料,這樣才好測試

先來畫個頁面,一個分頁列表吧,路徑 /src/service/dataLog.vue 用來顯示一些資訊

我在 element 元件裡找了一個列表功能和分頁功能

/src/service/dataLog.vue

dataLog.vue 的 template 部分

<template>
  <div class="app-container">
    <!-- 查詢框 雙向繫結 keyword-->
    <el-input
      v-model="keyword"
      placeholder="請輸入關鍵字"
      clearable
      style="width:500px" />
    <!-- 搜尋按鈕 繫結點選事件 -->
    <el-button type="primary" icon="el-icon-search" @click="getDataLog()">搜尋</el-button>
    <!-- data就是繫結資料用的 -->
    <el-table
      :data="dataLog"
      style="width: 100%">
      <el-table-column type="expand">
        <template slot-scope="props">
          <el-form label-position="left" inline class="demo-table-expand">
            <el-form-item label="錯誤資訊">
              <span>{{ props.row.log }}</span>
            </el-form-item>
          </el-form>
        </template>
      </el-table-column>
      <el-table-column
        label="服務單"
        prop="data"/>
      <el-table-column
        label="時間"
        prop="time"/>
    </el-table>
    <!-- 分頁 -->
    <pagination
      v-show="total>0"
      :total="total"
      :page.sync="listQuery.page"
      :limit.sync="listQuery.limit"
      @pagination="getDataLog" />
      <!-- total總條數
     listQuery.page 當前頁
     listQuery.limit 每頁幾條
     getDataLog 後買點選分頁時候要回撥的函式 -->
  </div>
</template>

注意 template 下只能有一個節點,兩個就報錯了,可以試下,所有我放在一個統一的 div 裡

至於這些值為啥這樣寫,我只能說照著人家給的模板改就好,人家寫啥你寫啥,樣式啥的人家上面都有

樣式部分就不貼了,最後會把完整的程式碼貼出來,來看下 js 的部分

這裡解釋下分頁,分頁除了初始化給了第 1 頁和每頁 10 條後,之後每次點選頁碼,資料都會雙向繫結到值上,所有在調後臺函式的時候,直接取 page 和 limit 值就行了,不想要再去想我怎麼去拿 div 上面的數字

<script>
// 這裡要呼叫我使用的 api
// 括號裡的是要使用的函式介面,多個的話逗號隔開
import { getDataLog } from '@/api/service/dataLog'
// 引入分頁元件
import Pagination from '@/components/Pagination'

export default {
  // 這裡需要把分頁元件註冊進來
  components: { Pagination },
  data() {
    return {
      // 搜尋關鍵字
      keyword: '',
      // 資料條數
      total: 0,
      // 分頁引數
      listQuery: {
        page: 1,
        limit: 10
      },
      // 列表資料
      dataLog: []
    }
  },
  // 這個是生命週期函式,這個時候是 data 和 methods 都初始化好了,具體看基礎知識
  created() {
    this.getDataLog()
  },
  methods: {
    // 函式部分
    getDataLog() {
      // 引數
      this.listQuery = {
        page: this.listQuery.page,
        limit: this.listQuery.limit,
        object: this.keyword
      }
      // 呼叫上面引入的 api 裡的 getDataLog
      // 不引入就報函式未定義了,剛開始一個人折騰好久,老子明明定義在這了,為啥還沒定義
      getDataLog(this.listQuery).then(response => {
        // 返回值處理
        this.dataLog = []
        this.total = response.data.total
        this.dataLog = response.data.items
        // 查詢後要把關鍵字給清空
        this.keyword = ''
      })
    }
  }
}
</script>

接下來看看上面的 api 介面

/src/api/service/dataLog.js

每次點選就會去呼叫 api 介面裡的方法,引數都看得懂

上面引用的 request 檔案使得每次呼叫的時候都會對請求進行攔截,上面的 BASE_API 就會在裡面被拼上去

import request from '@/utils/request'

// 獲取錯誤資訊列表
export function getDataLog(query) {
  return request({
    url: '/log/getDataLog',
    method: 'get',
    params: query
  })
}

/src/mock/service/dataLog.js

接下來就是使用 mock 假資料,我就迴圈了10條,因為假的分頁,特意去實現太費勁了

如果有多個介面的資料要返回,可以在 export default 裡寫多個介面去返回

import Mock from 'mockjs'

const List = []

const count = 10

// 模擬錯誤資訊
for (let i = 0; i < count; i++) {
  List.push(Mock.mock({
    data: '12987122',
    time: '好滋好味雞蛋仔',
    log: '江浙小吃、小吃零食江浙小吃、小吃零食'
  }))
}

export default {
  // 獲取錯誤資訊列表
  getDataLog: () => {
    return {
      total: List.length,
      items: List,
      limit: 10
    }
  }
}

/src/mock/index.js

上面的寫完還不行,因為通過 api 提交的請求,mock 不知道哪些是需要請求假資料的,所有需要在 index 檔案裡進行攔截

直接加就好了,就這兩行,把剛寫的假資料引用進來,對請求進行攔截

第一個引數,就是要攔截的 url 這裡就和 api 掛鉤起來了

第二個引數,get 型別請求

第三個引數,/src/mock/service/dataLog.js 裡 export 的對應介面,這樣就和 mock 假資料也掛鉤起來了

需要攔截多少個請求就要寫多少個

然後 npm run dev 執行測試就好了

axios 連線後臺真資料

這裡我偷了個懶,由於 utils/request.js 已經幫我們把 axios 都弄好了,像 BASE_API 的路徑拼接,我又不想再寫個 api 檔案,所以我就直接拿過來用了

先引入

import request from '@/utils/request'

js 部分:

methods: {
    getDataLog() {
      this.listQuery = {
        page: this.listQuery.page,
        limit: this.listQuery.limit,
        object: this.keyword
      }
      // mock 請求假資料
      // getDataLog(this.listQuery).then(response => {
      //   this.dataLog = []
      //   this.total = response.data.total
      //   this.dataLog = response.data.items
      //   // 查詢後要把關鍵字給清空
      //   this.keyword = ''
      // })
      // 請求後臺獲得真實資料
      request({
        url: '/log/getDataLog/',
        method: 'post',
        data: this.listQuery
      }).then(response => {
        this.dataLog = []
        this.total = response.data.pageEntity.total
        this.dataLog = response.data.retData
      })
    }
  }

這裡訪問路徑就是 http://127.0.0.1:8081/log/getDataLog,如果全路徑訪問也是可以的,url 前面帶了 “/”意思就是會進行路徑的拼接,如果寫的是 url: 'log/getDataLog' 那麼訪問就報錯了,因為字首沒拼上,還有要把 mock 裡的 index.js 檔案裡的注掉,要不會攔截變成假資料

這裡用的是 post 方法,後臺部分直接用 @RequestBody 接收引數就好了

也可以用 get 方法,把引數拼在 url 上傳遞,我這採用 restful 形式的介面,用 @PathVariable 接收引數

這時候你可能會遇到跨域問題

新建 config 包

@Configuration
public class CorssDomainConfig implements WebMvcConfigurer {

    @Autowired
    private CorsInterceptor corsInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        InterceptorRegistration registration = registry.addInterceptor(corsInterceptor);
        registration.addPathPatterns("/**");
    }

}

然後新建 interceptor 包

@Component
public class CorsInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        // 新增跨域CORS
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Headers", "Origin,X-Requested-With,Content-Type,Accept,Authorization,token, x-token");
        response.setHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH");
        return true;
    }
}

專案再啟動時,addInterceptors 就會把 preHandle 給註冊成物件,後續請求都會經過 preHandle 介面對請求做出處理

正式環境部署

我這前端採用 Nginx 作為前端的執行容器

詳細部署:Docker 上部署 Nginx

我 Nginx html 資料夾下我保留了 dist目錄

所以 /conf.d/default.conf 要改下

vue 裡 config/sit.env.js,這裡我配置了測試服的,然後在 prod.env.js 配置了正式服的

module.exports = {
  NODE_ENV: '"production"',
  ENV_CONFIG: '"sit"',
  // 專案訪問根路徑
  // 測試服
  BASE_API: '"http://xx.xx.xxx.xxx:xxxx"',
}
#測試服打包
npm run build:sit

#正式服打包
npm run build:prod

命令就在 package.json 裡

打包後會在根目錄生成 dist 資料夾,把資料夾放到伺服器的 html 資料夾下就好了,然後啟動 Nginx,啟動過就不用啟動了,由於我 Nginx 直接配置了 80 埠的,所以直接伺服器路徑訪問就行了

PS:如果遇到了打包報錯的情況,那就把 npm 更新下 npm install ,這會在專案根目錄生成 node_modules 資料夾,這些是需要的依賴,在 linux 上打包我這試了不行,依賴更新了也不對,不知道問題出在哪,應該是 windows 和 linux 依賴不太一樣吧

前端完整程式碼

/src/views/service/dataLog.vue

<template>
  <div class="app-container">
    <!-- 查詢框 雙向繫結 keyword-->
    <el-input
      v-model="keyword"
      placeholder="請輸入關鍵字"
      clearable
      style="width:500px" />
    <!-- 搜尋按鈕 -->
    <el-button type="primary" icon="el-icon-search" @click="getDataLog()">搜尋</el-button>
    <!-- data就是繫結資料用的 -->
    <el-table
      :data="dataLog"
      height="600"
      style="width: 100%">
      <el-table-column type="expand">
        <template slot-scope="props">
          <el-form label-position="left" inline class="demo-table-expand">
            <el-form-item label="錯誤資訊">
              <div v-html="props.row.log"/>
            </el-form-item>
          </el-form>
        </template>
      </el-table-column>
      <el-table-column
        label="服務單"
        prop="data"/>
      <el-table-column
        label="時間"
        prop="time"/>
    </el-table>
    <!-- 分頁 -->
    <pagination
      v-show="total>0"
      :total="total"
      :page.sync="listQuery.page"
      :limit.sync="listQuery.limit"
      @pagination="getDataLog" />
      <!-- total總條數
     listQuery.page 當前頁
     listQuery.limit 每頁幾條
     getDataLog 後買點選分頁時候要回撥的函式 -->
  </div>
</template>

<script>
// import { getDataLog } from '@/api/service/dataLog'
import Pagination from '@/components/Pagination'
import request from '@/utils/request'

export default {
  components: { Pagination },
  data() {
    return {
      // 搜尋關鍵字
      keyword: '',
      // 資料條數
      total: 0,
      // 分頁引數
      listQuery: {
        page: 1,
        limit: 10
      },
      // 列表資料
      dataLog: []
    }
  },
  created() {
    this.getDataLog()
  },
  methods: {
    getDataLog() {
      this.listQuery = {
        page: this.listQuery.page,
        limit: this.listQuery.limit,
        object: this.keyword
      }
      // mock 請求假資料
      // getDataLog(this.listQuery).then(response => {
      //   this.dataLog = []
      //   this.total = response.data.total
      //   this.dataLog = response.data.items
      //   // 查詢後要把關鍵字給清空
      //   this.keyword = ''
      // })
      // 請求後臺獲得真實資料
      request({
        url: '/log/getDataLog/',
        method: 'post',
        data: this.listQuery
      }).then(response => {
        this.dataLog = []
        this.total = response.data.pageEntity.total
        this.dataLog = response.data.retData
      })
    }
  }
}
</script>

<style>
  .demo-table-expand {
    font-size: 0;
  }
  .demo-table-expand label {
    width: 90px;
    color: #99a9bf;
  }
  .demo-table-expand .el-form-item {
    margin-right: 0;
    margin-bottom: 0;
    width: 50%;
  }
</style>

/src/api/service/dataLog.js

import request from '@/utils/request'

// 獲取錯誤資訊列表
export function getDataLog(query) {
  return request({
    url: '/log/getDataLog',
    method: 'get',
    params: query
  })
}

/src/mock/service/index.js

攔截原因,請求後臺就注掉

// Mock.mock(/\/log\/getDataLog/, 'get', dataLogAPI.getDataLog)

/src/mock/service/dataLog.js

import Mock from 'mockjs'

const List = []

const count = 10

// 模擬錯誤資訊
for (let i = 0; i < count; i++) {
  List.push(Mock.mock({
    data: '12987122',
    time: '好滋好味雞蛋仔',
    log: '江浙小吃、小吃零食江浙小吃、小吃零食'
  }))
}

export default {
  // 獲取錯誤資訊列表
  getDataLog: () => {
    return {
      total: List.length,
      items: List,
      limit: 10
    }
  }
}

 

參考:

https://blog.csdn.net/brucelpt/article/details/82994332

相關文章