10-Vue技术栈之脚手架配置代理(解决跨域问题)+ GitHub用户搜索案例

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

目录

1、基本使用

1.1 方法一

​ 在vue.config.js中添加如下配置

devServer:{
  proxy:"http://localhost:5000"
}

说明

  1. 优点配置简单请求资源时直接发给前端8080即可。
  2. 缺点不能配置多个代理不能灵活的控制请求是否走代理。
  3. 工作方式若按照上述配置代理当请求了前端不存在的资源时那么该请求会转发给服务器 优先匹配前端资源

1.2 方法二

​ 编写vue.config.js配置具体代理规则

module.exports = {
	devServer: {
      proxy: {
      '/api1': {// 匹配所有以 '/api1'开头的请求路径
        target: 'http://localhost:5000',// 代理目标的基础路径
        changeOrigin: true,
        pathRewrite: {'^/api1': ''}
      },
      '/api2': {// 匹配所有以 '/api2'开头的请求路径
        target: 'http://localhost:5001',// 代理目标的基础路径
        changeOrigin: true,
        pathRewrite: {'^/api2': ''}
      }
    }
  }
}
/*
   changeOrigin设置为true时服务器收到的请求头中的host为localhost:5000
   changeOrigin设置为false时服务器收到的请求头中的host为localhost:8080
   changeOrigin默认值为true
*/

说明

  1. 优点可以配置多个代理且可以灵活的控制请求是否走代理。
  2. 缺点配置略微繁琐请求资源时必须加前缀。

2、GitHub用户搜索案例

  • 实现效果

请添加图片描述

源代码已上传至个人主页。

结构目录
在这里插入图片描述

代码示例
main文件

import Vue from 'vue'
import App from './App.vue'
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap/dist/js/bootstrap.js'       
Vue.config.productionTip = false
new Vue({
	el: '#app',
	render: h => h(App),
	beforeCreate() {
		Vue.prototype.$bus = this
	}
	// 安装全局事件总线
})

App组件

<template>
  <div class="container">
    <Search/>
    <List/>
  </div>
</template>

<script>
import Search from './components/Search.vue'
import List from './components/List.vue'
export default {
	name:'App',
	components:{Search,List}
};
</script>

Search组件

<template>
  <nav class="navbar navbar-light bg-light p-4">
    <div class="container-fluid">
      <a class="navbar-brand">Search Github Users</a>
      <form class="d-flex">
        <input
          class="form-control me-2"
          type="search"
          placeholder="Search"
          aria-label="Search"
          v-model="keyWord"
        />
        <button class="btn btn-outline-success" @click.prevent="searchUsers">
          Search
        </button>
      </form>
    </div>
  </nav>
</template>

<script>
import axios from "axios";
export default {
  name: "Search",
  data() {
    return {
      keyWord: "",
    };
  },
  methods: {
    searchUsers() {
      // 请求前的数据
      this.$bus.$emit("updateListData", {
        isFirst: false,
        isLoading: true,
        errmsg: "",
        users: [],
      });
      axios({
        method: "GET",
        url: `https://api.github.com/search/users?q=${this.keyWord}`,
      }).then(
        (response) => {
          console.log(response.data.items);
          // 请求成功后的数据
          this.$bus.$emit("updateListData", {
            isLoading: false,
            errmsg: "",
            users: response.data.items,
          });
        },
        (error) => {
          // 请求错误后的数据
          this.$bus.$emit("updateListData", {
            isLoading: false,
            errmsg: error.message,
            users: [],
          });
        }
      );
    },
  },
};
</script>

<style>
</style>

List组件

<template>
  <div class="row row-cols-1 row-cols-md-1 g-4 mt-3">
    <div class="col">
      <div
        v-show="info.users.length"
        class="card"
        v-for="user in info.users"
        :key="user.login"
      >
        <a :href="user.html_url" target="_blank">
          <img :src="user.avatar_url" style="width: 100px" />
        </a>
        <p class="card-text">{{ user.login }}</p>
      </div>
    </div>
    <!-- 欢迎词 -->
    <div v-show="info.isFirst">
      <div class="alert alert-success" role="alert">
        <h4 class="alert-heading">welcome to mo world</h4>
        <p>Click Search at the top</p>
        <hr />
        <p class="mb-0">You'll get the list of users you want</p>
      </div>
    </div>
    <!-- 数据加载中 -->
    <div v-show="info.isLoading" class="text-center">
      <div class="spinner-border text-primary" role="status">
        <span class="visually-hidden">Loading...</span>
      </div>
      <div class="spinner-border text-secondary" role="status">
        <span class="visually-hidden">Loading...</span>
      </div>
      <div class="spinner-border text-success" role="status">
        <span class="visually-hidden">Loading...</span>
      </div>
      <div class="spinner-border text-danger" role="status">
        <span class="visually-hidden">Loading...</span>
      </div>
      <div class="spinner-border text-warning" role="status">
        <span class="visually-hidden">Loading...</span>
      </div>
      <div class="spinner-border text-info" role="status">
        <span class="visually-hidden">Loading...</span>
      </div>
      <div class="spinner-border text-light" role="status">
        <span class="visually-hidden">Loading...</span>
      </div>
      <div class="spinner-border text-dark" role="status">
        <span class="visually-hidden">Loading...</span>
      </div>
    </div>
    <!-- 错误 -->
    <div v-show="info.errmsg">{{ info.errmsg }}</div>
  </div>
</template>

<script>
export default {
  name: "List",
  data() {
    return {
      info: {
        isFirst: true,//判断是否为第一次打开页面
        isLoading: false,//判断是否点击了按钮数据正在在加载中
        errmsg: "",//返回一个错误信息
        users: [],//渲染列表
      },
    };
  },
  mounted() {
    this.$bus.$on("updateListData", (dataObj) => {
      this.info = { ...this.info, ...dataObj };
    });
  },
};
</script>


<style>
.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: 0.75rem;
  margin-bottom: 2rem;
  border: 1px solid #efefef;
  text-align: center;
}

.card > img {
  margin-bottom: 0.75rem;
  border-radius: 100px;
}

.card-text {
  font-size: 85%;
}
</style>
阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: vue