由於目前vue的使用率挺高的,所以就基於前後端分離的思想搭建一個vue腳手架項目,並實現一個簡單的表格功能。其中包含的技術點有vue腳手架的搭建、父子組件引用、父子組件之間的傳參以及整合Element UI 組件庫等。
一、vue 腳手架搭建
- 先安裝 node [ 腳手架項目需要用到 node 中的 npm ],不會的可以進行百度,此處不做講解。
- 安裝全局 vue-cli ,在命令行執行以下命令
npm install -g @vue-cli
# 或者用以下命令,但需要安裝 cnpm
cnpm install -g @vue-cli
- 安裝完成之後可以通過-v來檢查vue的版本
# 注意是 大寫的 V
vue -V
- 安裝 vue-cli 成功後,進入到想要放置項目的文件夾,執行以下命令創建項目
# test-vue 是我的項目名
vue create test-vue
我們通過上下鍵選擇最後,自定義配置
- 自定義配置,選項如下截圖【Linter/Formatter 最好不選,這是代碼質量檢查工具,即使代碼沒錯只是格式不規範也會報錯,個人覺得比較麻煩】
按上下鍵切換選項,按空格鍵 選擇或取消,根據自己的要求選擇,完成之後回車
- 選擇 CSS預編譯器,我選擇less,這幾個是動態樣式語言,根據個人習慣選擇
- 回車進入代碼檢測工具的選擇,這個在開始的時候最好不要選,本人是因爲誤選,就選擇標準的配置
- 選擇語法檢查的方式,一個是保存時檢測,一個是提交時檢測,此處選擇保存時檢測。
- 把Babel, PostCSS, ESLint, etc.?配置文件放在哪裏,我選擇 package.json 中,便於管理
- 是否記錄這些配置,以便下次使用,由於我之前誤選一個語法檢查的工具,此處就不保存了
- 回車 開始下載依賴模塊
- 下載完成之後會提示運行腳手架的命令,如下圖所示
- 我們依次使用上面的兩個命令,來啓動腳手架項目,啓動完成如下所示
- 如此,項目搭建完成,可以通過上面兩個鏈接訪問項目首頁。
- 項目目錄結構如下,具體目錄的作用 此處不做講解。
- 項目默認端口爲8080,如果項目改變默認端口,可以在項目根目錄創建 vue.config.js ,配置端口號重啓即可,內容如下
module.exports = {
/** 區分打包環境與開發環境
* process.env.NODE_ENV==='production' (打包環境)
* process.env.NODE_ENV==='development' (開發環境)
* baseUrl: process.env.NODE_ENV==='production'?"https://cdn.didabisai.com/front/":'front/',
*/
// 基本路徑
baseUrl: '/',
// 輸出文件目錄
outputDir: 'dist',
// eslint-loader 是否在保存的時候檢查
// lintOnSave: true,
// use the full build with in-browser compiler?
// https://vuejs.org/v2/guide/installation.html#Runtime-Compiler-vs-Runtime-only
//compiler: false,
// webpack配置
// see https://github.com/vuejs/vue-cli/blob/dev/docs/webpack.md
chainWebpack: () => {},
configureWebpack: () => {},
//如果想要引入babel-polyfill可以這樣寫
// configureWebpack: (config) => {
// config.entry = ["babel-polyfill", "./src/main.js"]
// },
// vue-loader 配置項
// https://vue-loader.vuejs.org/en/options.html
//vueLoader: {},
// 生產環境是否生成 sourceMap 文件
// productionSourceMap: true,
// css相關配置
//css: {
// 是否使用css分離插件 ExtractTextPlugin
// extract: true,
// 開啓 CSS source maps?
// sourceMap: false,
// css預設器配置項
// loaderOptions: {},
// 啓用 CSS modules for all css / pre-processor files.
// modules: false
// },
// use thread-loader for babel & TS in production build
// enabled by default if the machine has more than 1 cores
//parallel: require('os').cpus().length > 1,
// 是否啓用dll
// See https://github.com/vuejs/vue-cli/blob/dev/docs/cli-service.md#dll-mode
// dll: false,
// PWA 插件相關配置
// see https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-pwa
// pwa: {},
// webpack-dev-server 相關配置
devServer: {
open: process.platform === 'darwin',
port: 9099,
https: false,
hotOnly: false,
proxy: null, // 設置代理
before: app => {}
},
// 第三方插件配置
pluginOptions: {
// ...
}
}
二、腳手架項目整合Element UI table組件
- App.vue 作爲項目的容器,所有的頁面均需要放在此容器中才能得以展示在頁面讓我們看到。在初始化項目之後,App.vue 中默認有兩個通過路由跳轉的標籤,爲了不影響原有的文件,我們新建一個 UserList.vue 文件放置在 views 文件夾下。
- 在 router.js 中添加新的路由規則,用於跳轉到我們新創建的頁面【 /userList 】
import Vue from 'vue'
import Router from 'vue-router'
import Home from './views/Home.vue'
Vue.use(Router)
export default new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{
path: '/',
name: 'home',
component: Home
},
{
path: '/about',
name: 'about',
component: () => import('./views/About.vue')
},
{
path: '/userList',
name: 'userList',
component: () => import('./views/UserList.vue')
}
]
})
- 在 App.vue 中添加 路由標籤
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>|
<router-link to="/userList">UserList</router-link>
</div>
- 在項目中添加Element-UI依賴
# 在項目根目錄下,運行以下命令,即可添加 Element-UI依賴
npm i element-ui -S
# 添加 axios 用於向後臺發送請求,不可缺少
npm i -save axios
- 在新創建的 UserList.vue 文件中添加表格相關內容
<template>
<div>
<!-- 以下爲搜索框 -->
<div class="demo-input-size">
<el-input
placeholder="請輸入用戶名"
v-model="sname">
</el-input>
<el-input
placeholder="請輸入暱稱"
v-model="snickname">
</el-input>
<el-input
placeholder="請輸入年齡"
v-model="sage">
</el-input>
<el-input
placeholder="請輸入地址"
v-model="saddr">
</el-input>
</div>
<el-button type="primary" @click="search()" icon="el-icon-search">搜索</el-button>
<!-- 以下爲表頭和數據 -->
<el-table
:data="dataList"
stripe
border
height="570"
style="width: 80%; margin-top: 25px;">
<!-- 多選框 -->
<el-table-column
type="selection"
width="55">
</el-table-column>
<el-table-column
prop="id"
label="序號"
width="55">
</el-table-column>
<el-table-column
prop="name"
label="用戶名"
align="center"
width="180">
</el-table-column>
<el-table-column
prop="nickname"
align="center"
label="暱稱">
</el-table-column>
<el-table-column
prop="sex"
align="center"
label="性別">
</el-table-column>
<el-table-column
prop="age"
label="年齡">
</el-table-column>
<el-table-column
prop="birth"
label="生日">
</el-table-column>
<el-table-column
prop="addr"
label="地址">
</el-table-column>
<el-table-column label="操作" width="360">
<template slot-scope="scope">
<el-button size="mini" @click="handleSelect(scope.$index,scope.row)">查看</el-button>
<el-dialog title="查看用戶" :visible.sync="isShow" center :append-to-body='true' :lock-scroll="false" width="40%">
<UserInfo :user="user"></UserInfo>
</el-dialog>
<el-button size="mini" @click="handleUpdate(scope.$index,scope.row)">編輯</el-button>
<el-dialog title="編輯用戶" :visible.sync="isUpdate" center :append-to-body='true' :lock-scroll="false" width="40%">
<UserEdit :user="user" ></UserEdit>
</el-dialog>
<el-button size="mini" type="danger" @click="handleDelete(scope.$index,scope.row)">刪除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 以下爲分頁 -->
<el-pagination
@prev-click="prevPage"
@next-click="nextPage"
@current-change="currentPage"
background
layout="prev, pager, next"
:page-count="total">
</el-pagination>
</div>
</template>
- 只有頁面還不行,由於我們是純前端的項目,沒有後臺的接口。所以需要手動添加模擬數據,在script 標籤中添加以下內容
export default {
data() {
return {
isUpdate: false,//默認彈框隱藏
list:[],// 初始化總數據【刷新重置】
resList:[],// 搜索結果數據[臨時數據]
dataList:[],// 列表展示數據
total:0,
// 以下爲搜索字段
sname:'',
snickname:'',
saddr:'',
sage:'',
}
},
methods:{
getList(){
var obj= null;
for (var i = 0; i<100;i++) {
obj = new Object();
obj.id = (i+1);
obj.name = 'tom'+(i+1);
obj.nickname = '暱稱'+(i+1);
obj.sex = '性別'+(i+1);
obj.age = (i+1);
obj.birth = '2019-'+(i+1);
obj.addr = '地址'+(i+1);
// 由於沒有真實數據,需要通過標識進行僞刪除,如果通過下標刪除 會打亂數組結構,從而刪除會出現問題。(有接口的情況下不會出現問題)。
obj.isDel = 0;
this.list.push(obj);
this.resList.push(obj);
}
// 初始化 展示前十條信息
for(var i=0;i<10;i++){
this.dataList[i] = this.resList[i];
}
this.total = Math.ceil(this.resList.length/10);
}
},
mounted:function(){
this.getList();
}
}
- 到此處,整個合的table已經完成,頁面展示如下
三、父子組件引用
接下來我們來實現父組件 UserList.vue 中引用子組件 UserEdit.vue。
- 新建子組件 UserEdit.vue 放置在 views 目錄下,由於後面要講到父子組件的傳值,所以就直接寫入用戶的屬性內容如下
<template>
<el-form ref='form' >
<el-form-item label='編號'>
<label slot="label">編 號</label>
<el-input v-model='user.id' readonly style="width: 60%;"/>
</el-form-item>
<el-form-item label='用戶名'>
<el-input v-model='user.name' readonly style="width: 60%;"/>
</el-form-item>
<!-- 此處不可直接在label屬性值中加入 空格符(需藉助 label 標籤),否則會把 空格符 顯示出來 -->
<el-form-item label="暱稱">
<label slot="label">暱 稱</label>
<el-input v-model='user.nickname' readonly style="width: 60%;"/>
</el-form-item>
<el-form-item label='性別'>
<label slot="label">性 別</label>
<el-input v-model='user.sex' readonly style="width: 60%;"/>
</el-form-item>
<el-form-item label='年齡'>
<label slot="label">年 齡</label>
<el-input v-model='user.age' readonly style="width: 60%;"/>
</el-form-item>
<el-form-item label='地址'>
<label slot="label">地 址</label>
<el-input v-model='user.addr' readonly style="width: 60%;"/>
</el-form-item>
<el-form-item label='生日'>
<label slot="label">生 日</label>
<el-input v-model='user.birth' readonly style="width: 60%;"/>
</el-form-item>
<!--
<el-form-item>
<el-button type='primary' @click='addUser'>添加</el-button>
<el-button>取消</el-button>
</el-form-item>
-->
</el-form>
</template>
- 在父組件 UserList.vue 中script標籤下引入子組件 UserEdit.vue
import UserEdit from './UserEdit.vue';
// 並在 export default 下添加 該組件
components: {
UserEdit
},
- 在methods 中添加 編輯的方法
handleUpdate(index,row){
// 此屬性用於控制 dialog 彈框的顯示與隱藏,爲true則顯示,在 dialog 標籤中設置
this.isUpdate=true;
}
- 點擊編輯顯示如下,則說明父組件引用子組件成功
四、父子組件傳值
父子組件的傳值是比較重要的因爲在我們平時是使用非常頻繁的。
1、父組件向子組件傳值
- 需要在全局變量中定義一個user 用於傳遞到子組件
data() {
return {
isUpdate: false,
isShow:false,
list:[],// 初始化總數據【刷新重置】
resList:[],// 搜索結果數據[臨時數據]
dataList:[],// 列表展示數據
total:0,
sname:'',
snickname:'',
saddr:'',
sage:'',
user:null
}
},
- 修改 handleUpdate 方法把指定的對象數據傳遞到子組件
handleUpdate(index,row){
// 調用時,顯示彈框組件
this.isUpdate=true;
// 進行對象深拷貝,防止在子組件修改數據時父組件的數據也跟着修改
var obj = this.dCopy(row);
// 把 深拷貝返回的對象賦給 剛纔定義的全局變量 user 用於傳遞給子組件
this.user = obj;
}
- 子組件用 props 接收,js代碼如下
export default{
// 用於接收父組件傳過來的值【可爲 字符串、對象、數組等】
// 此 user 對應 標籤中 v-model中的user
props:["user"],
data(){
return{}
}
}
- 顯示結果如下
2、子組件向父組件傳值
當我們修改用戶信息之後會提交信息到後臺,此時就會用到子向父傳值
- 在父組件中 子組件標籤 UserEdit 中修改如下
<!-- @toparent="getChild" 此函數用於接收子組件傳遞過來的值 -->
<UserEdit :user="user" @toparent="getChild"></UserEdit>
- 在 methods 中添加 getChild 方法
getChild(cuser){
this.user = cuser;
for(var i=0;i<this.list.length;i++){
var obj = this.list[i];
if(this.user.id==obj.id){
this.list[i] = this.dCopy(this.user);
this.resList[i] = this.dCopy(this.user);
}
}
for(var i=0;i<this.dataList.length;i++){
if(this.dataList[i].id==this.user.id){
this.dataList[i]=this.dCopy(this.user);
}
}
// 設置 false 用於關閉彈框
this.isUpdate=false;
}
- 此時,子傳父就完成了,子組件修改信息,提交之後父組件接收到信息後進行修改。
本示例就講到這裏,其他 關於 搜索、分頁、查看、刪除等功能相對比較簡單,此項目就不做詳述!!!