Vue中使用ajax技术
Vue自学笔记
Vue
在Vue中使用ajax技术
第一种代理方法
在vue中推荐使用axios库来发送ajax请求。
当使用ajax发送请求的时候很容易产生跨域问题,在vue中解决跨域问题通常借助脚手架配置去解决,让脚手架充当代理服务器,代理服务器和当前前端处于同于个端口下面,前端所有的数据都经过代理服务器,由代理服务器发送给服务器处理数据返回。
当前服务器端口号与请求服务器端口号不一致,会出现跨域的情况。
vue的脚手架vue-cli提供了代理服务器的配置项,在config文件中添加如下。通过vue脚手架启动的服务器打开的前端页面和脚手架是处于同一个服务器的,所以不需要再次配置
devServer: {
proxy: 'http://localhost:请求的服务器端口号'
}
请求的时候请求代理服务器,并将请求的路径提交给代理服务器转交给服务器
局限性
- 一次只能配置一个代理服务器,无法同时配置多个proxy
- 如果当前代理服务器存在请求的资源,那么就会直接返回当前资源。比如public文件下存在请求的资源students文件,那么代理服务器就会将资源直接返回,无法辨别
第二种代理方法
在代理服务器配置项中添加完整的配置,代码如下,使用该方法可以灵活的控制哪些请求路径需要经过代理服务器并且可以设置多个代理路径
devServer: {
proxy: {
'/api': {
target: '<url>',
ws: true,
changeOrigin: true
},
'/foo': {
target: '<other_url>'
}
}
}
修改新的代理配置项如下,但是会出现报错提示。
原因是代理服务器的时候多配置了一个匹配路径/api,然而代理服务器会把/api/student一起拼接在地址后面发送给目的服务器,但是目的服务器不存在/api路径,所以才会报错。
以下是目的服务器的打印输出,可以查看到请求的地址req.url为/api/student,所以才会报错。
pathRewrite配置项
解决的方法就是在代理服务器配置的时候重写路径后再拼接路径发送给服务器,再次配置一个pathReWrite配置项,其中第一个参数为正则表达式
这样子就能成功接收到响应数据了
ws配置项
ws配置项即为websocket选项,服务器与客户端之间实行实时通信的配置
changeOrigin配置项
changeOrigin配置项的作用是,代理服务器每次请求服务器的时候,服务器都会询问代理服务器的主机号信息,当该配置项为true的时候,服务器询问代理服务器的时候,代理会谎称自己的真实端口号,并以请求的目的端口号作为回答。当为false的时候,代理服务器会将自己的真实端口号回答。
配置多个代理
getStudents() {
// 发送ajax请求
axios
.get("http://localhost:8080/api1/students")
.then((res) => {
console.log(res.data);
})
.catch((err) => {
console.log("失败了", err.message);
});
},
getCars() {
// 发送ajax请求
axios
.get("http://localhost:8080/api2/cars")
.then((res) => {
console.log(res.data);
})
.catch((err) => {
console.log("失败了", err.message);
});
},
一定要注意匹配的代理路径不能一个写成/api一个为/api2,否则会出现错误,即/api2会走/api的匹配
devServer: {
proxy: {
'/api1': {
target: 'http://localhost:5000',
pathRewrite: { "^/api1": "" }, //正则表达式
ws: true,
changeOrigin: false
},
'/api2': {
target: 'http://localhost:5001',
pathRewrite: { "^/api2": "" }, //正则表达式
ws: true,
changeOrigin: false
},
}
总结
- 第一种方法
a. 优点:代理配置简单,请求资源直接发给前端8080
b. 缺点:不能配置多个代理,不能灵活控制请求是否走代理路线
c. 如果前端存在同名资源,则代理服务器会直接将该资源返回 - 第二种方法
a. 优点:可以同时配置多个代理,并可以灵活控制请求是否走代理路线
b. 缺点:配置繁琐:请求的时候需要额外加上前缀。并且通常需要多配置一个pathRewrite配置项进行过滤
github案例
在搭建静态页面的时候,先搭建静态结构与样式,其次在分离,但是这次做的是页面需要使用到第三方库bootstrap框架。但是在引入的时候会出现一个问题。即在assets文件下存放css文件并且使用import导入的时候采取的是严格导入,即框架中使用的第三方资源同样需要导入。
所以可以在public中的html文件中引入,link引入的时候不会作出严格限制
github提供的免费api地址https://api.github.com/search/users?q=xxx,其中xxx为搜索的用户名参数
在search组件中
通过点击按钮将刚才输入的关键字存入ajax中发送出去请求数据
List组件
但是这些状态是根据触发自定义事件的时机决定
在List组件中修改了代码如下,方便后期直接修改多个属性的状态
在触发事件的时候,传递一个对象作为参数,对象中的数据都是data中固定好的选项,由于isFirst只有在页面一打开的时候为true,在第一次触发loading的时候修改为false,后期都为false了,所以可以不在对象中传递该属性省略掉。但是这么写的话在this.userList=dataObj的时候就会出现问题,使得data中的数据项缺少一个isFirst
为此可以修改代码,借助对象结构的思想,合并两个对象中的值,重复的则替换。,这样子就不会修改原有data中数据的结构
第三方库发送ajax
vue-resource插件
vue-resource是vue1.0的时候使用的第三方库,基于XML设计,但是被设计为一个插件,所以需要使用Vue.use()去使用。并且返回值也是一个promise
当使用完插件后,vm或者vc身上就会多出一个$http属性,该属性就是实现发送ajax请求。所以的步骤和axios一样只需要替换掉axios属性即可。
封装axios
当项目需要请求的数量增多,如果每次在一个页面中需要使用到axios,就导入,且多个页面之间每次导入后,请求的域名都是一样的,只是路径或参数不同而已,零散在不同的页面不好统一处理,那么就可以封装axios使用,将请求相同的域名放在一个目录下保存,方便修改。
如下代码中,将请求https://www.escook.cn
域名相同的封装在一起,并自定义设置axios配置,因此使用axios.create()
进行自定义配置。
这样子就创建了一个微型的axios,在导入的时候可以使用和axios一样的方法。
import axios from "axios";
export default axios.create({
baseURL: 'https://www.escook.cn' //存放相同的域名
})
导入的时候如下例子
import axios from "@/utils/axios_1"; //导入封装好的axios
// 发送axios请求
axios({
url: "/articles", //只穿路径,基地址已设置好
method: "GET",
params: {
_page: this.page,
_limit: this.limit,
},}).then((res) => {
console.log(res.data);
});
但是如果在另一个页面,也需要请求该域名,同时路径也相同,但是只有请求的参数不同,那么如何实现代码的复用。
在axios请求中,返回的值必然是一个promise
,那么封装接口的返回值一定需要是promise
,否则封装就没有意义。
单独封装一个api
文件夹,存放封装的方法,其中articleApi
文件就是对同域名下,请求相同路径代码的封装,每次调用只需要传递不同的参数即可。
// 实现同域名,同路由下的路由请求
import axios from "@/utils/axios_1";
// 采用按需导出
export function getArticleList(_page, _limit) {
return axios({
url: '/articles',
method: 'GET',
params: {
_page,
_limit
}
})
}
在组件中利用mounted
方法获取数据.这里需要注意的,封装的函数一定需要返回一个promise,并且在调用的时候使用await
或then
获取最终的数据。
// 按需导入采用对象解构
import { getArticleList } from "@/api/articleApi";
------------------------
async mounted() {
// 返回一个promise
const { data: res } = await getArticleList(this.page, this.limit);
console.log(res);
},
默认插槽 slot
设计一个如下显示的页面,然后添加需求,对于第一个和最后一个分裂,将文字分别替换为图片和视频显示。
可以使用笨办法即v-show进行判断显示,也可以实现相应的内容
但是如果数据多起来修改起来就不方便了,这里就可以借助默认插槽了。
在组件标签中,添加html结构,但是页面却并没有显示出来,这是因为vue解析了这个组件标签和img标签,但是在组件中,并不知道将img结构塞到哪里去。所以vue最终就不处理这个图片了
App组件中
Category组件中
所以需要在Category组件中使用默认插槽。即slot标签,slot标签可以放在结构中的任意位置。slot标签用于将组件标签中的内容接收到并存放在该位置显示。
需要注意的是:
- 在vue执行解析的时候,在App组件中就已经将组件标签内部的html元素解析完成了,所以css样式可以写在App组件中,也可以写在对应组件中
- 在slot标签中可以设置默认值,当没获取到组件中的HTML结构的时候,就会将slot标签中的内容显示
- slot插槽不写属性
name
的时候,该值默认为default
,即默认插槽
具名插槽
具名插槽即给slot标签添加name属性标记,给slot标记,引入具名标签的目的是如果存在多个slot标签,而组件标签中的内容未标记是放入哪一个插槽,则vue默认帮助我们将每一个slot标签都填充内容
所以给slot标签添加name属性
但是如果不希望多添加一个div包裹,可以食欲template标签替换掉div,这样在在最终样式中就不会多出些一个标签结构
使用template标签包裹的时候slot对应有两种写法
- 第一种:slot=“name的值”
- 第二种:新版写法v-slot:name的值
当使用v-slot:
写法的时候,需要使用template
标签将HTML标签元素包裹起来,否则报错,而普通的slot=""
写法不用使用template
标签。
v-slot:
这种写法只能用在component组件
或template
身上。
v-slot:
的简写方式是直接写一个#
,效果一致
<slot name="hah"></slot>
-----------------------
//完整写法
<template v-slot:hah>
<h6>这是组件标签内的元素</h6>
</template>
//简写形式
<template #hah>
<h6>这是组件标签内的元素</h6>
</template>
作用域插槽
当给出的数据不能存放在App组价中,而将数据放在使用插槽组件中的时候,需要将数据使用slot标签传递给使用者
在拥有插槽标签的组件中,且该组件拥有数据,将数据传递给使用插值的位置,使用如父组件给子组件传递数据的方式,:参数名=data数据
在使用插槽的位置,必须使用template包裹结构标签,并且在旧版中使用scope属性接收传递过来的数据,在新版中使用slot-scope,数据是一个对象格式,是因为在skot标签中可也传递多个数据,在接收的时候也可以对数据对象进行j解构赋值
在新的版本中甚至可以使用v-slot=“变量”,注意区分v-slot:
结构数据参数
当使用作用域插槽后,可以将不在本身的数据通过slot标签传递过来使用
<Category title="游戏">
<template v-slot="{ games }">
<div>
<ul>
<li v-for="(g, index) in games" :key="index">{{ g }}</li>
</ul>
</div>
</template>
</Category>
<Category title="游戏">
<template v-slot="{ games }">
<div>
<ol>
<li v-for="(g, index) in games" :key="index">{{ g }}</li>
</ol>
</div>
</template>
</Category>
<Category title="游戏">
<template v-slot="{ games }">
<h3 v-for="(g, index) in games" :key="index">{{ g }}</h3>
</template>
</Category>
总结
作用:适用于父组件像子组件中指定的位置插入HTML结## 标题构,也是一种组件之间的通信,适用于父传子
- 默认插槽
- 具名插槽
- 作用域插槽----数据在该组件自身,需要根据数据生成的结构根据组件的使用者决定
-使用插槽的时候接收数据的三种方式(使用插槽传递数据,接收的时候为一个对象包裹数据)
:scope=数据
:slot-scope=数据
:v-slot=数据
动态组件
vue2提供了一个<component>
标签实现动态组件的切换。
<component :is="组件名"></component>
其中is
属性是必选属性,用于确定渲染哪一个组件到该标签所占位的地方显示。
注意:每次切换组件的时候,上一个组件是被销毁的。这一点和路由中切换组件很相似。如果想在切换组件前,保存该组件上的一些操作的时候就需要借助keep-alive
标签将动态切换的组件缓存下来。
将需要被缓存的组件放入keep-alive
标签中,如果不指定缓存组件名,默认缓存所有组件。但这样子性能会变低。
<keep-alive>
<component :is="componentId"></component>
</keep-alive>
给keep-alive
标签指定include
属性,指定需要被缓存的组件名,没有出现在里面的组件名不会被缓存。
同时该标签也可以使用exclude
属性指定哪些组件不需要被缓存。
需要注意的是:这两个属性中写的名字是组件中name
所指定的组件名,而非导入组件时候定义的注册名称
//只会缓存Left组件的信息
<keep-alive include="Left">。。。</keep-alive>
同时设计到组件的动态切换的时候,vue提供了两个新的生命周期函数:activated
和deactivated
,只有在组件切换的时候,这两个生命周期才会使用到。
activated() {
console.log("激活了left");
},
deactivated() {
console.log("失活了left");
},
ESLint语法检查插件
在脚手架中安装eslint插件
- 使用npm命令
$ npm install eslint --save-dev
- 紧跟着使用命令创建一个文件保存信息
$ ./node_modules/.bin/eslint --init
跟着提示信息选择对应的设置,创建完成后,就会新建一个文件.eslintrc.js
在根目录下
在配置文件中添加如下代码信息
"rules": {
/* no-console是配置选项,代表禁用console,后面跟着限制条件:在生成环境下禁用 */
"no-console": process.env.NODE_ENV === 'production' ? "warn" : "off",
"no-debugger": process.env.NODE_ENV === 'production' ? "warn" : "off"
}
如图所示就是代码中出现了不符合规定的地方导致报错提示。在橙色区域给出了是什么规则导致报错出现,可以复制该规则到官网的规则中查询。
因此我们可以借助一些VSCode提供的插件来协助我们处理。
这里先安装第一个插件:ESLint
在设置JSON中添加如下信息
安装第二个插件Prettier - Code formatter
更多推荐
所有评论(0)