Vue.js 学习笔记之三:与服务器的数据交互
显而易见的,之前的02_toDoList存在着一个很致命的缺陷。那就是它的数据只存在于浏览器端,一但用户关闭或重新载入页面,他之前加入到程序中的数据就会全部丢失,一切又恢复到程序的初始状态。要想解决这个问题,就需要 Web 应用的前端在适当的时间将获得的输入数据存储到后端服务器上,然后在需要时再从服务器上获取这些数据。这部分笔记将记录如何利用 Vue.js 框架来完成 Web 应用程序的前端与后端之间的交互。这一次,我同样会通过构建一个"留言本"应用来贯穿整个学习过程。
首先需要在code目录下依次执行npm install express body-parser knex和npm install sqlite3@<指定的版本>命令,安装接下来创建 Web 服务所需要的后端组件(需要注意的是,这里安装的sqlite3要根据knex安装后的提示选择对应的版本)。接下来,在code目录下创建一个名为03_Message的目录,并在该目录下执行npm init -y命令,将其初始化成一个 Node.js 项目。在这里,之所以将服务端所需要的组件安装在项目目录的上一级目录中,是因为我接下来还需要在项目目录中安装前端组件,并将其开放给浏览器端访问,所以前后端所需要的组件最好分开存放。
现在,我要基于 Express 框架来创建一个 Web 服务了。具体做法就是在code/03_Message目录下创建一个名为index.js的服务器端脚本文件,并在其中输入如下代码:
const path = require('path');
const express = require('express')
const bodyParser = require('body-parser');
const knex = require('knex');
const port = 8080;
// 创建服务器实例
const app = express();
// 配置 public 目录,将其开放给浏览器端
app.use('/', express.static(path.join(__dirname, 'public')));
// 配置 node_modules 目录,将其开放给浏览器端
app.use('/node_modules', express.static(path.join(__dirname, 'node_modules')));
//配置 body-parser 中间件,以便获取 POST 请求数据。
app.use(bodyParser.urlencoded({ extended : false}));
app.use(bodyParser.json());
// 创建数据库连接对象:
const appDB = knex({
client: 'sqlite3', // 设置要连接的数据类型
connection: { // 设置数据库的链接参数
filename: path.join(__dirname, 'data/database.sqlite')
},
debug: true, // 设置是否开启 debug 模式,true 表示开启
pool: { // 设置数据库连接池的大小,默认为{min: 2, max: 10}
min: 2,
max: 7
},
useNullAsDefault: true
});
appDB.schema.hasTable('notes') // 查看数据库中是否已经存在 notes 表
.then(function(exists) {
if(exists == false) { // 如果 notes 表不存在就创建它
appDB.schema.createTable('notes', function(table) {
// 创建 notes 表:
table.increments('uid').primary();// 将 uid 设置为自动增长的字段,并将其设为主键。
table.string('userName'); // 将 userName 设置为字符串类型的字段。
table.string('noteMessage'); // 将 notes 设置为字符串类型的字段。
});
}
})
.then(function() {
// 请求路由
// 设置网站首页
app.get('/', function(req, res) {
res.redirect('/index.htm');
});
// 响应前端获取数据的 GET 请求
app.get('/data/get', function(req, res) {
appDB('notes').select('*')
.then(function(data) {
console.log(data);
res.status(200).send(data);
}).catch(function() {
res.status(404).send('找不到相关数据');
});
});
// 响应前端删除数据的 POST 请求
app.post('/data/delete', function(req, res) {
appDB('notes').delete()
.where('uid', '=', req.body['uid'])
.catch(function() {
res.status(404).send('删除数据失败');
});
res.send(200);
});
// 响应前端添加数据的 POST 请求
app.post('/data/add', function(req, res) {
console.log('post data');
appDB('notes').insert(
{
userName : req.body['userName'],
noteMessage : req.body['noteMessage']
}
).catch(function() {
res.status(404).send('添加数据失败');
});
res.send(200);
});
// 监听 8080 端口
app.listen(port, function(){
console.log(`访问 http://localhost:${port}/,按 Ctrl+C 终止服务!`);
});
})
.catch(function() {
// 断开数据库连接,并销毁 appDB 对象
appDB.destroy();
});
由于 Vue.js 框架的特点,前端需要后端提供的服务除了获取指定的 HTML 和 JavaScript 文件之外,主要就是对数据库的增删改查操作了,所以在上面这个服务中,除了将public、node_modules目录整体开放给浏览器端访问之外,主要提供了一个基于 GET 请求的数据查询服务,和两个基于 POST 请求的数据添加与删除操作。
接下来,我可以开始前端部分的构建了。首先需要在code/03_Message目录下执行npm install vue axios命令,安装接下来所要用到的前端组件(该命令会自动生成一个node_modules目录,正如上面所说,该目录会被服务端脚本整体开放给浏览器端)。然后,继续在同一目录下创建public目录,并在其中创建一个名为index.htm的文件,其代码如下:
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script defer="defer" src="/node_modules/vue/dist/vue.js"></script>
<script defer="defer" src="/node_modules/axios/dist/axios.js"></script>
<script defer="defer" src="/js/main.js"></script>
<title>留言本</title>
</head>
<body>
<div id="app">
<h1>留言本</h1>
<div id="showNote" v-for="note in notes">
<span>{{ note.userName }} 说:{{ note.noteMessage }} </span>
<input type="button" value="删除" @click="remove(note.uid)">
</div>
<div id="addMessage">
<h2>请留言:</h2>
<label :for="userName">用户名:</label>
<input type="text" v-model="userName">
<br>
<label :for="Message">写留言:</label>
<input type="text" v-model="Message"></input>
<input type="button" value="添加留言" @click="addNew">
</div>
</div>
</body>
</html>
这个页面主要被分为了两个部分,第一部分会根据notes中的数据使用v-for指令迭代显示已被添加到数据库中的留言,并提供了一个删除按钮以便删除指定的留言(使用v-on指令绑定单击事件处理函数)。第二部分则是一个用于添加留言的输入界面,这里使用了v-model指令来获取需要用户输入的userName和Message数据。现在,我需要来创建相应的 Vue 对象实例了,为此,我会在刚才创建的public目录下再创建一个js目录,并在其中创建名为main.js的自定义前端脚本文件,其代码如下:
// 程序名称: Message
// 实现目标:
// 1. 学习 axios 库的使用
// 2. 掌握如何与服务器进行数据交互
const app = new Vue({
el: '#app',
data:{
userName: '',
Message: '',
notes: []
},
created: function() {
that = this;
axios.get('/data/get')
.then(function(res) {
that.notes = res.data;
})
.catch(function(err) {
console.error(err);
});
},
methods:{
addNew: function() {
if(this.userName !== '' && this.Message !== '') {
that = this;
axios.post('/data/add', {
userName: that.userName,
noteMessage: that.Message
}).catch(function(err) {
console.error(err);
});
this.Message = '';
this.userName = '';
axios.get('/data/get')
.then(function(res) {
that.notes = res.data;
})
.catch(function(err) {
console.error(err);
});
}
},
remove: function(id) {
if(uid > 0) {
that = this;
axios.post('/data/delete', {
uid : id
}).catch(function(err) {
console.error(err);
});
axios.get('/data/get')
.then(function(res) {
that.notes = res.data;
})
.catch(function(err) {
console.error(err);
});
}
}
}
});
这个 Vue 实例与我们之前创建的大同小异,主要由以下四个成员组成:
el成员:用于以 CSS 选择器的方式指定 Vue 实例所对应的元素容器,在这里,我指定的是<div id="app">元素。data成员:用于设置页面中绑定的数据,这里设置了以下三个数据变量:notes:这是一个数组变量,用于存放已被添加的留言记录。userName:这是一个字符串变量,用于获取"用户名"数据。Message:这是一个字符串变量,用于获取"留言"数据。
created成员:用于在程序载入时做初始化操作,在这里,我从服务端读取了已被添加的留言记录,并将其加载到notes变量中。methods成员:用于定义页面中绑定的事件处理函数,这里定义了以下两个事件处理函数:addNew:用于添加新的留言记录,并同步更新notes中的数据。remove:用于删除指定的留言记录,并同步更新notes中的数据。
通常情况下,我们在 Vue.js 框架中会选择使用 axios 这样的第三方组件来处理发送请求和接收响应数据的工作,引入该组件的方式与引入 Vue.js 框架的方式是一样的,可以像上面一样先下载到本地,然后使用<script>标签引入,也可以使用 CDN 的方式直接使用<script>标签引入,像这样:
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://unpkg.com/axios/dist/axios.js"></script>
<!-- 或者 -->
<!-- 生产环境版本,优化了文件大小和载入速度 -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
需要注意的是,该引用标签在 HTML 页面中的位置必须要在自定义 JavaScript 脚本文件(即main.js)的引用标签之前。当然,我在上述代码中只展示了axios.get和axios.post这两个最常用方法的基本用法,由于该组件支持返回 Promise 对象,所以我们可以采用then方法调用链来处理响应数据和异常状况。关于 axios 组件更多的使用方法,可以参考相关文档(http://www.axios-js.com/zh-cn/docs/)。
Vue.js 学习笔记之三:与服务器的数据交互的更多相关文章
- Vue.js学习笔记(2)vue-router
vue中vue-router的使用:
- vue.js 学习笔记3——TypeScript
目录 vue.js 学习笔记3--TypeScript 工具 基础类型 数组 元组 枚举 字面量 接口 类类型 类类型要素 函数 函数参数 this对象和类型 重载 迭代器 Symbol.iterat ...
- Vue.js学习笔记:在元素 和 template 中使用 v-if 指令
f 指令 语法比较简单,直接上代码: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" " ...
- Vue.js 学习笔记 第7章 组件详解
本篇目录: 7.1 组件与复用 7.2 使用props传递数据 7.3 组件通讯 7.4 使用slot分发内容 7.5 组件高级用法 7.6 其他 7.7 实战:两个常用组件的开发 组件(Compon ...
- Vue.js——学习笔记(一)
Vue-自学笔记 Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架.与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用.Vue 的核心库只关注视图层,不仅 ...
- Vue.js 学习笔记之二:数据驱动开发
在 Vue.js 框架中,与 HTML 页面元素的交互方式没有像原生 JavaScript 接口那么直接,它是通过先在 HTML 元素标签中嵌入一系列类似于普通标签属性的 Vue 指令属性来绑定数据, ...
- Vue.js 学习笔记之四:Vue 组件基础
到目前为止,这个系列的笔记所展示的都是一些极为简单的单页面 Web 应用程序,并且页面上通常只有几个简单的交互元素.但在实际生产环境中,Web 应用程序的用户界面往往是由多个复杂的页面共同组成的.这时 ...
- Vue.js 学习笔记之五:编译 vue 组件
正如上一篇笔记中所说,直接使用 ES6 标准提供的模块规范来编写 Vue 组件在很多情况下可能并不是最佳实践.主要原因有两个,首先是市面上还有许多并没有对 ES6 标准提供完全支持的 Web 浏览器, ...
- Vue.js——学习笔记
Vue-自学笔记 Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架.与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用.Vue 的核心库只关注视图层,不仅 ...
随机推荐
- python3+pyqt5+opencv3简单使用
python3+pyqt5+opencv3简单使用(转载) 关于python3下搭建pyqt5(pycharm)参考这条链接. 对于pyqt的使用个人比较建议ui设计与逻辑功能分开开发. 下面介绍下简 ...
- Inno Setup Compiler 中文使用教程
一.概要 该文章主要解决,Inno Setup Compiler工具的使用问题. 如有什么建议欢迎提出,本人及时修改.[如有任何疑惑可以加Q群:580749909] 二.步骤 (1)下载地址:http ...
- 深度优先搜索(DFS)解题总结
定义 深度优先搜索算法(Depth-First-Search),是搜索算法的一种.它沿着树的深度遍历树的节点,尽可能深的搜索树的分支. 例如下图,其深度优先遍历顺序为 1->2->4-&g ...
- ORA-01455: converting column overflows integer datatypes.
系统执行抛了一个ORA-01455: converting column overflows integer datatypes.把当时执行的SQL取出来,在plsql developer里面执行是没 ...
- 要不是真的喜欢学技术,谁会来用Python爬小姐姐啊
养成习惯,先赞后看!!!不用于任何商业价值,只是自己娱乐.否则 爬虫爬的好,牢饭吃到饱.这是我们这次爬取的网址:https://www.vmgirls.com/ 很多人学习python,不知道从何学起 ...
- 数字电路基础(三)TTL与非门输入端接电压表的示数
如下图所示,当ui输入低电平,电压表示数为0.3v,当ui输入高电平时,电压表示数为1.4v,分析如下 当ui=0.3 此时VT1导通,电流都从输入端流出,VT1的基极电位被钳位在1.0v(Ub1=0 ...
- Fitness - 05.19
倒计时226天 运动45分钟,共计9组,4.7公里.拉伸10分钟. 每组跑步3分钟(6.5KM/h),走路2分钟(5.5KM/h). 上周的跑步计划中断了,本周重复第三阶段的跑步计划. 一共掉了10斤 ...
- 记一次内存飙升的Windbg
背景 突然间接到运维的报警,我们一个服务,内存找过了6GB的占用.才6GB 也不是很大,因为在处理别的事情,服务dump一下暂时一放,然后半小时之后,接到了运维的Kafka堆积报警.然后切换着重启了一 ...
- 无法从NVIDA官网下载安装CUDA安装包?NVIDA官网怎么了?
最近几天由于不知名的原因,导致很多人无法从官网下载NVIDA的CUDA安装包,下载时,浏览器提示此文件可能危害你的计算机,选择保留下载下来也只是一个42字节的exe文件 双击进行安装又出现以下问题: ...
- JVM学习第一天(虚拟机的前世今生与与Java的内存区域)
其实说JVM的时候有很多人会懵, 也很不理解,我会写Java代码就可以了,我干嘛要学这个,其实不是的,学习JVM是很有必要性的; 为什么要了解JVM 1:写出更好,更健壮的Java程序; 2:提高Ja ...