vue2.0+Element-ui實戰案例

小周sri的碼農發表於2018-11-03

前言

我們將會選擇使用一些 vue 周邊的庫vue-cli, vue-router,axios,moment,Element-ui搭建一個前端專案案例,後端資料介面,會使用json-server快速搭建一個本地的服務,方便對資料的增刪改查,

利用以上技術我們會搭建一個vue案例,效果展示圖:

 

 

 

以上就是我們最終要實現的全部效果,我會一塊一塊的講解,關於腳手架安裝和json-server搭建,在本次部落格中,不會講解,如果想看的話,在小編的部落格中,也有講解關於腳手架搭建和json-server搭建,如果想學習的話,可以看一下。

1.專案結構展示

       左邊第一個是前端專案結構,第二個為json-server服務端

2.頁面搭建

在本次案例中,小編採用Element-ui快速搭建前端頁面,以提高效率。如果不瞭解的話,可以去官網看一下

  2.1安裝element-ui

 通過npm install element-ui -S 安裝前端ul框架,安裝完之後,並在main.js引入

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

Vue.use(ElementUI)

  2.2頁面佈局UserInfo.vue

  直接通過element-ui中table佈局,把整體建構頁面佈局完成,

<h1>使用者資訊管理介面</h1>
  	<el-row>
  		<el-col :span="20" :push='2'>
  			<div>
  				<el-form :inline="true">
  					<el-form-item style="float: left" label="查詢使用者資訊:">
  						<el-input v-model="keyUser" placeholder="查詢所需要的內容......"></el-input>
  					</el-form-item>
  					<el-form-item style="float: right">
  						<el-button type="primary" size="small" icon="el-icon-edit-outline" @click="hanldeAdd()">新增</el-button>
  					</el-form-item>
  				</el-form>
  			</div>
  			<div class="table">
  				<el-table
				    :data="searchUserinfo(keyUser)"
				    border
				    style="width: 100%">
				    <el-table-column
				      type="index"
				      label="序號"
				      align="center"
				      width="60">
				    </el-table-column>
				    <el-table-column
				      label="日期"
				      align="center"
				      width="120">
				      <template slot-scope="scope">
				        <span>{{ scope.row.date | moment}}</span>
				      </template>
				    </el-table-column>
				    <el-table-column
				      label="姓名"
				      align="center"
				      width="100">
				      <template slot-scope="scope">
				        <span>{{ scope.row.name }}</span>
				      </template>
				    </el-table-column>
				    <el-table-column
				      label="郵箱"
				      align="center"
				      width="160">
				      <template slot-scope="scope">
				        <span>{{ scope.row.email }}</span>
				      </template>
				    </el-table-column>
				    <el-table-column
				      label="標題"
				      align="center"
				      width="160">
				      <template slot-scope="scope">
				        <span>{{ scope.row.title }}</span>
				      </template>
				    </el-table-column>
				    <el-table-column
				      label="評價"
				      align="center"
				      width="200">
				      <template slot-scope="scope">
				        <span>{{ scope.row.evaluate }}</span>
				      </template>
				    </el-table-column>
				    <el-table-column
				      label="狀態"
				      align="center"
				      width="160">
				      <template slot-scope="scope">
				        <span>{{ scope.row.state }}</span>
				      </template>
				    </el-table-column>
				    <el-table-column label="操作" fixed="right">
				      <template slot-scope="scope">
				        <el-button
				          size="mini"
				          @click="handleEdit(scope.$index, scope.row)">編輯</el-button>
				        <el-button
				          size="mini"
				          type="danger"
				          @click="handleDelete(scope.$index, scope.row)">刪除</el-button>
				      </template>
				    </el-table-column>
				  </el-table>
  			</div>
  		</el-col>
  	</el-row>

  

  2.3頁面資料獲取並展示

  通過axios請求本地搭建的服務資料,把得到的資料展示到頁面當中。

       也是通過cnpm install axios --save安裝並在main.js中引入

import axios from 'axios'

Vue.prototype.$axios = axios

 我們需要在方法methods中定義一個getUserInfo方法,用於請求資料

data () {
    return {
        tableData: [],  用於存放資料

        }   
}
getUserInfo() {
  this.$axios.get('http://localhost:3000/data').then(res => {
  	this.tableData = res.data   
  })
},
這是時候,資料是請求到了,但是頁面併為展示,這就關係到vue的生命週期。如果對vue生命週期不是很瞭解的話,可以官網仔細看一遍,

我們只需要在created這個生命週期鉤子中,呼叫我們請求資料的方法就可以把資料展示到頁面中。這樣我們就完成第一步了,頁面資料請求展示
created:在模板渲染成html前呼叫,即通常初始化某些屬性值,然後再渲染成檢視。
created(){
  	this.getUserInfo()
  },

 3.新增資料

剛才我們已經完成第一步,把後臺的資料展示到前端頁面中,接下來我們對資料進行新增,頁面全部都是用element搭建

3.1頁面結構搭建,把AddUserInfo.vue元件當成一個子元件,在父元件中引入這個子元件,點選新增按鈕,彈出這個新增對話方塊

<template>
  <div class="hello">
    <el-dialog title="新增使用者資訊" :visible.sync="dialogAdd.show">
	  <el-form :model="formDate" ref="formdong" label-width="100px" :rules="formrules">
	    <el-form-item label="日期" prop="date">
	      	<el-date-picker
		      v-model="formDate.date"
		      type="date"
		      placeholder="選擇日期">
		    </el-date-picker>
	    </el-form-item>
	    <el-form-item label="姓名" prop="name">
	      <el-input v-model="formDate.name"></el-input>
	    </el-form-item>
	    <el-form-item label="郵箱" prop="email">
	      <el-input v-model="formDate.email"></el-input>
	    </el-form-item>
	    <el-form-item label="標題" prop="title">
	      <el-input v-model="formDate.title"></el-input>
	    </el-form-item>
	    <el-form-item label="評價" prop="evaluate">
	      <el-input v-model="formDate.evaluate"></el-input>
	    </el-form-item>
	    <el-form-item label="狀態" prop="state">
	      <el-input v-model="formDate.state"></el-input>
	    </el-form-item>
	  </el-form>
	  <div slot="footer" class="dialog-footer">
	    <el-button @click="dialogAdd.show = false">取 消</el-button>
	    <el-button type="primary" @click="dialogFormAdd('formdong')">確 定</el-button>
	  </div>
	</el-dialog>
  </div>
</template>

  3.2我們在父元件UserInfo中引入子元件AddUserInfo.vue,

3.<AddUser :dialogAdd="dialogAdd" @update="getUserInfo"></AddUser>  //使用這個元件,


1. import AddUser from './AddUserInfo.vue'   //引入元件  

2. components:{   //註冊
      AddUser,
  }

3.3通過點選父元件的新增按鈕觸發子元件彈出框

dialogAdd是我們在父元件定義的的,需要傳遞給子元件,
<el-button type="primary" size="small" icon="el-icon-edit-outline" @click="hanldeAdd()">新增</el-button>
在data定義用於是否彈出新增彈出框,預設false不彈出,只有點選新增按鈕的時候才彈出彈出框 dialogAdd:{ show:false }, methods方法中 hanldeAdd(){ //新增 this.dialogAdd.show = true; //彈出對話方塊 },

3.4子元件需要接受父元件傳遞的方法.並請求資料。實現新增

<script>
export default {
  name: 'AddUser',
  props:{
  	dialogAdd:Object
  },
  data () {
    return {
      formDate:{
        date:'',
        name:'',
        email:'',
        title:'',
        evaluate:'',
        state:''
      },
      formrules:{
      	date:[{required:true,message:"日期不能為空",trigger:"blur"}],
      	name:[{required:true,message:"使用者名稱不能為空",trigger:"blur"}],
      	email:[{required:true,message:"郵箱不能為空",trigger:"blur"}],
      }
    }
  },
  methods:{
  	dialogFormAdd(formdong) {
  		this.$refs[formdong].validate((valid) => {
          if (valid) {
            this.$axios.post('http://localhost:3000/data',this.formDate).then(res => {
            	this.$message({
            		type:"success",
            		message:"新增資訊成功"
            	})
            	this.dialogAdd.show = false;
            	this.$emit('update');    

            })
            this.formDate  = ""
          } else {
            console.log('error submit!!');
            return false;
          }
        })
  	}
  }
}
</script>
this.$emit('update');   子元件資料發生改變了,父元件檢視卻沒有更新,這時候通過子創父,this.$emit,想父元件傳送子元件傳遞的方法,
<AddUser :dialogAdd="dialogAdd" @update="getUserInfo"></AddUser>  
@update="getUserInfo"    //接受子元件傳遞過來的方法去更新檢視

 4.實現刪除 

<el-button
   size="mini"
   type="danger"
  @click="handleDelete(scope.$index, scope.row)">刪除</el-button>

 刪除資料需要根據id去刪除,使用es6模板字串進行拼接

handleDelete(index,row) {
  		// 刪除使用者資訊
  		this.$axios.delete(`http://localhost:3000/data/${row.id}`).then(res =>{
  			this.$message({
        		type:"success",
        		message:"刪除資訊成功"
        	})
        	this.getUserInfo()    //刪除資料,更新檢視
  		})
  	},

  5.實現編輯功能

在這裡新增彈出框內容和編輯彈出框內容一模一樣,可以選擇進行封裝,封裝成一個元件,新增和編輯共同使用這一個元件,根據自定義一個欄位來判斷點選 的是新增還是編輯按鈕。在本次案例中,沒有封裝,如果想封裝的話,可以自己嘗試封裝元件,來提高效率。

5.1頁面搭建EditUser.vue元件,也是當做一個子元件,在父元件中去引入這個子元件,並把獲取的資料展示到頁面中。

<template>
  <div class="hello">
    <el-dialog title="編輯使用者資訊" :visible.sync="dialogEdit.show">
	  <el-form :model="form" ref="formEdit" label-width="100px" :rules="formrules">
	    <el-form-item label="日期" prop="date">
	      	<el-date-picker
		      v-model="form.date"
		      type="date"
		      placeholder="選擇日期">
		    </el-date-picker>
	    </el-form-item>
	    <el-form-item label="姓名" prop="name">
	      <el-input v-model="form.name"></el-input>
	    </el-form-item>
	    <el-form-item label="郵箱" prop="email">
	      <el-input v-model="form.email"></el-input>
	    </el-form-item>
	    <el-form-item label="標題" prop="title">
	      <el-input v-model="form.title"></el-input>
	    </el-form-item>
	    <el-form-item label="評價" prop="evaluate">
	      <el-input v-model="form.evaluate"></el-input>
	    </el-form-item>
	    <el-form-item label="狀態" prop="state">
	      <el-input v-model="form.state"></el-input>
	    </el-form-item>
	  </el-form>
	  <div slot="footer" class="dialog-footer">
	    <el-button @click="dialogEdit.show = false">取 消</el-button>
	    <el-button type="primary" @click="dialogFormEdit('formEdit')">確 定</el-button>
	  </div>
	</el-dialog>
  </div>
</template>

  在父元件中定義好需要傳遞的資料欄位

dialogAdd:{   //編輯彈出框,預設是false
      	show:false
      },
      form:{    //編輯資訊
        date:'',
        name:'',
        email:'',
        title:'',
        evaluate:'',
        state:''
      },

  5.2也是在方法中點選編輯按鈕,在編輯中,點選拿一行,需要獲取那一行的欄位資料,並把獲取的資料傳遞給子元件顯示到彈出框中,需要肯據row,來獲取每一行的資料。

<el-button
size="mini"
@click="handleEdit(scope.$index, scope.row)">編輯</el-button>
 <el-button
handleEdit(index,row){ //編輯 this.dialogEdit.show = true; //顯示彈 this.form = { date:row.date, name:row.name, email:row.email, title:row.title, evaluate:row.evaluate, state:row.state, id:row.id } },

  當我門列印row的是,就是點選哪一行的編輯按鈕,對應的資料就好列印出來,這時候我們只需要把得到的資料傳遞給子元件就行

5.3父元件得到的資料,子元件通過props接受,和新增資料幾乎一樣

<script>
export default {
  name: 'HelloWorld',
  props:{
  	dialogEdit:Object,
    form:Object
  },
  data () {
    return {
      formrules:{
      	date:[{required:true,message:"日期不能為空",trigger:"blur"}],
      	name:[{required:true,message:"使用者名稱不能為空",trigger:"blur"}],
      	email:[{required:true,message:"郵箱不能為空",trigger:"blur"}],
      }
    }
  },
  methods:{
  	dialogFormEdit(formEdit) {
  		this.$refs[formEdit].validate((valid) => {
          if (valid) {
            this.$axios.put(`http://localhost:3000/data/${this.form.id}`,this.form).then(res => {
            	this.$message({
            		type:"success",
            		message:"編輯資訊成功"
            	})
              console.log(res)
            	this.dialogEdit.show = false;
            	this.$emit('updateEdit')   //更新父元件資料檢視
            })
          } else {
            console.log('error submit!!');
            return false;
          }
        })
  	}
  }
}
</script>

 

6查詢資料

<el-form-item style="float: left" label="查詢使用者資訊:">
  <el-input v-model="keyUser" placeholder="查詢所需要的內容......"></el-input>
</el-form-item>

 6.1需要定義一個查詢方法,通過filter對陣列進行過濾,並返回一個新的資料,最後通過es6中includes方法,判斷查詢的條件是否包含,includes如果包含就返回true,如果不包含就返回false

searchUserinfo(keyUser) {
  		return this.tableData.filter((user) => {
  			if(user.name.includes(keyUser)) {
  				return user
  			}
  		})
  	}

  把定義好的方法,繫結到data,因為這個方法會返回一個新的陣列

 7.時間格式化

寫到這個案例已經基本寫完了,還是一些細節需要修改,比如我我們新增日期,頁面顯示並不是我們想要的。我門只想要右邊的效果.

   

這時候推薦一個日期格式化外掛moment.js,可以快速幫我們解決這個問題

7.1通過npm install moment   --save下載

  在main.js引入

import moment from 'moment'

 我們定義一個全域性過濾的filter,無論在那個元件都可以使用,主要呼叫moment

//獲取年份
Vue.filter('moment', function (value, formatString) {
    formatString = formatString || 'YYYY-MM-DD HH:mm:ss';
    return moment(value).format("YYYY-MM-DD"); // value可以是普通日期 20170723
});

  

8.全部程式碼

8.1UserInfo.vue元件程式碼

<template>
  <div class="info">
  	<h1>使用者資訊管理介面</h1>
  	<el-row>
  		<el-col :span="20" :push='2'>
  			<div>
  				<el-form :inline="true">
  					<el-form-item style="float: left" label="查詢使用者資訊:">
  						<el-input v-model="keyUser" placeholder="查詢所需要的內容......"></el-input>
  					</el-form-item>
  					<el-form-item style="float: right">
  						<el-button type="primary" size="small" icon="el-icon-edit-outline" @click="hanldeAdd()">新增</el-button>
  					</el-form-item>
  				</el-form>
  			</div>
  			<div class="table">
  				<el-table
				    :data="searchUserinfo(keyUser)"
				    border
				    style="width: 100%">
				    <el-table-column
				      type="index"
				      label="序號"
				      align="center"
				      width="60">
				    </el-table-column>
				    <el-table-column
				      label="日期"
				      align="center"
				      width="120">
				      <template slot-scope="scope">
				        <span>{{ scope.row.date | moment}}</span>
				      </template>
				    </el-table-column>
				    <el-table-column
				      label="姓名"
				      align="center"
				      width="100">
				      <template slot-scope="scope">
				        <span>{{ scope.row.name }}</span>
				      </template>
				    </el-table-column>
				    <el-table-column
				      label="郵箱"
				      align="center"
				      width="160">
				      <template slot-scope="scope">
				        <span>{{ scope.row.email }}</span>
				      </template>
				    </el-table-column>
				    <el-table-column
				      label="標題"
				      align="center"
				      width="160">
				      <template slot-scope="scope">
				        <span>{{ scope.row.title }}</span>
				      </template>
				    </el-table-column>
				    <el-table-column
				      label="評價"
				      align="center"
				      width="200">
				      <template slot-scope="scope">
				        <span>{{ scope.row.evaluate }}</span>
				      </template>
				    </el-table-column>
				    <el-table-column
				      label="狀態"
				      align="center"
				      width="160">
				      <template slot-scope="scope">
				        <span>{{ scope.row.state }}</span>
				      </template>
				    </el-table-column>
				    <el-table-column label="操作" fixed="right">
				      <template slot-scope="scope">
				        <el-button
				          size="mini"
				          @click="handleEdit(scope.$index, scope.row)">編輯</el-button>
				        <el-button
				          size="mini"
				          type="danger"
				          @click="handleDelete(scope.$index, scope.row)">刪除</el-button>
				      </template>
				    </el-table-column>
				  </el-table>
  			</div>
  		</el-col>
  	</el-row>
  	<AddUser :dialogAdd="dialogAdd" @update="getUserInfo"></AddUser>
  	<EditUser :dialogEdit="dialogEdit" :form="form" @updateEdit="getUserInfo"></EditUser>
  </div>
</template>

<script>
	import AddUser from './AddUser.vue'
	import EditUser from './EditUser.vue'
export default {
  name: 'info',
  data () {
    return {
      tableData:[],
      dialogEdit:{
      	show:false,
      },
      dialogAdd:{
      	show:false
      },
      keyUser:"",
      form:{    //編輯資訊
        date:'',
        name:'',
        email:'',
        title:'',
        evaluate:'',
        state:''
      },
    }
  },
  methods:{
  	getUserInfo() {
  		this.$axios.get('http://localhost:3000/data').then(res => {
        console.log(res)
  			this.tableData = res.data
  		})
  	},
  	hanldeAdd(){  //新增
  		this.dialogAdd.show = true;
  	},
  	handleEdit(index,row){  //編輯
  		this.dialogEdit.show = true; //顯示彈
  		this.form = {
   			date:row.date,
   			name:row.name,
   			email:row.email,
   			title:row.title,
   			evaluate:row.evaluate,
   			state:row.state,
   			id:row.id
   		}
      console.log(row)
  	},
  	handleDelete(index,row) {
  		// 刪除使用者資訊
  		this.$axios.delete(`http://localhost:3000/data/${row.id}`).then(res =>{
  			this.$message({
        		type:"success",
        		message:"刪除資訊成功"
        	})
        	this.getUserInfo()    //刪除資料,更新檢視
  		})
  	},
  	searchUserinfo(keyUser) {
  		return this.tableData.filter((user) => {
  			if(user.name.includes(keyUser)) {
  				return user
  			}
  		})
  	}
  },
  created(){
  	this.getUserInfo()
  },
  components:{
  	AddUser,
  	EditUser
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1{
	font-size: 30px;
	color: #333;
	text-align: center;
	margin: 0 auto;
	padding-bottom: 5px;
	border-bottom: 2px solid #409EFF;
	width: 300px
}
</style>

8.2AddUserInfo.vue元件

<template>
  <div class="hello">
    <el-dialog title="新增使用者資訊" :visible.sync="dialogAdd.show">
	  <el-form :model="formDate" ref="formdong" label-width="100px" :rules="formrules">
	    <el-form-item label="日期" prop="date">
	      	<el-date-picker
		      v-model="formDate.date"
		      type="date"
		      placeholder="選擇日期">
		    </el-date-picker>
	    </el-form-item>
	    <el-form-item label="姓名" prop="name">
	      <el-input v-model="formDate.name"></el-input>
	    </el-form-item>
	    <el-form-item label="郵箱" prop="email">
	      <el-input v-model="formDate.email"></el-input>
	    </el-form-item>
	    <el-form-item label="標題" prop="title">
	      <el-input v-model="formDate.title"></el-input>
	    </el-form-item>
	    <el-form-item label="評價" prop="evaluate">
	      <el-input v-model="formDate.evaluate"></el-input>
	    </el-form-item>
	    <el-form-item label="狀態" prop="state">
	      <el-input v-model="formDate.state"></el-input>
	    </el-form-item>
	  </el-form>
	  <div slot="footer" class="dialog-footer">
	    <el-button @click="dialogAdd.show = false">取 消</el-button>
	    <el-button type="primary" @click="dialogFormAdd('formdong')">確 定</el-button>
	  </div>
	</el-dialog>
  </div>
</template>

<script>
export default {
  name: 'AddUser',
  props:{
  	dialogAdd:Object
  },
  data () {
    return {
      formDate:{
        date:'',
        name:'',
        email:'',
        title:'',
        evaluate:'',
        state:''
      },
      formrules:{
      	date:[{required:true,message:"日期不能為空",trigger:"blur"}],
      	name:[{required:true,message:"使用者名稱不能為空",trigger:"blur"}],
      	email:[{required:true,message:"郵箱不能為空",trigger:"blur"}],
      }
    }
  },
  methods:{
  	dialogFormAdd(formdong) {
  		this.$refs[formdong].validate((valid) => {
          if (valid) {
            this.$axios.post('http://localhost:3000/data',this.formDate).then(res => {
            	this.$message({
            		type:"success",
            		message:"新增資訊成功"
            	})
            	this.dialogAdd.show = false;
            	this.$emit('update');

            })
            this.formDate  = ""
          } else {
            console.log('error submit!!');
            return false;
          }
        })
  	}
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
  
</style>

8.3EditUser.vue編輯元件

<template>
  <div class="hello">
    <el-dialog title="編輯使用者資訊" :visible.sync="dialogEdit.show">
	  <el-form :model="form" ref="formEdit" label-width="100px" :rules="formrules">
	    <el-form-item label="日期" prop="date">
	      	<el-date-picker
		      v-model="form.date"
		      type="date"
		      placeholder="選擇日期">
		    </el-date-picker>
	    </el-form-item>
	    <el-form-item label="姓名" prop="name">
	      <el-input v-model="form.name"></el-input>
	    </el-form-item>
	    <el-form-item label="郵箱" prop="email">
	      <el-input v-model="form.email"></el-input>
	    </el-form-item>
	    <el-form-item label="標題" prop="title">
	      <el-input v-model="form.title"></el-input>
	    </el-form-item>
	    <el-form-item label="評價" prop="evaluate">
	      <el-input v-model="form.evaluate"></el-input>
	    </el-form-item>
	    <el-form-item label="狀態" prop="state">
	      <el-input v-model="form.state"></el-input>
	    </el-form-item>
	  </el-form>
	  <div slot="footer" class="dialog-footer">
	    <el-button @click="dialogEdit.show = false">取 消</el-button>
	    <el-button type="primary" @click="dialogFormEdit('formEdit')">確 定</el-button>
	  </div>
	</el-dialog>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props:{
  	dialogEdit:Object,
    form:Object
  },
  data () {
    return {
      formrules:{
      	date:[{required:true,message:"日期不能為空",trigger:"blur"}],
      	name:[{required:true,message:"使用者名稱不能為空",trigger:"blur"}],
      	email:[{required:true,message:"郵箱不能為空",trigger:"blur"}],
      }
    }
  },
  methods:{
  	dialogFormEdit(formEdit) {
  		this.$refs[formEdit].validate((valid) => {
          if (valid) {
            this.$axios.put(`http://localhost:3000/data/${this.form.id}`,this.form).then(res => {
            	this.$message({
            		type:"success",
            		message:"編輯資訊成功"
            	})
              console.log(res)
            	this.dialogEdit.show = false;
            	this.$emit('updateEdit')
            })
          } else {
            console.log('error submit!!');
            return false;
          }
        })
  	}
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
  
</style>

  以上這次全部的案例deom,在過程中有些說的不是很好,請見諒,如果喜歡,請多多關注

 

相關文章