在Vue框架中可以有很多方式实现 ajax, 其中有xhr、jQuery、fetch、axios、vue-resource, 其中Vue的作者尤雨溪推荐使用axios,所以在使用Vue框架时,尽量还是使用axios
但是当我们使用ajax时,经常会遇到跨域的问题,比如你本地的端口号是8080, 而服务器的端口号是5050,当你向服务器请求数据时,就会存在跨域的问题。
跨域也有很多的解决方案:
【1】cors方法:不需要前端人员操作,只需要后端人员在写服务器的时候,给你返回响应的时候,会加几个特殊的响应头;
【2】jsonp: 需要后端人员和前端人员都进行相应的操作,不常用 只能解决 GET 请求的跨域问题,其它的请求方式解决不了。
【3】代理 proxy: 在Vue框架中经常使用
因为服务器和服务器之间的数据传输并不是用的ajax,仅仅用的是http,所以不存在跨域的问题,这样本地端口向代理服务器发起请求,而代理服务器目标服务器请求,这样就解决了跨域问题。
1 配置代理服务器
在vue.config.js 中配置
// 1. 开启代理服务器,解决跨域问题(方式一)
devServer: {
proxy: 'http://localhost:5000' // 需要转发的服务器的端口
},
// 2.开启代理服务器(方式二)
devServer: {
proxy: {
'/api': { // /api为请求前缀,想要走代理,就在请求的地址前面加上/api,前缀可以根据需要更改
target: '
pathRewrite: {
'^/api': '' // 去掉请求路径中的/api
},
ws: true, // 用于支持websocket
changeOrigin: true // 用于控制请求头中host值
},
// 配置多个
'/api2': { // /api为请求前缀,想要走代理,就在请求的地址前面加上/api,前缀可以根据需要更改
target: '
pathRewrite: {
'^/api': '' // 去掉请求路径中的/api
},
ws: true, // 用于支持websocket
changeOrigin: true // 用于控制请求头中host值
}, // 配置多个...
// '/foo': {
// target: '
// }
}
}
建议使用方式2,可以配置多个代理服务器,还有一个问题就是当请求的资源本地有时,会优先读取本地得信息,不会走代理,这样就不会读取到服务器中真实的信息。所以如果想要指定走代理的话,需要指定请求前缀。
2 请求github数据案例
【List组件】
export default {
name: 'List',
data() {
return {
info: {
isFirst: true,
isLoading: false,
errMsg: '',
users: []
}
}
},
mounted() {
this.$bus.$on('updateUsers', (dataObj) => {
this.info = {...this.info, ...dataObj} // 重名的属性以后面的为主,后面没有的就用前面的
})
},
}
.album {
min-height: 50rem; /* Can be removed; just added for demo purposes */
padding-top: 3rem;
padding-bottom: 3rem;
background-color: #f7f7f7;
}
.card {
float: left;
width: 33.333%;
padding: .75rem;
margin-bottom: 2rem;
border: 1px solid #efefef;
text-align: center;
}
.card > img {
margin-bottom: .75rem;
border-radius: 100px;
}
.card-text {
font-size: 85%;
}
【Search组件】
Search Github Users
import axios from 'axios'
export default {
name: 'Search',
data() {
return {
keyWord: ''
}
},
methods: {
search() {
/* 请求前更新List数据 */
this.$bus.$emit('updateUsers', { isFirst: false, isLoading: true, errMsg: '', users: []})
axios.get(`https://api.github.com/search/users?q=${this.keyWord}`).then(
response => {
console.log('请求成功了', response.data.items)
/* 请求成功后更新List数据 */
this.$bus.$emit('updateUsers', { isLoading: false, errMsg: '', users: response.data.items})
},
error => {
console.log('请求失败了', error.message)
/* 请求失败后更新List数据 */
this.$bus.$emit('updateUsers', { isLoading: false, errMsg: error.message, users: []})
}
)
}
},
}
【App组件】
import List from './components/List.vue'
import Search from './components/Search.vue'
export default {
name:'App',
components:{
List,
Search
},
}
3 插槽
3.1 默认插槽
【App组件】
- {{item}}
import Category from './components/Category.vue'
export default {
name:'App',
components:{
Category,
},
data() {
return {
foods:['火锅','烧烤','小龙虾','牛排'],
games:['红色警戒','穿越火线','劲舞团','超级玛丽'],
films:['《教父》','《拆弹专家》','《你好,李焕英》']
}
},
}
.container {
display: flex;
justify-content: space-around;
}
#pg1 {
width: 100%;
}
【Category组件】
{{title}}分类
export default {
name: 'Category',
// props: ['listData', 'title']
props: ['title']
}
.category {
margin-left: 100px;
margin-top: 100px;;
width: 200px;
height: 300px;
background-color: skyblue;
border: 1px solid orange;
}
h1{
text-align: center;
background-color: pink;
}
3.2 具名插槽
【App组件】
import Category from './components/Category.vue'
export default {
name:'App',
components:{
Category,
},
data() {
return {
foods:['火锅','烧烤','小龙虾','牛排'],
games:['红色警戒','穿越火线','劲舞团','超级玛丽'],
films:['《教父》','《拆弹专家》','《你好,李焕英》']
}
},
}
.container {
display: flex;
justify-content: space-around;
}
#pg1 {
width: 100%;
}
【Category组件】
{{title}}分类
export default {
name: 'Category',
// props: ['listData', 'title']
props: ['title']
}
.category {
margin-left: 100px;
margin-top: 100px;;
width: 200px;
height: 300px;
background-color: skyblue;
border: 1px solid orange;
}
h1{
text-align: center;
background-color: pink;
}
3.3 作用域插槽
【Category组件】
{{title}}分类
export default {
name: 'Category',
// props: ['listData', 'title']
props: ['title'],
data() {
return {
games:['红色警戒','穿越火线','劲舞团','超级玛丽'],
msg:'你好啊'
}
},
}
.category {
margin-left: 100px;
margin-top: 100px;;
width: 200px;
height: 300px;
background-color: skyblue;
border: 1px solid orange;
}
h1{
text-align: center;
background-color: pink;
}
【App组件】
- {{item}}
- {{item}}
{{msg}}
import Category from './components/Category.vue'
export default {
name:'App',
components:{
Category,
},
}
.container {
display: flex;
justify-content: space-around;
}
相关链接
发表评论