一、express使用复习
// 1. 导入 express
let express = require('express');
let bodyParser = require('body-parser');
// 2. 创建一个服务
let app = express();
// 3. 使用静态资源服务中间件
app.use(express.static(__dirname));
app.use(bodyParser.json());
// 4. 配置路由
app.get('/api/login/:id', (req, res) => {
console.log(req.params);
console.log(req.path);
// req.headers 请求头信息
// req.url 请求路径 + 问号传参
// req.path 路径
// req.host 主机名
// req.params 动态路由参数
res.send({
code: 0,
data: null,
msg: 'ok'
});
});
app.post('/api/getList', (req, res) => {
console.log(req.body);
res.send({
code: 0,
data: null,
msg: 'ok'
});
});
app.listen(8000, () => console.log(8000));
二、express动态路由
动态路由是什么?
路由中的某一部分是可以变的,这一部分需要用:标识;如果没有:这一部分就是不可以变的
获取动态路由的值
在 express 的请求对象上有一个 params 属性,这个属性保存了动态路由的值;
let express = require('express');
let bodyParser = require('body-parser');
let app = express();
app.use(express.static(__dirname));
app.use(bodyParser.json());
// 动态路由:路由中的某一部分是可以变的,这一部分需要用:标识;如果没有:这一部分就是不可以变的;
app.get('/order/details/:orderId', (req, res) => {
console.log(req.path); // /order/details/123
console.log(req.params); // { orderId: '123' } 动态路由部分可以在req.params中获取,req.params 是一个对象,其中的属性是在声明路由时冒号后面的值;
res.send(req.params);
});
app.listen(8000, (req, res) => console.log(8000));
三、param方法
- app.param() 方法用于拦截所有带有 id 的动态路由,可以访问请求对象 req 和响应对象 res;
let express = require('express');
let bodyParser = require('body-parser');
let app = express();
app.use(express.static(__dirname));
app.use(bodyParser.json());
// app.param 方法用于拦截所有带有id的动态路由,可以访问
app.param('orderId', (req, res, next) => {
console.log(req.params);
if(!/\d+/.test(req.params)) {
res.send('参数错误');
} else {
next(); // 把控制权交给下一个拦截或者真正的路由处理函数响应
}
// 在这个函数中可以访问 req 和 res,可以增加 headers 或者判断参数合法与否,如果不合法可以提前响应;如果校验结束后要执行 next(),
});
app.get('/order/detail/:orderId', (req, res, next) => {
// console.log(req.params);
res.send(req.params)
});
app.listen(8000, () => console.log(8000));
四、中间件 middleware
- 中间件:一个访问请求对象和响应对象的函数
- 一般中间件都是有固定功能或者实现拦截的
let express = require('express');
let bodyParser = require('body-parser');
let app = express();
app.use(express.static(__dirname));
app.use(bodyParser.json());
// app.use() 方法使用中间件,中间件在请求被服务器接收之后,真正被响应之前被调用
app.use(function (req, res, next) {
// 中间件,只要请求就会被挨个调用;
// 如果在当前中间件中没有结束请求,必须执行 next,把控制权交给下一个中间件或者路由响应函数,否则请求一直处于挂起状态;
req.sleep = '睡觉';
next();
});
app.use(function (req, res) {
console.log(req.sleep);
res.send('帅');
});
app.get('/api/test', (req, res) => {
console.log()
});
app.listen(8000, () => console.log('8000'));
五、认识Vue
Vue 是什么?
Vue.js 是一门 MVVM 框架,框架的思路是数据映射视图;是数据驱动的,有别于我们过往的 DOM 操作开发思想;
MVC 和 MVVM
MVC 和 MVVM 都是设计模式,是框架的开发理念;
- MVC: M model 是数据层 V view 视图层 C controller 控制器层,控制器层是连接 model 和视图的;一般是单向数据流,通过 Controller 把数据绑定到 view 中
- MVVM: M model 数据层 V view 视图层 VM view-model 视图模型层 通过视图模型把数据层和视图层练习起来,可以双向数据绑定,可以单向数据绑定
此外,Vue 是响应式的框架;所谓响应式不是 css 的响应式,而是通过修改数据,视图自动发生变化。当视图发生变化时,数据也会随着改变;这就是双向数据绑定;
使用Vue
- HTML代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--Vue 需要一个根元素-->
<div id="app">
<div>
{{1 + 2}}
</div>
<div>
{{1 && 2}}
</div>
<div>
{{0 || 1}}
</div>
<div>
{{true ? 'a' : 'b'}}
</div>
<div>
{{product}}
</div>
<div>
{{user.name}}
{{user.age}}
{{user.title}}
</div>
<!--Vue 的模板语法,moustache(小胡子)语法;支持 js 表达式,不能写语句,只能写表达式,将来在页面中显示最终表达式的结果-->
<!--如果是变量,会从 Vue 的 data 中取到对应的属性值-->
</div>
<script src="js/vue.js"></script>
<script src="js/2-使用vue.js">
</script>
</body>
</html>
- JS
// Vue 是 vue 的构造函数,在执行构造函数时需要传入一个对象;对象的属性都是配置 vue 应用的;
let vm = new Vue({
el: '#app', // 指定 vue 应用挂载的元素
data: {
product: 'Apple Mac Pro',
user: {
name: '马宾',
age: 18,
title: '宇宙集团军总司令'
}
}
});
六、双向数据绑定
什么是双向数据绑定?
双向数据绑定:通过 Vue 模板语法,把 Vue 中 data 里面的数据绑定到页面中;如果我们修改这个数据,页面中绑定这个数据的地方的值都会跟着自动更新;
- HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
我的电话:{{phone}} <br>
<input type="text" v-model="phone">
</div>
<script src="js/vue.js"></script>
<script src="js/3-双向数据绑定.js"></script>
</body>
</html>
- JS
// 使用 Vue 的应用,必须设置一个根元素
let vm = new Vue({
el: '#app',
data: {
phone: '16666666'
}
});
双向数据绑定的原理:
vue 利用的 Object.defineProperty 这个方法遍历 data 中所有的属性,给每个属性增加了一个 setter 和 getter 方法,当数据发生变化的时候,会触发 setter 方法,当获取数据时,会触发 getter 方法;Object.defineProperty 在 IE8 及以下不兼容,所以 vue 只能在 IE9 以上使用;
七、双向数据绑定原理
- HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<input type="text" id="input">
<div id="app"></div>
<script src="js/4-双向数据绑定原理.js"></script>
</body>
</html>
- JS
let obj = {
_name: 1
}
let input = document.getElementById('input');
let app = document.getElementById('app');
// defineProperty 是一个函数,用来定义对象属性的特性;是 Object 的静态方法
Object.defineProperty(obj, 'name', {
get() {
return this._name;
},
set(val) {
this._name = val;
app.innerHTML = this._name;
// vue 使用的是发布订阅模式,vue 会收集页面中所有绑定数据的元素,这些相当于订阅了 data 里面的数据变更的事件,当数据发生变更时,会触发 set 方法,在 set 方法中会把所有的使用这个属性的元素的值更新成最新的值(发布事件);
}
});
// v-model 的原理也是利用了 DOM 事件,当表单元素的值发生变化时,设置对象的属性,然后设置对象的属性的时候,会触发 set 方法,在 set 方法中,会去修改所有依赖这些值的地方
input.oninput = function () {
obj.name = this.value
};
八、向 Vue 的 data 中新增属性
- HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
{{user.school}} <br>
{{user.age}}
</div>
<script src="js/vue.js"></script>
<script src="js/5-向vue中新增属性.js"></script>
</body>
</html>
- JS
let vm = new Vue({
el: '#app',
data: {
user: {
school: 'zf'
}
}
});
console.log(vm); // vm 是 Vue 的实例,会把 new Vue 配置对象 data 中的数据代理到 vm 自身上;并且在 Vue 实例初始化时,vm 中的属性都是响应式的(都会映射到视图中,如果修改这些属性,视图中的值也会跟着改变);
// 修改这些属性的方式:
// 1. 修改 vm 属性上的值
// vm.user.school = '珠峰';
// 2. 使用 $set()
// vm.$set(vm.user, 'school', 'ZF');
// 使用 $set 还可以向 data 对象中动态增加属性
vm.$set(vm.user, 'age', 19);
九、vue 中的常用指令
指令是什么?
在 Vue 中,以 v- 开头的行内属性;Vue 赋予了这些属性一些特殊功能;
常用的指令:
- v-model 把表单元素的 value 和 data 中的某个属性绑定在一起
- v-text 把数据绑定到 DOM 元素中,且具有响应式,会把之前的覆盖掉,v-text 不识别标签
- v-html 可以识别标签
- v-if 当属性值是 true,则显示当前元素,如果为 false 当前元素不显示,但是会显示 v-else 中的内容
- v-show 当属性值是 true,显示元素,为 false 隐藏元素;
- v-if 是控制的 DOM 元素,如果为 false 页面中没有这个元素;而 v-show 是设置的元素的 display
- v-bind: 用于绑定动态属性,并且可以简写成一个 : ,v-bind 后,这个属性就可以使用 data 中该属性的值
示例
- HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<input type="text" v-model="flag">
<div v-text="title"></div>
<div v-html="title"></div>
<div v-if="tt">v-if</div>
<div v-else>v-else</div>
<div v-show="hh">v-show</div>
<img v-bind:src="img" alt="">
</div>
<script src="js/vue.js"></script>
<script src="js/6-vue中的常用指令.js"></script>
</body>
</html>
- JS
let vm = new Vue({
el: '#app',
data: {
flag: 'abc',
title: `<h2>这是一个h2</h2>`,
tt: false,
hh: false,
yy: false,
img: 'clock.png',
names: ['张三', '李四']
}
});
十、v-for 指令
v-for 的作用:
v-for 用于列表渲染,根据给定的值生成多个相同元素;
用法:
- v-for Array 数组有多少项就要生成多少个 li
<li v-for="(a, index) in arr">{{a.name}} {{a.age}}</li>
- v-for Object 对象有多少个 key 就生成多少 li
<li v-for="(a, b) in obj">{{a}} {{b}}</li>
- v-for num 生成 num 个 li
<li v-for="(a, b) in num">{{a}} {{b}}</li>
- v-for str 生成 str.length 个 li
<li v-for="(a, b) in str">{{a}} {{b}}</li>
示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<ul>
v-for Array 数组有多少项就要生成多少个 li
<li v-for="(a, index) in arr">{{a.name}} {{a.age}} </li>
v-for Object 对象有多少个 key 就生成多少 li
<li v-for="(a, b) in obj">{{a}} {{b}}</li>
v-for num 生成 num 个 li
<li v-for="(a, b) in num">{{a}} {{b}}</li>
v-for str 生成 str.length 个 li
<li v-for="(a, b) in str">{{a}} {{b}}</li>
</ul>
</div>
<script src="js/vue.js"></script>
<script>
let vm = new Vue({
el: '#app',
data: {
arr: [
{name: '张三', age: 15},
{name: '李四', age: 18}
],
num: 5,
str: 'zfpex',
obj: {
goods: 'iPhone',
manufacture: '富土康',
price: '$1000'
}
}
})
// v-for 用于列表渲染
</script>
</body>
</html>