创建项目

使用 @vue/cli 新建项目 vuetify-data-table-example

输入命令:vue create vuetify-data-table-example

在看到的选项中选择以下几项:

  • Choose Vue version
  • Babel
  • Router
  • Vuex

控制台显示安装过程如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
D:\sources\vue_repos>vue create vuetify-data-table-example

Vue CLI v4.5.9
? Please pick a preset: Manually select features
? Check the features needed for your project: Choose Vue version, Babel, Router, Vuex
? Choose a version of Vue.js that you want to start the project with 2.x
? Use history mode for router? (Requires proper server setup for index fallback in production) No
? Where do you prefer placing config for Babel, ESLint, etc.? In dedicated config files
? Save this as a preset for future projects? No


Vue CLI v4.5.9
✨ Creating project in D:\sources\vue_repos\vuetify-data-table-example.
⚙️ Installing CLI plugins. This might take a while...

yarn install v1.22.5
info No lockfile found.
[1/4] Resolving packages...
[2/4] Fetching packages...
info fsevents@2.1.3: The platform "win32" is incompatible with this module.
info "fsevents@2.1.3" is an optional dependency and failed compatibility check. Excluding it from installation.
info fsevents@1.2.13: The platform "win32" is incompatible with this module.
info "fsevents@1.2.13" is an optional dependency and failed compatibility check. Excluding it from installation.
[3/4] Linking dependencies...#################################################################################################] 1060/1060
[4/4] Building fresh packages...
success Saved lockfile.
Done in 16.28s.
🚀 Invoking generators...
📦 Installing additional dependencies...

yarn install v1.22.5
[1/4] Resolving packages...
[2/4] Fetching packages...
info fsevents@2.1.3: The platform "win32" is incompatible with this module.
info "fsevents@2.1.3" is an optional dependency and failed compatibility check. Excluding it from installation.
info fsevents@1.2.13: The platform "win32" is incompatible with this module.
info "fsevents@1.2.13" is an optional dependency and failed compatibility check. Excluding it from installation.
[3/4] Linking dependencies...
[4/4] Building fresh packages...

success Saved lockfile.
Done in 5.71s.
⚓ Running completion hooks...

📄 Generating README.md...

🎉 Successfully created project vuetify-data-table-example.
👉 Get started with the following commands:

$ cd vuetify-data-table-example
$ yarn serve

安装 Vuetify 和 leancloud SDK

添加 vuetify

当vue 项目创建成功后,输入以下命令进入项目文件夹:

cd vuetify-data-table-example

然后再使用命令在项目中安装 vuetify:

vue add vuetify

遇到以下选项时,选择 Default(默认) 项:

1
2
3
4
? Choose a preset: (Use arrow keys)
> Default (recommended)
Prototype (rapid development)
Configure (advanced)

控制台显示安装过程如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
D:\sources\vue_repos\vuetify-data-table-example>vue add vuetify

📦 Installing vue-cli-plugin-vuetify...

yarn add v1.22.5
[1/4] Resolving packages...
[2/4] Fetching packages...
info fsevents@2.1.3: The platform "win32" is incompatible with this module.
info "fsevents@2.1.3" is an optional dependency and failed compatibility check. Excluding it from installation.
info fsevents@1.2.13: The platform "win32" is incompatible with this module.
info "fsevents@1.2.13" is an optional dependency and failed compatibility check. Excluding it from installation.
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Saved lockfile.
success Saved 5 new dependencies.
info Direct dependencies
└─ vue-cli-plugin-vuetify@2.0.8
info All dependencies
├─ interpret@1.4.0
├─ null-loader@3.0.0
├─ rechoir@0.6.2
├─ shelljs@0.8.4
└─ vue-cli-plugin-vuetify@2.0.8
Done in 9.23s.
✔ Successfully installed plugin: vue-cli-plugin-vuetify

? Choose a preset: Default (recommended)

🚀 Invoking generator for vue-cli-plugin-vuetify...
📦 Installing additional dependencies...

yarn install v1.22.5
[1/4] Resolving packages...
[2/4] Fetching packages...
info fsevents@2.1.3: The platform "win32" is incompatible with this module.
info "fsevents@2.1.3" is an optional dependency and failed compatibility check. Excluding it from installation.
info fsevents@1.2.13: The platform "win32" is incompatible with this module.
info "fsevents@1.2.13" is an optional dependency and failed compatibility check. Excluding it from installation.
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Saved lockfile.
Done in 6.94s.
⚓ Running completion hooks...

✔ Successfully invoked generator for plugin: vue-cli-plugin-vuetify
vuetify Discord community: https://community.vuetifyjs.com
vuetify Github: https://github.com/vuetifyjs/vuetify
vuetify Support Vuetify: https://github.com/sponsors/johnleider

安装 leancloud SDK

在控制台输入以下命令安装 leancloud SDK, 建议使用淘宝源以加快安装速度(在 npm install 后添加 –registry=https://registry.npm.taobao.org 参数):

npm install leancloud-storage --save

控制台显示安装过程如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
D:\sources\vue_repos\vuetify-data-table-example>npm install leancloud-storage --save --registry https://registry.npm.taobao.org
npm WARN deprecated core-js@2.6.12: core-js@<3 is no longer maintained and not recommended for usage due to the number of issues. Please, upgrade your dependencies to the actual version of core-js@3.
npm WARN deprecated @hapi/address@2.1.4: This version has been deprecated and is no longer supported or maintained
npm WARN deprecated @hapi/topo@3.1.6: This version has been deprecated and is no longer supported or maintained
npm WARN deprecated @hapi/hoek@8.5.1: This version has been deprecated and is no longer supported or maintained
npm WARN deprecated @hapi/bourne@1.3.2: This version has been deprecated and is no longer supported or maintained
npm WARN deprecated @hapi/joi@15.1.1: joi is leaving the @hapi organization and moving back to 'joi' (https://github.com/sideway/joi/issues/2411)
npm WARN deprecated request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142
npm WARN deprecated har-validator@5.1.5: this library is no longer supported
npm WARN deprecated urix@0.1.0: Please see https://github.com/lydell/urix#deprecated
npm WARN deprecated resolve-url@0.2.1: https://github.com/lydell/resolve-url#deprecated
npm WARN deprecated chokidar@2.1.8: Chokidar 2 will break on node v14+. Upgrade to chokidar 3 with 15x less dependencies.
npm WARN deprecated fsevents@1.2.13: fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.
npm WARN rm not removing D:\sources\vue_repos\vuetify-data-table-example\node_modules\.bin\semver.cmd as it wasn't installed by D:\sources\vue_repos\vuetify-data-table-example\node_modules\semver
npm WARN rm not removing D:\sources\vue_repos\vuetify-data-table-example\node_modules\.bin\semver as it wasn't installed by D:\sources\vue_repos\vuetify-data-table-example\node_modules\semver
npm WARN rm not removing D:\sources\vue_repos\vuetify-data-table-example\node_modules\.bin\json5.cmd as it wasn't installed by D:\sources\vue_repos\vuetify-data-table-example\node_modules\json5
npm WARN rm not removing D:\sources\vue_repos\vuetify-data-table-example\node_modules\.bin\json5 as it wasn't installed by D:\sources\vue_repos\vuetify-data-table-example\node_modules\json5

> core-js@3.8.1 postinstall D:\sources\vue_repos\vuetify-data-table-example\node_modules\@vue\babel-preset-app\node_modules\core-js
> node -e "try{require('./postinstall')}catch(e){}"

Thank you for using core-js ( https://github.com/zloirock/core-js ) for polyfilling JavaScript standard library!

The project needs your help! Please consider supporting of core-js on Open Collective or Patreon:
> https://opencollective.com/core-js
> https://www.patreon.com/zloirock

Also, the author of core-js ( https://github.com/zloirock ) is looking for a good job -)


> core-js@2.6.12 postinstall D:\sources\vue_repos\vuetify-data-table-example\node_modules\babel-runtime\node_modules\core-js
> node -e "try{require('./postinstall')}catch(e){}"


> ejs@2.7.4 postinstall D:\sources\vue_repos\vuetify-data-table-example\node_modules\ejs
> node ./postinstall.js

Thank you for installing EJS: built with the Jake JavaScript build tool (https://jakejs.com/)

npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: vue-loader-v16@npm:vue-loader@^16.0.0-beta.7 (node_modules\@vue\cli-service\node_modules\vue-loader-v16):
npm WARN notarget SKIPPING OPTIONAL DEPENDENCY: No matching version found for vue-loader-v16@16.1.2.
npm WARN @vue/babel-preset-app@4.5.9 requires a peer of core-js@^3 but none is installed. You must install peer dependencies yourself.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.13 (node_modules\chokidar\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@2.1.3 (node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.1.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})

+ leancloud-storage@4.9.0
added 157 packages from 87 contributors, removed 70 packages and updated 1093 packages in 101.605s

64 packages are looking for funding
run `npm fund` for details

leancloud 初始化

在项目中添加以下文件及文件夹:

  • src/api/init.js
  • src/api/config/lc.config.js

编辑 src/api/config/lc.config.js 内容如以下所示(部分字符已经更改为 * , 请使用自己 leancloud应用Keys 进行替换):

1
2
3
4
5
6
7
8
9
10
11
12
// src/api/config/lc.config.js
export default {
//'这里填写 leancloud 的 appId',
id: '9MCRS87WVkReLtNbQWbnllm9-********',

// '这里填写 leancloud 的 appKey',
key: 'zAfYTXaiXYGeQUm8********',

// '这里填写 leancloud 的 REST API 服务器地址,国际版应用等未绑定自定义域名的此项留空'
url: 'https://*******.lc-cn-n1-shared.com',
}

编辑 src/api/init.js, 内容如以下代码所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// src/api/init.js
import LC from 'leancloud-storage';
import config from './config/lc.config';

let initOptions;

if (config.url.trim() === '') {
// url 为空的时候,访问国际版:leancloud.app
initOptions = {
appId: config.id,
appKey: config.key,
};
} else {
// url 不为空的时候,访问国内版:leancloud.cn
initOptions = {
appId: config.id,
appKey: config.key,
serverURLs: config.url,
};
}

// 执行 leanCloud 初始化
LC.init(initOptions);

export default {}

编辑 src/main.js, 添加导入并执行LeanCloud初始化的语句,如以下代码所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// src/main.js
import Vue from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';
import vuetify from './plugins/vuetify';

require('./api/init.js'); // 导入并执行LeanCloud初始化
Vue.config.productionTip = false;

new Vue({
router,
store,
vuetify,
render: h => h(App)
}).$mount('#app');

完成以上操作之后,项目的结构如下图所示:

开发基于 leancloudCRUD 应用

leancloud 添加 class

登录到 leancloud 官方网站,在应用中添加名为 Tutorialclass

Tutorial 类中添加以下三列:

属性名 类型 含义
title String 标题
description String 描述
published Boolean 状态

小技巧:上述在 leancloud 中创建Tutorial的步骤可以省略,当第一次执行添加记录操作时,会自动完成相应类以及列的创建。

创建数据服务层

添加文件 src/api/services/TutorialDataService.js, 编辑其文件内容如以下代码所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
// src/api/services/TutorialDataService.js

import LC from 'leancloud-storage';

class TutorialDataService {
// 获取所有数据,此例使用数据表组件自带的分页功能
// 如要使用手动分页,请参加vuetify 数据表组件进行修改
getAll() {
return new Promise((resolve, reject) => {
let query = new LC.Query('Tutorial');
// 按 createdAt 降序
query.descending('createdAt')
.find()
.then(resp => {
console.log('getAll:', resp);
resolve(resp);
})
.catch(error => {
console.log('getAll:', error);
reject(error);
});
});
}
// 使用id 查询一条记录
get(id) {
return new Promise((resolve, reject) => {
let query = new LC.Query('Tutorial');
query.get(id)
.then(resp => {
console.log('get(id):', resp);
resolve(resp);
}).catch(error => {
console.log('get(id):', error);
reject(error);
});
});
}
// 添加新记录,data包含添加的字段及对应的值
create(data) {
return new Promise((resolve, reject) => {
let Tutorial = LC.Object.extend('Tutorial');
let tutorial = new Tutorial(data);
tutorial.save()
.then(resp => {
console.log('create:', resp);
resolve(resp);
})
.catch(error => {
console.log('create:', error);
reject(error)
});
});
}
// 修改记录, data 包含要修改的值
update(id, data) {
return new Promise((resolve, reject) => {
let tutorial = LC.Object.createWithoutData('Tutorial', id);
tutorial.set(data);
tutorial.save()
.then(resp => {
console.log('delete(id):', resp);
resolve(resp)
})
.catch(error => {
console.log('delete(id):', error);
reject(error)
});
});
}
// 删除一条记录
delete(id) {
return new Promise((resolve, reject) => {
let tutorial = LC.Object.createWithoutData('Tutorial', id);
tutorial.destroy()
.then(resp => {
console.log('delete(id):', resp);
resolve(resp)
})
.catch(error => {
console.log('delete(id):', error);
reject(error)
});
});
}
// 批量删除记录,data 为包含批量操作记录的数组
deletaAll(data) {
return new Promise((resolve, reject) => {
// 获取所有待删除记录的id
let ids = data.map(item=>{return item.id});
let query = new LC.Query('Tutorial');
query.containedIn('objectId',ids) // 使用id 把所有要删除的记录打出来
.destroyAll() // 执行批量删除操作
.then(resp => {
console.log('deletaAll(data):', resp);
resolve(resp);
})
.catch(error => {
console.log('deletaAll(data):', error);
reject(error);
});
});
}
}

export default new TutorialDataService();

编辑路由

打开 src/router/index.js 文件,编辑内容如以下代码所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// src/router/index.js
import Vue from 'vue';
import VueRouter from 'vue-router';

Vue.use(VueRouter);

const routes = [
{
path: '/', // 路由
alias: '/tutorials', // 别名
name: 'tutorials',
component: () => import('@/views/TutorialsList.vue'),
},
{
path: '/tutorials/:id',
name: 'tutorial-details',
component: () => import('@/views/Tutorial.vue')
},
{
path: '/add',
name: 'add',
component: () => import('@/views/AddTutorial.vue'),
},
];

const router = new VueRouter({
routes
});

export default router;

添加视图文件

打开src/App.vue 文件,编辑其内容所以下代码所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<template>
<v-app>
<v-app-bar app>
<div class="d-flex align-center mr-2">bezKoder</div>
<v-btn to="/tutorials" text>Tutorials</v-btn>
<v-btn to="/add" text>Add</v-btn>
</v-app-bar>

<v-main>
<router-view />
</v-main>
</v-app>
</template>

<script>
export default {
name: "App",
data: () => ({
//
}),
};
</script>

添加 Vuetify 视图(组件)

分别添加以下文件,以便和路由文件的设置相匹配:

  • src/views/TutorialsList.vue
  • src/views/Tutorial.vue
  • src/views/AddTutorial.vue

新增记录的视图

打开 src/views/AddTutorial.vue 文件,编辑其内容如以下代码所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
<template>
<div class="submit-form mt-3 mx-auto">
<p class="headline">Add Tutorial</p>

<div v-if="!submitted">
<v-form ref="form" lazy-validation>
<v-text-field
v-model="tutorial.title"
:rules="[(v) => !!v || 'Title is required']"
label="Title"
required
></v-text-field>

<v-text-field
v-model="tutorial.description"
:rules="[(v) => !!v || 'Description is required']"
label="Description"
required
></v-text-field>
</v-form>

<v-btn color="primary" class="mt-3" @click="saveTutorial">Submit</v-btn>
</div>

<div v-else>
<v-card class="mx-auto">
<v-card-title> Submitted successfully! </v-card-title>

<v-card-subtitle>
Click the button to add new Tutorial.
</v-card-subtitle>

<v-card-actions>
<v-btn color="success" @click="newTutorial">Add</v-btn>
</v-card-actions>
</v-card>
</div>
</div>
</template>

<script>
import TutorialDataService from "@/api/services/TutorialDataService.js";
export default {
name: "add-tutorial",
data: () => ({
tutorial: {
id: null,
title: "",
description: "",
published: false,
},
submitted: false,
//
}),
methods: {
saveTutorial() {
var data = {
title: this.tutorial.title,
description: this.tutorial.description,
published: false,
};

TutorialDataService.create(data)
.then((response) => {
this.tutorial.id = response.id;
this.submitted = true;
})
.catch((e) => {
console.log(e);
});
},

newTutorial() {
this.submitted = false;
this.tutorial = {};
},
},
};
</script>

<style>
.submit-form {
max-width: 300px;
}
</style>

使用 v-data-table 组件展示所有数据

打开 src/views/TutorialsList.vue 文件,编辑其内容如以下文件所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
<template>
<v-row align="center" class="list px-3 mx-auto">
<v-spacer />
<v-col cols="12" md="4">
<v-text-field
v-model="search"
append-icon="mdi-magnify"
label="Search"
single-line
hide-details
></v-text-field>
</v-col>

<v-col cols="12" sm="12">
<v-card class="mx-auto" tile>
<v-card-title>Tutorials</v-card-title>

<v-data-table
:headers="headers"
:items="tutorials"
:search="search"
v-model="selected"
show-select
disable-pagination
:hide-default-footer="true"
>
<template v-slot:[`item.actions`]="{ item }">
<v-icon small class="mr-2" @click="editTutorial(item.id)"
>mdi-pencil</v-icon
>
<v-icon small @click="deleteTutorial(item.id)">mdi-delete</v-icon>
</template>
</v-data-table>

<v-card-actions>
<v-btn :disabled="selected.length<=0" small color="error" @click="removeAllTutorials">
Remove Selected
</v-btn>
</v-card-actions>
</v-card>
</v-col>
</v-row>
</template>

<script>
import TutorialDataService from "@/api/services/TutorialDataService.js";
export default {
name: "tutorials-list",
data() {
return {
tutorials: [], // 数据表的显示的所有数据
selected: [], //多选框选中的项
search: "", // 用于搜索功能,分别绑定到搜索框和数据表组件
// 数据表的表头
headers: [
{ text: "Title", align: "start", sortable: false, value: "title" },
{ text: "Description", value: "description", sortable: false },
{ text: "Status", value: "status", sortable: false },
{ text: "Actions", value: "actions", sortable: false },
],
};
},
methods: {
// 获取所有数据
retrieveTutorials() {
this.tutorials = []; // 每次要先清空数据
TutorialDataService.getAll()
.then((response) => {
// 遍历获取的数据,并提取需要的字段
response.forEach((item) => {
this.tutorials.push({
id: item.id, // leancloud中的id值直接获取
title: item.get("title"), // 自定义字段要使用 get() 获取值
description: item.get("description"),
// 此处将 published 以 status 进行显示
status: item.get("published") ? "Published" : "Pending",
});
});
})
.catch((e) => {
console.log(e);
});
},
// 刷新数据
refreshList() {
this.retrieveTutorials();
},
// 批量删除选中的记录
removeAllTutorials() {
// 判断是否有已选中的记录
if (this.selected.length>0) {
console.log("selected: ", this.selected);
TutorialDataService.deletaAll(this.selected)
.then((response) => {
console.log(response);
this.refreshList(); // 更新数据
this.selected =[]; // 清空已选中数据
})
.catch((e) => {
console.log(e);
});
}
},
// 搜索标题, 此功能未使用,可以注释或是删除,搜索功能直接由数据表组件提供
searchTitle() {
// this.tutorials=this.tutorials.filter(item=>{
// return !item.title.indexOf(this.title);
// });
},
// 编辑记录
editTutorial(id) {
// 使用命名路由跳转到 Tutorial.vue ,传递参数为记录的id
this.$router.push({ name: "tutorial-details", params: { id: id } });
},
// 删除一条记录
deleteTutorial(id) {
TutorialDataService.delete(id)
.then(() => {
this.refreshList();
})
.catch((e) => {
console.log(e);
});
},

// 格式化显示数据,对标题和描述只显示前 30个字符的内容
getDisplayTutorial(tutorial) {
return {
id: tutorial.id,
title:
tutorial.title.length > 30
? tutorial.title.substr(0, 30) + "..."
: tutorial.title,
description:
tutorial.description.length > 30
? tutorial.description.substr(0, 30) + "..."
: tutorial.description,
status: tutorial.published ? "Published" : "Pending",
};
},
},
mounted() {
this.retrieveTutorials();
},
};
</script>

<style>
.list {
max-width: 750px;
}
</style>


显示详细信息以及修改数据

打开 src/views/Tutorial.vue 文件,编辑其内容如以下代码所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
<template>
<div v-if="currentTutorial" class="edit-form py-3">
<p class="headline">Edit Tutorial</p>

<v-form ref="form" lazy-validation>
<v-text-field
v-model="currentTutorial.title"
:rules="[(v) => !!v || 'Title is required']"
label="Title"
required
></v-text-field>

<v-text-field
v-model="currentTutorial.description"
:rules="[(v) => !!v || 'Description is required']"
label="Description"
required
></v-text-field>

<label><strong>Status:</strong></label>
{{ currentTutorial.published ? "Published" : "Pending" }}

<v-divider class="my-5"></v-divider>

<v-btn
v-if="currentTutorial.published"
@click="updatePublished(false)"
color="primary"
small
class="mr-2"
>
UnPublish
</v-btn>

<v-btn
v-else
@click="updatePublished(true)"
color="primary"
small
class="mr-2"
>
Publish
</v-btn>

<v-btn color="error" small class="mr-2" @click="deleteTutorial">
Delete
</v-btn>

<v-btn color="success" small @click="updateTutorial"> Update </v-btn>
</v-form>

<p class="mt-3">{{ message }}</p>
</div>

<div v-else>
<p>Please click on a Tutorial...</p>
</div>
</template>

<script>
import TutorialDataService from "@/api/services/TutorialDataService.js";

export default {
name: "tutorial",
data() {
return {
currentTutorial: null,
message: "",
};
},
methods: {
getTutorial(id) {
TutorialDataService.get(id)
.then((item) => {
this.currentTutorial = {
id: item.id,
title: item.get("title"),
description: item.get("description"),
published: item.get("published"),
};
console.log(this.currentTutorial);
})
.catch((e) => {
console.log(e);
});
},

updatePublished(status) {
var data = {
id: this.currentTutorial.id,
title: this.currentTutorial.title,
description: this.currentTutorial.description,
published: status,
};

TutorialDataService.update(this.currentTutorial.id, data)
.then((response) => {
this.currentTutorial.published = status;
console.log(response);
})
.catch((e) => {
console.log(e);
});
},

updateTutorial() {
TutorialDataService.update(this.currentTutorial.id, this.currentTutorial)
.then((response) => {
console.log(response);
this.message = "The tutorial was updated successfully!";
})
.catch((e) => {
console.log(e);
});
},

deleteTutorial() {
TutorialDataService.delete(this.currentTutorial.id)
.then((response) => {
console.log(response.data);
this.$router.push({ name: "tutorials" });
})
.catch((e) => {
console.log(e);
});
},
},
mounted() {
this.message = "";
this.getTutorial(this.$route.params.id);
},
};
</script>

<style>
.edit-form {
max-width: 300px;
margin: auto;
}
</style>

运行程序

在项目文件夹打开CMD控制台PowerShell窗口,输入以下命令运行程序:

1
npm run serve

如果运行成功,将看到类似以下的信息:

1
2
3
4
5
DONE  Compiled successfully in 266ms

App running at:
- Local: http://localhost:8080/
- Network: http://192.168.1.80:8080/

打开浏览器,并输入以上网址回车就可以看到运行的结果了。

项目源代码

查看源代码,请浏览以下网址:
https://gitee.com/hujiyi/vuetify-data-table-example

===END===