一、解决 Ajax 跨域问题
跨域问题是浏览器的同源策略造成的,为了安全,浏览器不允许javascript和跨域的内容交互,跨域不止存在于前后端,还有俩个窗口间也可以存在跨域。
1.解决跨域的方法:
- CORS(通过设置响应头允许跨域)
- jsonp(引入外部资源不受同源策略限制,只支持GET)
- 代理服务器
2.配置代理服务器
代理服务器所处的端口号和自己本地服务端口保持一致 如:localhost:8080
借助vue脚手架配置代理(devServe.proxy):
方法一
在vue.config.js中添加如下配置:
//开启代理服务器 xxx是代理服务器要转发的服务器的端口号
devServer:{
proxy:"http://localhost:xxx"
}
说明:
1.优点:配置简单,请求资源时直接发给前端(8080)即可。
2.缺点:不能配置多个代理,不能灵活的控制请求是否走代理
3.工作方式:若按照上述配置代理,当请求了前端不存在的资源时,那么该请求会转发给服务器,如果请求的资源本身就有则不会走代理。(优先匹配前端资源)
方法二(常用)
在vue.config.js中添加如下配置:
devServer:{
proxy:{
'/api1':{//匹配所有以'/api1'开头的请求路径
target:'http://localhost:xx1',//代理目标的基础路径(只写到端口号)
ws:true,//用于支持websocket
changeOrigin:true,
//取消多余的'/api1'前缀
pathRewrite:{'^/api1':''}
}
'/api2':{//匹配所有以'/api1'开头的请求路径
target:'http://localhost:xx2',//代理目标的基础路径
changeOrigin:true,
//取消多余的'/api2'前缀
pathRewrite:{'^/api1':''}
}
}
}
//changeOrigin默认为true
//changeOrigin设置为true时,服务器收到的请求头中的host是伪造的——host和被请求服务器端口号相同
//changeOrigin设置为false时,服务器收到的请求头中的host是真实的——host为发送请求的端口号
使用axios发送请求:
axios.get('http://localhost:8080/api1/...').then(
response =>{
console.log('请求成功',response.data)
},
error =>{
console.log('请求失败',error.message)
}
)
说明:
1.优点:可以配置多个代理,且可以灵活的控制请求是否走代理(不走代理:取消前缀)
2.缺点:配置略微繁琐,请求资源时必须加前缀
3.vue项目中常用的Ajax库
axios
通用的Ajax请求库,官方推荐,使用广泛
vue-resource
vue插件库,vue1.x使用广泛,官方已不维护
二、slot插槽
1.什么是插槽
作用:让父组件可以向子组件指定位置插入html结构,也是一种组件间的通信方式,适用于父组件==>子组件
可以简单理解为:在子组件挖了一个坑<slot></slot>
需要用父组件给子组件的内容来填坑,至于怎么填要看父组件,而坑的位置则由子组件决定。
2.插槽的使用方法
(1)默认插槽(匿名插槽、单个插槽)
一个组件中只能有一个该类插槽
//父组件
<Category>
<div>...html结构...</div>
</Category>
//子组件
<template>
<div>
//定义插槽
<slot>插槽默认内容(当使用者没有传具体结构时会显示)</slot>
</div>
</template>
(2)具名插槽
在子组件给插槽命名,名字通过属性name来定义
父组件则通过给template标签绑定v-slot:xxx
可简写为#xxx
一个组件中可以有很多具名插槽
//父组件
<Category>
//v-slot只能使用在template标签上
<template v-slot:centet">
<div>...html结构1...</div>
</template>
<template #footer>
<div>...html结构2...</div>
</template>
</Category>
//子组件
<template>
<div>
//定义插槽
<slot name="center">插槽默认内容...</slot>
<slot name="footer">插槽默认内容...</slot>
</div>
</template>
(3)作用域插槽
数据在组件自身,但根据数据生成的结构需要组件的使用者来决定。
slot-scope="xxx"
,xxx是一个对象存放着定义插槽的组件传来的数据
//父组件
<Category>
//v-slot只能使用在template标签上
<template slot-scope="scopeDate">
//生成ul列表
<ul>
<li v-for="g in scopeData.game" :key="g">{{g}}</li>
</ul>
</template>
</Category>
<Category>
<template slot-scope="scopeDate">
//生成h4标题
<h4 v-for="g in scopeData.game" :key="g">{{g}}</h4>
</template>
</Category>
//子组件
<template>
<div>
<slot :games="games"></slot>
</div>
</template>
<script>
export default{
name:'Category',
//数据在子组件自身
data(){
return{
games:{'红色警戒','穿越火线','英雄联盟'}
}
},
}
</script>