1.前端准備工作
首先新建一個項目,然后引入iView插件,配置好router
npm安裝iView
npm install iview --save
cnpm install iview --save
src/main.js文件內容
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import iView from 'iview';
import 'iview/dist/styles/iview.css';
Vue.use(iView);
Vue.config.productionTip = false
new Vue({
router,
render: h => h(App)
}).$mount('#app')
src/router.js文件內容
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/table1',
component: () => import('./views/table1.vue')
},
{
path: '/table2',
component: () => import('./views/table2.vue')
},
{
path: '/table3',
component: () => import('./views/table3.vue')
},
{
path:'/',
redirect:'/table1'
}
]
})
2.后端准備工作
環境說明
python版本:3.6.6
Django版本:1.11.8
數據庫:MariaDB 5.5.60
新建Django項目,在項目中新建app,配置好數據庫
api_test/app01/models.py文件內容
from django.db import models
class UserProfile(models.Model):
name = models.CharField("用戶名", max_length=32)
email = models.EmailField(max_length=32)
status = models.IntegerField(default=1)
def to_dic(self):
return dict([(attr, getattr(self, attr)) for attr in [f.name for f in self._meta.fields]])
api_test/urls.py文件內容
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^get_user/$',views.get_user_list),
]
api_test/app01/views.py文件內容
from django.http import JsonResponse
from .models import UserProfile
def get_user_list(request):
# for i in range(1, 1001): // 向數據庫創建1000條記錄
# name = "user" + str(i)
# email = "user%s@qq.com" % str(i)
# status = random.randint(1, 3)
# user_obj = UserProfile(name=name, email=email, status=status)
# user_obj.save()
current = request.GET.get("current", 1)
size = request.GET.get("size", 0)
sortType = request.GET.get("sortType")
filterType = request.GET.get("filterType")
res_list = []
try:
user_list = UserProfile.objects.all()
if filterType and filterType != "undefined":
user_list = user_list.filter(status=int(filterType))
total = user_list.count()
if current and size:
end = int(current) * int(size)
start = (int(current) - 1) * int(size)
user_list = user_list[start:end]
except Exception as e:
print(e)
return JsonResponse({"result": False}, safe=False)
for user in user_list:
res_list.append(user.to_dic())
if sortType == "desc":
res_list = sorted(res_list, key=lambda x: x["id"], reverse=True)
else:
res_list = sorted(res_list, key=lambda x: x["id"], reverse=False)
res = {
"data": {
"list": res_list,
"total": total
},
"result": True
}
return JsonResponse(res, safe=False)
3.服務端分頁
src/views/table1.vue文件內容
<template>
<div style="padding:32px 64px">
<h1>服務端分頁及選擇頁面數據條數</h1>
<Table
:columns="columns"
:data="data"
:loading="loading"
border
size="small">
</Table>
<div style="text-align:center;margin:16px 0">
<Page
:total="total"
:current.sync="current"
:page-size-opts="page_size_array"
show-sizer
show-total
@on-change="getData"
@on-page-size-change="handleChangeSize"></Page>
</div>
</div>
</template>
<script>
import axios from 'axios'
export default {
data() {
return {
columns:[
{
type:"index",
width:100,
align:'center',
title:'ID',
key:'id',
},
{
title:'姓名',
key:'name',
},
{
title:'狀態',
key:'status',
render: (h, {row}) => {
if (row.status === 1) {
return h('Tag', {
props: {
color: 'green'
}
}, "等級 1")
} else if (row.status === 2) {
return h('Tag', {
props: {
color: 'red'
}
}, "等級 2")
} else if (row.status === 3) {
return h('Tag', {
props: {
color: 'blue'
}
}, "等級 3")
}
},
},
{
title:'郵箱',
key:'email',
}
],
data:[],
loading:false,
page_size_array: [10, 20, 30, 40, 60, 100], // 設置每頁可以切換的條數
total:0,
current:1, // 當前頁面
size:10, // 設置初始每頁可以顯示的數據條數
}
},
methods:{
getData (){
if (this.loading) return;
this.loading = true;
axios.get(`http://127.0.0.1:8000/get_user/?current=${this.current}&size=${this.size}`).then(res => {
if(res.data.result) {
this.data = res.data.data.list;
this.total = res.data.data.total;
this.loading = false
} else {
this.$Message.error('請求失敗');
}
})
},
handleChangeSize (val){
this.size = val;
this.$nextTick(() => {
this.getData();
})
}
},
mounted () {
this.getData();
}
}
</script>
分別運行前后端項目,瀏覽器打開URL:http://localhost:8080/#/table1,渲染效果如下


分頁組件中,在前端代碼里自定義了可以選擇每頁顯示多少條數據的渲染結果

前端的頁碼數改變或者每頁顯示的數據條數被改變都會重新向后端請求數據
4.服務端分頁並排序及過濾
后端代碼不變,src/views/table2.vue文件內容
<template>
<div style="padding:32px 64px">
<h1>服務端分頁並排序,過濾</h1>
<Table
:columns="column"
:data="data"
:loading="loading"
border
@on-sort-change="handleSortChange"
@on-filter-change="handleFilterChange"
size="small"></Table>
<div style="text-align:center;margin:16px 0">
<Page :total="total" show-sizer :current.sync="current" @on-change="getData" @on-page-size-change="handleChangeSize"></Page>
</div>
</div>
</template>
<script>
import axios from 'axios'
export default {
data() {
return {
total: 0,
current: 1,
size:10,
loading: false,
sortType: 'normal', // normal || asc || desc
filterType: undefined, // undefined,1,2
column: [
{
title: "ID",
key: 'id',
sortable: 'custom'
},
{
title: "用戶名",
key: 'name'
},
{
title: "郵箱",
key: 'email'
},
{
title: "等級",
key: 'status',
render: (h, {row}) => {
if (row.status === 1) {
return h('Tag', {
props: {
color: 'green'
}
}, "等級 1")
} else if (row.status === 2) {
return h('Tag', {
props: {
color: 'red'
}
}, "等級 2")
} else if (row.status === 3) {
return h('Tag', {
props: {
color: 'blue'
}
}, "等級 3")
}
},
filters: [
{
label: '級別 1',
value: 1
},
{
label: '級別 2',
value: 2
},
{
label: '級別 3',
value: 3
},
],
filterMultiple: false,
filterRemote(value) {
console.log(value);
this.filterType = value[0];
}
}
],
data: []
}
},
methods: {
handleSortChange({columns, key, order}) {
this.sortType = order;
this.current = 1;
this.getData();
},
handleFilterChange() {
this.current = 1;
this.getData();
},
handleChangeSize (val){
this.size = val;
this.$nextTick(() => {
this.getData();
})
},
getData() {
if (this.loading) return;
this.loading = true;
axios.get(`http://127.0.0.1:8000/get_user/?current=${this.current}&size=${this.size}&sortType=${this.sortType}&filterType=${this.filterType}`).then(res => {
if(res.data.result) {
this.data = res.data.data.list;
this.total = res.data.data.total;
this.loading = false;
} else {
this.$Message.error('請求失敗');
}
})
}
},
mounted() {
this.getData();
}
}
</script>
瀏覽器打開URL:http://localhost:8080/#/table2,渲染效果如下

在前端對用戶ID進行倒序排序

在前端對用戶狀態進行過濾


在前端對用戶進行過濾后再對用戶ID進行倒序排序

在前端頁面進行的每一個分頁或過濾操作,都會重新向后端請求數據
5.前端分頁並排序及過濾
src/views/table3.vue文件內容
<template>
<div style="padding:32px 64px">
<h1>前端分頁並排序,過濾</h1>
<Table
:data="dataWithPage"
:columns="column"
:loading="loading"
border
@on-sort-change="handleSortChange"
@on-filter-change="handleFilterChange"
size="small"></Table>
<div style="text-align:center;margin:16px 0">
<Page :total="limitData.length" :current.sync="current"></Page>
</div>
</div>
</template>
<script>
import axios from 'axios'
export default {
data() {
return {
total: 0,
current: 1,
loading: false,
sortType: 'normal', // normal || asc || desc
filterType: undefined, // undefined,1,2
column: [
{
title: "號碼",
key: 'id',
sortable: 'custom'
},
{
title: "用戶名",
key: 'name',
},
{
title: "郵箱",
key: 'email',
},
{
title: "等級",
key: 'status',
render: (h, {row}) => {
if (row.status === 1) {
return h('Tag', {
props: {
color: 'green'
}
}, "等級 1")
} else if (row.status === 2) {
return h('Tag', {
props: {
color: 'red'
}
}, "等級 2")
} else if (row.status === 3) {
return h('Tag', {
props: {
color: 'blue'
}
}, "等級 3")
}
},
filters: [
{
label: '級別 1',
value: 1
},
{
label: '級別 2',
value: 2
},
{
label: '級別 3',
value: 3
},
],
filterMultiple: false,
filterMethod(value, row) {
if (value === 1) {
return row.status === 1;
} else if (value === 2) {
return row.status === 2;
} else if (value === 3) {
return row.status === 3;
}
},
filterRemote(value) {
this.filterType = value[0];
}
}
],
data: []
};
},
computed: {
limitData() {
let data = [...this.data];
if (this.sortType === 'asc') {
data = data.sort((a, b) => {
return a.number > b.number ? 1 : -1;
})
}
if (this.sortType === 'desc') {
data = data.sort((a, b) => {
return a.number < b.number ? 1 : -1;
})
}
if (this.filterType === 1) {
data = data.filter(item => {
return item.status === 1;
})
} else if (this.filterType === 2) {
data = data.filter(item => {
return item.status === 2;
})
} else if (this.filterType === 3) {
data = data.filter(item => {
return item.status === 3;
})
}
return data;
},
dataWithPage () {
const data = this.limitData;
const start = this.current * 10 - 10;
const end = start + 10;
return [...data].slice(start,end);
}
},
methods: {
getData() {
if (this.loading) return;
this.loading = true;
axios.get(`http://127.0.0.1:8000/get_user/`).then(res => {
if(res.data.result) {
this.data = res.data.data.list;
this.total = res.data.data.total;
this.loading = false;
} else {
this.$Message.error('請求失敗');
}
})
},
handleSortChange({columns, key, order}) {
this.sortType = order;
this.current = 1;
},
handleFilterChange() {
this.current = 1;
this.getData();
},
},
mounted() {
this.getData();
}
}
</script>
瀏覽器打開URL:http://localhost:8080/#/table3,渲染效果如下

進行分頁,選擇下一頁

在前端頁面進行用戶狀態過濾

在前端進行分頁和排序時,不會向后端請求數據,只有當在前端進行過濾時,才會重新向后端請求數據
