Vue全家桶系列一: Vue基础

1,209 阅读21分钟

阅读前先知:↓↓↓

我已将源代码上传到了我的码云仓库中,感兴趣的可以去下载源码,

点我 - 跳转到源码仓库地址, 下载源代码配合文章学习!

边看博文,边看源码,根据博客和源代码自己动手Demo敲一遍,这种最简单的方式让你快速掌握Vue基础,加油吧! 源码中的目录层级和文件名称,都和文章目录中的一致,一目了然,根据文章目录找到对应的源码文件。 源代码我也相应的进行了优化,相对于文章中的章节,源码优化后阅读和理解起来更容易些。

Vue - 官方文档

1:Vue基础 - 指令

1.1: 初识Vue

1.1: Vue之HelloWorld

// --------------------- Vue之HelloWorld ------------------
#app 数据渲染区域, el:#app指定元素挂载, data:{数据名称: 数据值}要挂载的内容区域

点我看源码 - 运行代码:查看效果!

1.2: 模板语法概述

// --------------------- 模板语法概述 ------------------
将data中的数据渲染到vue模板中, [{each 数据对象 as value}} {{value}}

1.3: 指令概念与v-cloak指令用法

// --------------------- 指令概念与v-cloak指令用法 ------------------
解决了文字闪动问题
<div v-clock>{{mag}}</div>

1.3.1: 数据填充相关3个指令的用法

// --------------------- 数据填充相关3个指令的用法 ------------------
数据填充相关3个指令的用法-v-text/v-html/v-pre原始信息

1.4: 数据响应式概念与v-once用法

// --------------------- 数据响应式概念与v-once用法 ------------------
数据响应式概念与v-once用法-数据渲染到页面后,数据不可二次修改

1.5: 双向数据绑定与v-model指令用法

// --------------------- 双向数据绑定与v-model指令用法 ------------------
-双向数据绑定与v-model指令用法-一般使用在输入框
输入框中的值发生改变,v-model能监听到,且修改数据v-model会实时更新数据

1.6: MVVM设计思想分析

// --------------------- MVVM设计思想分析 ------------------
MVVM设计思想分析-model+view+view-model
model要渲染的数据+view要渲染到那个元素中+view-model(dom事件监听, data数据绑定)

1.7: 事件绑定基本用法

// --------------------- 事件绑定基本用法 ------------------
事件绑定基本用法-v-on:click / @click

1.8: 事件函数参数传递方式

// --------------------- Vue之HelloWorld ------------------
事件函数参数传递方式-函数名(要传递的参数, 触发的事件对象event)

1.9: 事件修饰符的用法

// --------------------- Vue之HelloWorld ------------------
v-on:click.stop阻止冒泡, 
v-on:click.prevent阻止默认行为

1.10: 按键修饰符的用法

// --------------------- 事件修饰符的用法 ------------------
v-on:keyuo.有意义的名称--->对应有意义的处理函数
(v-on:keyup.delete-->清空输入框值的处理函数)。
v-on:keyup.enter按下回车键--->handelSubmit:function(){conole.log(this.uname)}就打印表单中的数据内容

1.10.1: 自定义按键修饰符

// --------------------- 自定义按键修饰符 ------------------
v-on:keyup.自定义按键名称=事件处理函数
(v-on:keyup.aaa=handle处理函数)只要按下了该按键,就会触发该按键对应的处理函数。 
定义按键键码值:Vue.config.keyCode.按键的名称=键码值(Vue.config.keyCode.aaa=65

1.10.2: 阶段小结:简单计算器案例

// ------------------- 简单计算器 ----------------
其实就是点击计算触发了事件处理函数,函数中键data中的属性值,通过parseInt相加的和赋值给data中的result,将result展示在计算结果中 v-text=result

1.10.3: 属性绑定基本用法

// ---------------- 属性绑定基本用法 ----------------
属性绑定基本用法-v-bind:href / :href

1.10.4: 指令v-model底层原理分析

// ---------------- 指令v-model底层原理分析 ----------------
一个v-model相当于2个事件:
 1 v-bind:value=要绑定的数据, 
2 v-on:input="$event.target.value"

1.10.5: 样式绑定之class绑定对象用法

// ---------------- 样式绑定之class绑定对象用法 ----------------
样式绑定之class绑定对象用法-class{ }对象方式
class{ }对象方式:
1定义类名完成样式布局,
2使用样式v-bind:class(类名: data中属性,值为true就会添加该样式),
v-bind:class={类名1, data中的属性1,类名2, data中的属性2}

1.10.6: 样式绑定之class绑定数组用法

// ---------------- 样式绑定之class绑定数组用法 ----------------
样式绑定之class绑定数组用法-class [ ] 数组方式
1:定义类名, 
2:将类名放在data属性中,当做值, 
3:将data中的值放在数组中渲染给元素 v-bind:class"[data属性名1,data属性名2]"

1.10.7: 样式绑定之class绑定3个细节用法

// ---------------- 样式绑定之class绑定3个细节用法 ----------------
1:可以数组中,嵌套{ }对象, 
2:可以在data中定义一个属性:接收一个对象{ }, 对象中有多个类名,且值为true3:元素本身已有class类样式,还可以v-bind:class绑定data中的属性值。【具体看分析图】

1.10.8: 样式绑定之style绑定用法

// ---------------- 样式绑定之style绑定用法 ----------------
样式绑定之style绑定用法-style { }对象形式, style [ ]数组形式
1style { }对象形式: v-bind:style{color颜色名: data中的属性名}该属性名是data中直接的属性名,
2 style [ ]数组形式:v-bind:style="[data属性名1,data属性名2]",该属性名是属性名: { }对象中有多个属性

1.10.9: 分支结构用法

// ---------------- 分支结构用法 ----------------
分支结构用法-v-if/v-else/v-else-if, v-show
v-if判断条件一,v-else判断条件二,v-else-if判断条件三,v-if判断条件四 ,因为判断的是data中的某个属性,如果该属性的值满足判断条件,就会执行该判断条件中的语句。 v-show如果data中的属性的值是true,该元素就会显示,反之则隐藏

1.20: 循环结构遍历数组与key的作用分析

// ---------------- 循环结构遍历数组与key的作用分析 ----------------
循环结构遍历数组与key的作用分析-循环结遍历数组v-for='每一项 in 要遍历的数据'
1:在data中定义一个属性,对应的是数组,数组中有单个的值,
也有多个{ }对象,遍历方式:v-for="(item, index) in list :key="item.id"",item表示每一项,
index就是对象中的id值

1.20.1: 循环结构遍历对象

// ---------------- 循环结构遍历对象 ----------------
循环结构遍历对象-v-for(v, k, i)
1:在data中定义一个属性,对应的是对象中有多个属性。
2:v-if结合遍历使用:v-if v===12  v-for (属性值v, 属性名k,索引 i )in 遍历的对象

阶段小结: Tab栏切换案例

// ------------------------------- 流程分析 -------------------------------------
1:需求分析与UI概览
2:实现模板布局
3:切换样式处理
4:事件处理

1:遍历展示真实数据
2:数据默认隐藏,根据currentIndex默认显示第一张和第一个tab高亮显示
3:绑定点击事件,点击时让currentIndex=index,点那个哪个就高亮

2:自定义指令、计算、侦听、过滤器、生命周期·

2.1:常用特性概述与表单效果概览

2.2:表单基本操作

// ---------------- 表单基本操作 ------------------
表单元素被选中的规则:
1:通过v-model绑定data中的属性,该属性中的值就是表单对象中要显示的内容。 
2:data中属性可以是单个值,多个值则放在数组中,每一项用' '引号包裹,逗号隔开。 
3:多选框规律:因为v-model绑定了data中的属性,该元素中的value=1值,对应的就是data属性数组中的值,有几个多选框就会显示几个。

2.3:表单域修饰符用法

// ---------------- 表单域修饰符用法 ------------------
表单域修饰符用法-3种常见修饰
1:v-mode.number:转换为number类型,方便运算。  
2:v-model.trim能去除前后空格,中间去不了。 
3:v-model.lazy lazy将事件切换为change类型事件,经测试输入框失去焦点才触发该修饰符

2.4:自定义指令基本用法

// ---------------- 自定义指令基本用法 ------------------
1:在元素中使用该自定义指令,
2: 全局定义自定义指令:Vue.directive('focus')全局声明focus自定义指令, inserted:function(el){el.focus}函数中让该元素自动获取焦点

2.5:自定义指令-带参数

// ---------------- 自定义指令-带参数 ------------------
1:在元素中使用该自定义指令,
 2: 全局定义自定义指令:Vue.directive('focus')全局声明focus自定义指令, 
 inserted:function(el, 参数1)el.style.backargroundColor=参数1.value.color,
能通过它拿到输入框中msg的对应属性名为color的值,
相当于把blue直接赋值给了样式

2.6:自定义局部指令用法

// ---------------- 自定义局部指令用法 ------------------
局部指令只能在该组件中使用,定义方式写在vue实例中,按顺序一般写在methods后面,
directive事件对象中该color属性,通过bind指定了事件处理函数,函数中拿到输入框的值,
将该属性的值赋值给样式,完成样式修改。

2.7:计算属性基本用法

// ---------------- 计算属性基本用法 ------------------
计算属性基本用法-computed
计算属性嫩格式逻辑复杂的函数,用它能内容更加简洁,compuetd计算属性名,对应{ }对象,对象中的属性名对应了处理函数function, 
该函数的处理结果能返回给计算属性

2.8:计算属性与方法的区别

// ---------------- 计算属性与方法的区别 ------------------
计算属性:如果不发生改变,就会从缓存中拿结果,效率高,性能好。 
方法,每次刷新页面都会触发该方法,使用性能开销要大。

2.9:侦听器基本用法

// ---------------- 侦听器基本用法 ------------------
侦听器基本用法-watch
使用场景一般用于异步或者开销较大的操作,比如通过ajax接口拿数据,和settimeout异步任务

侦听器案例

// ---------------- 侦听器案例 ------------------
该案例核心方法:1:在methods中定义异步函数,在侦听器中调用该方法,因为侦听器能实时拿到最新的数据, 
但是侦听器中的属性名必须和data中的属性名一致,通过w-model.lazy实时接收到用户输入的值,去做出验证。
【简单点说,就是methods中封装的异步任务,用watch中执行了】

2.9.1:过滤器基本用法

// ---------------- 过滤器基本用法 ------------------
1 全局过滤器 :1 使用 :{{data中的属性名 | 过滤器名称 | 过滤器名称}}Vue.filter('过滤器名称',处理函数)。

 2:局部过滤器,一般写在data后面,filter: { 过滤器名称:事件处理函数}。 注意多个过滤器 | 竖线隔开就可以了。

2.9.2:带参数的过滤器案例

// ---------------- 带参数的过滤器案例 ------------------
过滤器中的(参数1:就是data中的属性名, 参数2:调用过滤器传递的参数),
实际应用场景,就是根据第二参数,自定义格式化日期。

2.9.3:实例的生命周期

// ---------------- 实例的生命周期 ------------------
实例的生命周期-分为3个大阶段
阶段一渲染:
阶段二数据改动,更新数据:
阶段三:销毁vue实例会触发, 该阶段中,我们主要记住mounted函数,以为页面数据已经渲染完成,我们之后会常用它调用ajax接口去渲染页面数据。

2.9.4:Vue生命周期中文图解 - 自己画的,仅供参考学习!

阶段小结实践:图书管理案例

图书管理功能概述

// --------------------- 图书管理功能概述 ----------------------
图书的增删改查

Vue数组处理相关概念

// --------------------- Vue数组处理相关概念 ----------------------
7大变更方法,【push尾部添加 pop删除 shift头部删除 unshift头部添加,splice切割, sort排序, reverse反转】会直接改变数据,且实施更新,立竿见影。
 
3大替换方法,需要重新接收返回值,页面数据才能立竿见影,【filter过滤, concat拼合, slice切割】

Vue动态处理响应式数据

// --------------------- Vue动态处理响应式数据 ----------------------
vm.$set(参数1:vue中的属性,可以是数组或者对象, 参数2:可以是序号也可以是属性名, 参数3:需要替换的内容),完成数据修改。

如果是对象:(参数1:修改的对象, 参数2, 属性名, 属性值),

如果是数组(参数1:修改的数组, 参数二,数组的第几项,索引,参数3:属性值)

图书列表展示

// --------------------- 图书列表展示 ----------------------
v-for=“item in books”遍历这个对象  :key="item.id"绑定id,提高性能。
将遍历的数据中填充到生成对应的单元格中。去展示数据, 最有一行是手动追加的,
没参加一行数据,都会自动添加这个删除,
v-on:click.prevent会阻止a标签的默认跳转行为。

添加图书

// --------------------- 添加图书 ----------------------
1:在data中添加要的数据,id+name,值默认是空, 
2:输入框v-model="id"双向数据绑定,
点击提出触发handler事件函数,创建空对象book,将输入框中的值赋值给这个空对象中的属性接收,
再将这一项psuh到books数组中。最后清空输入框的值,完成添加功能

修改图书

// --------------------- 修改图书 ----------------------
因为共用了一个提交按钮,就只能通过id输入框的禁用区分修改和添加功能, 
点击修改将id输入框禁用,handle添加中判断,因为提交已经是灰色了,表示为修改,对比id如果一致,
就把这个对象中的name给修改,return true修改完成退出some,
将id输入框禁用状态恢复正常,并清空输入框中的值,妙的就是点击修改,
就会把内容填充到表单中,填充完成,点击因为falg已经是false,
就会执行添加功能,完成修改功能

删除图书

// --------------------- 删除图书 ----------------------
方式一:根据findIndex找出那个id,赋值给index,在调用splice根据index将这条删除。 
方式二:直接用filter过滤出不符合规则的id留下,符合规则的id就排除掉, 巧妙的将点击的id给删除了

常用特性应用场景

// --------------------- 常用特性应用场景 ----------------------
1:filter过滤器,格式化日期时间  
2Vue.directive让id输入框自动获得焦点, 
3: computed计算属性,计算页面books中有几个对象,就是图书的数量, 
4: watch侦听:会返回输入框的值和数据中的name一致,就返回给flag表示书名以存在,存在就让提交按钮变成灰色,反之就是正常按钮。 
5: mounted页面渲染晚餐,将数据剪切到这里赋值给data,在把data赋值给this.books,完成data中空books的填充。 页面数据渲染依旧正常。

3: Vue组件

3.1:组件化开发概述

3.2:组件基本使用

// ------------------ 组件基本使用 -------------------
组件基本使用-Vue.component
全局组件通过Vue.component创建,data必须是一个函数,数据必须通过return给返回来,
template中渲染组件真实的元素标签,以及事件绑定等操作,自己也有单独的handler函数,
子组件的挂载方式就是,在app容器中挂载就能渲染到页面上了

3.3:组件注册注意事项-上

// ------------------ 组件注册注意事项-上 -------------------
1:data不是说含糊,且必须return回来, 
2:template中必须用有一个根元素,不能同时存在几个根元素,会报错, 
3:组件模板中使用模板语法,这样就能换行有格式的写代码

3.4:组件注册注意事项-下

// ------------------ 组件注册注意事项-下 -------------------
1: 全局组件用驼峰命名法的组件,在app中必须是短横线的方式,
但是驼峰命名法,能把这个组件放在其他曲全局组件中的template中,
这样不受影响,可以继续使用驼峰命名法,但在app中强制使用短横线命名方式

3.5:局部组件注册方式

点我看源码 - 运行代码:查看效果!

// ------------------ 局部组件注册方式 -------------------
局部组件使用var关键字声明的,它也有自己的data函数,
和template模板渲染,但是他必须放在vm父实例对象中component这个组件中去注册配置好,才能挂载到app中去显示。
因为是局部组件,只能在父组件中使用,其他全局组件使用局部组件会报错。

3.6:Vue调试工具安装与使用

// ------------------ Vue调试工具安装与使用 -------------------
调试工具能清晰看到组件的嵌套结构,和数据分析以及修改,所见即所得

3.7:父组件向子组件传值-基本用法

点我看源码 - 运行代码:查看效果!

// ------------------ 父组件向子组件传值-基本用法 -------------------
子组件通过props定义好自定义属性,通过它就能接收父组件data中的数据了,

3.8:父组件向子组件传值-props属性命名规则

点我看源码 - 运行代码:查看效果!

// ------------------ 父组件向子组件传值-props属性命名规则 -------------------
props子组件属性绑定命名规则,如果子组件是驼峰命名法,
在template中也能使用驼峰命名法去渲染或挂载该兄弟组件,

但是如果想要在app中挂载渲染,必须是短横线的方式去挂载该属性,和组件名称命名的要求是一致的

3.9:父组件向子组件传值-props属性值类型

点我看源码 - 运行代码:查看效果!

// ------------------ 父组件向子组件传值-props属性值类型 -------------------
props属性类型能接收字符串类型,能接收number类型,能接收布尔类型,能接收数组类型,也能接收对象类型,
唯独2种需要注意,所有属性名都需要被' '引号包裹, 
数值和布尔类型,需要前面加上: 冒号属性绑定,否则都是字符串类型。

3.9.1:子组件向父组件传值-基本用法

点我看源码 - 运行代码:查看效果!

// ------------------ 子组件向父组件传值-基本用法 -------------------
子向父传值,其实就是子组件修改了父组件中的数据, 是通过子组件的$emit绑定一个自定义事件名称,
这个自定义事件名称将会在子组件挂载的时候,会去调用父组件中的事件处理函数,
从而实现了子组件去修改父组件中的内容

3.9.2:子组件向父组件传值-携带参数

点我看源码 - 运行代码:查看效果!

// ------------------ 子组件向父组件传值-携带参数 -------------------
子组件如果想要传递参数,其向父组件传值是一样的,
就是多了第二个参数而已,参数1是自定义事件名称, 参数2就是实参,
该实参能在子组件触发父组件的时候,调用父组件的事件处理函数,
函数的实参就是刚才传递的参数二,这样就实现了子向父传值,携带参数

3.9.3:兄弟组件之间数据交互

点我看源码 - 运行代码:查看效果!

// ------------------ 兄弟组件之间数据交互 -------------------
在一个页面中有2个vue.component全局子组件,能通过新建一个通信中心,实现数据共享,
通信中心就是新new Vue一个对象作为事件处理中心,子组件就能在自己的事件处理函数中,
通过hub.$emit去触发兄弟之间的处理函数,就实现了点击自己触发兄弟是事件处理效果了,
如果想解绑,就必须在父组件的处理函数中,使用hub.$off(子组件的事件处理函数)
就能实现函数销毁,完成解绑功能

3.9.4:组件插槽基本用法

// ------------------ 组件插槽基本用法 -------------------
组件中有一个slot叫插槽,就是一个占位符,如果在渲染子组件的时候,
元素中有数据,就会渲染元素中的数据,如果没有数据,就会渲染插槽中的默认值

3.9.5:具名插槽用法

// ------------------ 具名插槽用法 -------------------
也叫有名字的插槽,如果在子组件挂载的时候,slot声明了name就会使用子组件中同名的插槽去渲染该元素,
如果没有就会渲染到默认的无名插槽中

3.9.6:作用域插槽用法

// ------------------ 作用域插槽用法 -------------------
也可以理解为同数据二次加工的插槽, 因为子组件通过props绑定了自定义属性名,
而自己的template也遍历了该父组件中的数据,此时想要对数据二次包装,
就得在子组件挂载中通过:自定义属性名再次接收父组件中的数据,使用slot-scope去一个别名,
因为:info已经在第一次遍历的时候接收了每一项,所以现在就能通过对象名.每一项的.属性名,
进行数据的二次加工,可以通过v-if控制元素的高亮。

阶段小结实践:购物车案例

功能概述

// ------------------ 功能概述 ------------------
功能分析:商品的加减,输入框中输入数量,总价格会发生改变。

实现组件化布局

// ------------------ 实现组件化布局 ------------------
页面分为上中下结构,所以就用了3个局部组件,一个全局my-cart父组件,
将内容按照上中下抽离后,在全局父组件中通过components配置好,
并挂载在全局父组件中的template中去渲染,而全局父组件挂载到app根组件中

实现标题和结算组件功能

// ------------------ 实现标题和结算组件功能 ------------------
1:显示xx用户,因为父组件data中有一个uname属性,子组件必须同props=['uname'],
将自动你故意属性挂载在组件渲染的时候,把父组件的:uname=uname,
给接收过来,在子组件中template中渲染该用户
2:统计总价格:子组件通过porps在子组件挂载渲染中通过:list=lsit把父组件中的列表数据,
传递给了子组件,子组件通过computed计算属性能实时拿到数据中的更新,封装了一个total函数,
函数中用list.forEach遍历每一项,每一项中的单价*数量+=t,
然后将t的总和返回给total函数拿去渲染。

实现列表组件删除商品功能

// ------------------ 实现列表组件删除商品功能 ------------------
1:触发自己的点击事件,把这个id携带, 自己的处理函数中通过this.$emit传递给红娘,
红娘携带id触发了父组件的删除事件,父组件接收到$event事件对象,
通过list.findIndex根据id找到这一条返回给index,
调用list.splice根据index删除这一条数据

实现列表组件更新商品功能-上

// ------------------ 实现列表组件更新商品功能-上 ------------------
输入框数量发生改变总价格随着改变。
1:渲染输入框中的数量:value=item.num,因为是input,所以动态绑定的是:value值, 
2:@blur输入失去焦点时触发自己的事件函数,把id和事件对象通过this.$emit参数2是一个对象, 
对象中有id属性和num属性。通过红娘在自己组件渲染的位置,触发父组件的事件函数,
父函数通过$event能拿到参数2,在父事件处理函数中通list.some找到这个id把输入框中的num赋值给item.numreturn true跳出代码的执行,
完成了输入框中的val影响数据中的num,
computed总价格就发生了更新

实现列表组件更新商品功能-下

// ------------------ 实现列表组件更新商品功能-下 ------------------
点击+-实现输入框中的值和总价格发生改变:
1:给a标签绑定点击事件,.prevent阻止默认跳转行为,触发自己的事件函数, 
因为+-和输入框在一行,且都是操作商品的数量,所以就共用了一个chang-num函数,
在参数1中的type类型区分是什么操作,他们3个都是通过一个红娘去触发事件函数,
事件函数的$event能拿到参数1中的数据, 在事件函数中通过if判断vak.tyoe的类型做对应的处理,
通过some根据id找到该条数据,将输入框中的值赋值给item.num
这样data中的数据发生了改变,computed总价格也会发生改变

4: Promise

4.1: 前后端交互概述与URL地址格式

// -------------------- 前后端交互概述与URL地址格式 ----------------------
1:传统url地址是: 协议://IP地址:端口/路径/?查询参数/#锚点。 
2Restful形式的URL: GET请求,POST添加,PUT修改,DELETE修改

4.2: 异步编程问题与Promise概述-fixed

// -------------------- 异步编程问题与Promise概述-fixed ----------------------
普通$.ajax需要发起多个请求,在回调函数中打印多个请求返回的结果, 代码太多太重复, 且顺序会乱。 
如果通过嵌套会形成回调地狱,但是代码的打印顺序是正确的。

4.3: Promise基本用法

// -------------------- Promise基本用法 ----------------------
promise对象能解决回调问题,resolve返回正确的结果,

reject返回错误的结果,但是度需要通过.then回调函数中打印的, 
第一个回调函数是正确的结果,第二个回调函数返回的是错误的结果

4.4: Promise发送Ajax请求并处理回调地狱问题

// -------------------- Promise发送Ajax请求并处理回调地狱问题 ----------------------
封装ajax请求函数,请求函数中创建promise函数,
promise函数中嵌套了ajax函数,将错误信息通过resolve打印, 
正确的信息通过reject打印。
调用queryData函数,测试能成功的打印一个返回的结果,
如果想要同时调用多个请求函数,打印多个结果,
就可在起一个请求中通过return去调用第二个请求函数, 
这样就可重复调用多个处理函数,一次性拿到多个处理结果。

4.5: Promise的then方法参数中的函数的返回值

// -------------------- Promise的then方法参数中的函数的返回值 ----------------------
1:一个请求函数中,二次创建promise对象,它会带调用它自己下面的那一个then再把结果输出来。 
如果它返回的不是promsie对象,返回的是一个普通的字符串,也会在它的下一个.then中拿出结果。
这样一对比发现返回promise和字符串都差不多,都是触发自己的下一个.then中输出返回的结果

4.6: Promise常用API-实例方法

// -------------------- 前后端交互概述与URL地址格式 ----------------------
内置方法:如果同时使用2个.then,那么第一个then中返回的是正确的结果,
第二个then中返回的是错误的结果。
如果分开写,
.then返回的是正确的结果,.catch拿到的是错误的信息,
.finally无论成功语法,都会触发它。

4.7: Promise常用API-对象方法

// -------------------- Promise常用API-对象方法 ----------------------
Promise.all只能拿到第一个结果, 
Promise.race能同时执行多个函数的调用,一次性拿到多个处理结果,

5: 数据请求:Fetch API

5.1: FetchAPI概述与基本使用

//----------------- FetchAPI概述与基本使用 ----------------
1:在index.js中定义接口,app.get('/fdata'), 
2:在页面中通过fatch(请求地址/接口地址)访问服务器, 
通过return data.text()将数据返回,

5.2: GET、DELETE、POST、PUT

//----------------- GET、DELETE、POST、PUT ----------------
1:get方式:1.1 传统方式:页面中请求地址后面?id=123,这是传统的请求方式,
也是在本体中data.text把数据返回给打印, 
1.2:resful风格:请求地址后面直接/123携带id,其他都是一致的。
但是服务器中不一样app.get('/books/:id')他能动态接收id

2delete 删除:1:页面请求:直接在请求地址后面携带ID,
但是必须声明method:delete方式为删除,其他是一致的。
2:服务器接口:app.delete(‘/books/:id’,接收到id

3:post方式:1:传统方式:普通的请求地址,
method:post请求方式,body:uname=lisi&pwd=123456,
请求体携带请求参数, headers:{Content-Type:'application/x-www-form-urlencoded'}请求头信息,其他一致。

4:put方式:1:页面请求:请求地址后面携带id,method:put请求方式为put,
body:JSON.stringify({uname:'xx', pwd:'xx'}), 
headers:{Content-Type:'application/x-www-form-urlencoded'}
请求头信息,其他一致.

resful风格:普通的请求地址,method请求方式,
body:JSON.stringify({uname:'xx', pwd:'xx'})。
需要通过转换成json字符串。headers:{Content-Type:application./json}json类型的请求头,
其他一致
服务器接口:app.put(‘/books/:id’,),其他是普通的

params和req.body的区别:
req.params是请求地址后面携带的参数,
【比如req.params.id就是请求地址后面/books/123的这个123id地址】
req.body 是请求体body中的信息:
【比如req.body.uname,就是请求体body请求体对象中的属性, body: JSON.stringify({uname:''xx', pwd:'xx'})】

总结
resful和传统的服务器区别:
区别就是传统就是普通的请求地址,后面不携带任何参数, 
在请求页面中的请求地址后面直接携带,或者在请求body中携带。 
resful接口的后面:/id可以接受id,在请求页面中通过body传递,
必读设置请求头。区别就是接口多了:/id接收id,

resful调用接口和传统调用的区别:页面请求中body不一样而已,
普通的是一行写完,body:'uanme=lis&pwd=123', 
而resful是body中通过body:JSON.stringify以键值对形式传递数据的uname:'zs'。

5.3: FetchAPI响应数据格式

//----------------- FetchAPI响应数据格式 ----------------
在请求页面中通过data.json能把json字符串转换为对象类型,
类似于JSON.parse方法,如果不转换表面上看似一样的,但是json()转换出来的是对象类型,
能通过对象.属性获得值。而不转换是string类型,值会是undefined

数据请求:axios

axios概述与基本用法

// ------------------------ axios概述与基本用法 ---------------------
通过axios.get(请求地址/接口地址).then就能拿到ret接口返回的数据, 

可以简化成ret.data就是要拿到的接口具体的数据:详细代码实例: 

axios.get('http://localhost:3000/adata').then(function(ret) { console.log(ret.data) }),接口app.get('/adata', (req, res) => {res.send('xx')})

axios的GET和DELETE请求传参

//---------------------- axios的GET和DELETE请求传参 -----------------------
页面请求方式:
1:传统get在请求地址后面携带上/axios?id=123携带上请求的ID2:redful的请求/axios/123, 
3: params方式携带参数axios.get('xxx/axios', params: { id: 11 }).then function(ret) {console.log(ret)}。三者的区别及㐊传递参数的方式不同, 推荐还是方式二。
服务器处理方式: 

1:传统get方式:app.get('/axios', (req, res)) 
2: resful风格:app.get('/axios/:id', (req, res))两者的区别就是后面的id

delete方式: 
1:页面请求:axios.delete('请求地址/接口地址', {params: {id: 111}}).then(function(ret)console.log(ret.data)), 
就是调用请求地址,params携带请求参数ID,在.then中打印出来。 

2:服务器请求处理:app.delete('/axios', (req, res) => {})是普通的请求处理,只是delete请求方式不同而已。

axios的POST和PUT请求传参

//---------------------- axios的POST和PUT请求传参 -----------------------
1:页面请求:
1:普通post: axios.post('请求地址/路由地址', {uanme: lis,请求的参数}).then(function())拿到服务器响应的数据, 

方式2: var params = new URLSearchParams(); params.append('uname', 'zhangsan') 通过创建查询参数, 

往这个查询对象中添加具体的属性,通过axios.post('请求地址/路由地址/, params).then(function(ret)),

发起请求,将params对象携带,在then中拿到结果。
2:服务器请求处理:app.post('/axios')普通的接口处理, 
只是post请求方式不一致而已。
pust请求: 

1:页面请求: axios.put(请求地址/路由地址/id), {uname: 'lisi'}).then(function(ret) {}, 
具体解释:就是普通的请求地址携带了路由和id,参数2就是携带的参数, 

2: 服务器处理: app.put('/axios/:id')路由地址后面携带了id

axios响应结果与全局配置

//---------------------- axios响应结果与全局配置 -----------------------
1:页面请求:1:配置基准URL请求地址:axios.defaults.baseURL='http://127.0.0.1:3000', 

2: 设置请求头: axios.defaults.headers['mytoken']=hello,这样以后页面请求只要给请求地址即可, 
而token也被设置好了,以后的请求之中都会带有token,

2:接口处理:app.get('/aixos-json', (req, res) => { res.json({uname: lisi, }) })
在路由处理中,把配置还请求地址后,还要在res.json中配置好json数据对象, 这样页面请求中,
就不需要携带任何参数了,因为参数在服务器·中已经被处理好了。

axios拦截器用法

//---------------------- axios拦截器用法 -----------------------
1:请求拦截器:axios.interceptors.request.use(function(config) { console.log(config
就是请求对象,它能拿到关于页面的请求信息,我们可以把token设置在请求中config.headers.mytoken='nihao', 

注意mytoken已经在服务器中的跨图请求中设置好了,使用才能用,但是必须通过return将这个参数给return出去) }),
第二个function打印的是错误信息。  

2:响应拦截器:axiosinterceptors.response.use,
可以在这个响应拦截中将res.data的返回值给data,
这样以后在请求中可以直接通过data拿到数据,
而不用res.data.但是也补习return出去,

3:服务器接口,app.get('/adata', (req, res) => {}),是一个普通的接口处理

async函数基本用法

//---------------------- async函数基本用法 -----------------------
1async简化函数封装异步发起数据请求: 函数封装的时候在前面加上async, 
在调用axios.get发起数据请求的时候前面加上await, 他的返回结果被变量接收,
需要将这个变量return出去【其实就是接口返回的数据,被return出去了,
这样后面调用这函数封装, 就能感到数据】

2async简化promise对象, 在封装函数前面加上async, 在函数里面创建peomsie对象, 
该对象中有一个异步任务, 异步任务执行的结果赋值给ret,然后return个函数封装,
这样调用函数通过.then就能拿到异步中的执行结果。

async函数处理多个异步请求

//---------------------- async函数处理多个异步请求 -----------------------
在一个async中可以同时调用多次await拿到异步任务的返回值,
传给第二个接口,当做形参一并传给服务器, 
该案例中接口1中返回的是hello, 所以接口2的请求参数中是有这个hello, 
所以就会执行第一句world, 
如果修改接口路由中的不是hello,就会执行error

阶段小结:axios图书管理案例

业务需求概述

// ----------------------- 业务需求概述 ------------------
布局分析:1:books.html图书页面, 
2:data.json:本地的假数据,并非是真正的mysql数据库中的数据,
3:index.js:入口文件,挂载路由,启动web服务器,用body-parser解析json数据,
启动静态资源服务,处理请求参数,解析json数据,挂载全局路由。
4:readme:接口说明文件, 
5:router.js 配置具体页面路由,和路由对应的处理函数 , 
6:server.js用来存放处理路由函数的的文件,全都市具体路由页面处理函数  
7:data.json:页面所需遍历的数据,暂时用json数据代替,没有使用数据库

图书列表加载_fixed

// ----------------------- 图书列表加载_fixed ------------------
根据案例分析的请求方式和请求地址,查看readme说明文件,调用接口,请求到数据,
方式1: 调用接口,在.thne中把获取到的数据赋值给books,实现页面数据渲染。 
方式2:直接使用es6的箭头函数,this的指向就变正确了,将获取到的数据赋值给books, 
方式3:直接调用接口,把结果的返回值赋值给变量,变量中的ret.data赋值给books,也就实现了数据的渲染。  
方式4;最简单的方式:调用接口返回的数据,直接赋值给this.books实现了页面数据的填充。【渲染部分的逻辑,没有修改,是用现成的,实现了数据的填充,渲染数据】

添加图书

// ----------------------- 添加图书 ------------------
流程示意的解释了接口和请求方式, 以及readme文件对具体的接口说明了详细参数,直接调用了接口,
参数2携带了请求参数name:this.anme,将输入框中的内容发送给了处理器,接口返回的数据,
直接返回给ret,如果res.status状态是200,表示完成添加,调用queryData查询调用渲染接口,再次渲染页面

验证图书名称存在性

// ----------------------- 验证图书名称存在性 ------------------
流程示意中解释了请求方式和请求地址, 按照reamde说明文件中,
直接调用接口响应到的数据让ret接收响应结果,如果ret.status=1表示图书已经存在,
就让提交按钮禁用掉。反之没有就不禁用掉。

编辑图书

// ----------------------- 编辑图书 ------------------
流程示意中解释了请求方式和请求地址, 按照reamde说明文件中, 
先调用接口1,在点击修改中发起axios数据请求,携带id,根据id把这个对象找到,
再把这个输入框中的值渲染到名称输入框中,接口2发起数据请求携带id,那输入框中的值,
赋值给name属性,完成额修改功能,将修改的结果返回给ret, 如果ret.status=200表示数据完成修改, 
再次调用queryData函数,重选渲染页面数据

删除图书

// ----------------------- 删除图书 ------------------
流程示意中解释了请求方式和请求地址, 按照reamde说明文件中,直接调用了接口u,把id1携带过去,
后台服务器接收到数据,就根据id完成删除,返回值给ret,如果ret状态是200,表示删除成功,
调用queryDtata重选渲染页面

【总结就是,根据ppt的示意流程,和readme查看接口和请求方式。一般是直接调用接口,携带id或者书籍的名称,完成功能, 如果状态是200或者1,表示已经完成功能,此时调用queryData重新渲染页面数据】

下一篇:Vue全家桶系列二: Vue Router - 路由