菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
0
0

Vue组件通信+Vue组件插槽+动画与过渡+使用vue-cli解决Ajax跨域问题

原创
05/13 14:22
阅读数 182

1 Vue组件通信

1.1 组件间通信基本原则

● 不要在子组件中直接修改父组件的状态数据
● 数据在哪, 更新数据的行为(函数)就应该定义在哪

1.2 vue 组件间通信方式

● props
● vue 的自定义事件
● 消息订阅与发布(如: pubsub 库)
● slot
● vuex

1.3 props

props:让组件接收外部传过来的数据,此方式用于父组件向子组件传递数据
props传递数据原则:单向数据流,只能父传子
注意:
● 如果需要向非子后代传递数据必须多层逐层传递
● 兄弟组件间也不能直接props 通信, 必须借助父组件才可以
● 所有标签属性都会成为组件对象的属性, 模板页面可以直接引用

1.3.1.父组件通过传统方式或v-bind动态绑定向子组件传送数据

<!-- App父组件 -->
<template>
  <div>
   <!-- 传送数据一定要写在父组件的子组件标签上(通过标签属性)-->
   <!-- 1.传统方式传送数据 -->
    //<Student name='张三'/>
   <!-- 2.动态绑定传送数据(不限于形式,可能是函数)  Student.name会作为表达式自动执行 -->
    <Student :name='Student.name'/>
  </div>
</template>
<script>
//引入子组件
import Student from "./components/Student.vue";
export default {
   name: "App",
   components: { Student },
   data() {
    return {
      Student:{
        name:'张三'
      }
    };
  },
};
</script>

1.3.2.子组件内部通过props接收父组件传递的数据

<!-- Student子组件 -->
//第一种方式(只接收)最常用
props:['name']
//第二种方式(限制类型)
props:{name:String}
//第三种方式(限制类型、限制必要性、指定默认值)
props:{
	name:{
	type:String, //类型
	required:true, //必要性
	default:'张三' //默认值
	}
}

备注:props是只读的,Vue底层会监测你对props的修改,如果进行了修改,就会发出警告,若业务需求确实需要修改,那么请复制props的内容到data中一份,然后去修改data中的数据。

App.vue 父组件

<template>
  <div>
    <!-- 传递数据 -->
    <!-- :是v-bind动态绑定 18会作为表达式自动执行 -->
    <Student name='李四' sex='女' :age='18'></Student>
  </div>
</template>

<script>
//引入子组件
import Student from "./components/Student.vue";
export default {
   name: "App",
   components: { Student },
};
</script>

<style>
</style>
Student.vue 子组件
<template>
  <div>
    <h2>学生姓名:{{ name }}</h2>
    <h2>学生性别:{{ sex }}</h2>
    <h2>学生年龄:{{ myAge + 1 }}</h2>
    <button @click="updateAge">尝试修改收到的年龄</button>
  </div>
</template>

<script>
export default {
  name: "Student",
  data() {
    return {
    //若业务需求确实需要修改,那么请复制props的内容到data中一份,然后去修改data中的数据
      myAge: this.age,
    };
  },
  methods: {
    updateAge() {
      this.myAge++;
    },
  },
  //接收数据  简单声明接收
 props:['name','age','sex']
};
</script>

图片.png

1.4 自定义事件

自定义事件:用于子组件向父组件传递数据
使用场景:A是父组件,B是子组件,B想给A传数据,那么就要在A中给B绑定自定义事件(事件的回调在A中)。
隔代组件或兄弟组件间通信此种方式不合适

1.4.1.绑定自定义事件

方式一: v-on

 <!-- App.vue父组件 -->
// 在父组件中给子组件 xxx为自定义事件 getStudentName为回调函数(在父组件中)
<Student @xxx="getStudentName" />
...
  methods: {
  //回调函数
    getStudentName(name) {
      this.studentName = name;
    },
  },

方式二: ref

//通过ref给Student组件打标识
<Student ref="student"  />
...
  methods: {
  //回调函数
    getStudentName(name) {
      this.studentName = name;
    },
  },
 mounted() {
    //通过$refs获取Student组件
    //在获取到的Student组件上绑定自定义事件xxx getStudentName为回调函数
    this.$refs.student.$on("xxx", this.getStudentName); //$on当...时
  },

1.4.2.触发自定义事件

方法:this.$emit(xxx, data)

 <!-- Student.vue子组件 -->
<button @click="sendStudentName">把学生名给App</button>
...
  methods: {
    sendStudentName() {
      //触发Student组件实例身上的xxx自定义事事件
      this.$emit("xxx", this.name);
    }
  },

注意:
● 解绑自定义事件:this.off(‘xxx’) ● 当需要自定义事件只能触发一次:可以使用once修饰符,或once方法。
● 组件上也可以绑定原生DOM事件,需要使用native修饰符。
● <Student @click.native=“show” />
● 隔代组件或兄弟组件间通信不能使用自定义事件

案例

App父组件
<template>
  <div class="app">
    <h1>{{ msg }},学生姓名是:{{ studentName }}</h1>
    <!-- 第一种:使用@或v-on -->
    <!-- <Student @atguigu="getStudentName" /> -->

    <!-- 第二种:使用ref -->
    <Student ref="student" @click.native="show" />
  </div>
</template>

<script>
import Student from "./components/Student";
export default {
  name: "App",
  components: { Student },
  data() {
    return {
      msg: "你好啊!",
      studentName: "",
    };
  },
  methods: {
    getStudentName(name) {
      this.studentName = name;
    },
    show() {
      alert(123);
    },
  },
  mounted() {
    this.$refs.student.$on("atguigu", this.getStudentName); //绑定自定义事件
  },
};
</script>

<style scoped>
.app {
  background-color: gray;
  padding: 5px;
}
</style>
Student.vue子组件
<template>
  <div class="student">
    <h2>学生姓名:{{ name }}</h2>
    <h2>当前求和为:{{ number }}</h2>
    <button @click="add">点我number++</button>
    <button @click="sendStudentName">把学生名给App</button>
    <button @click="unbind">解绑atguigu事件</button>
    <button @click="death">销毁当前Student组件的实例(vc)</button>
  </div>
</template>

<script>
export default {
  name: "Student",
  data() {
    return {
      name: "张三",
      number: 0,
    };
  },
  methods: {
    add() {
      this.number++;
    },
    sendStudentName() {
      //触发Student组件实例身上的atguigu事件
      this.$emit("atguigu", this.name);
    },
    unbind() {
      this.$off("atguigu"); //解绑一个自定义事件
      // this.$off(['atguigu','demo']) //解绑多个自定义事件
      // this.$off() //解绑所有的自定义事件
    },
    death() {
      this.$destroy(); //销毁了当前Student组件的实例,销毁后所有Student实例的自定义事件全都不奏效。
    },
  },
};
</script>

<style lang="less" scoped>
.student {
  background-color: pink;
  padding: 5px;
  margin-top: 30px;
}
</style>

图片.png

1.5 全局事件总线(GlobalEventBus)

全局事件总线:适用于任意组件间通信。

1.5.1.安装全局事件总线

//main.js
new Vue({
  el: '#app',
  render: h => h(App),
  //安装全局事件总线 beforeCreate创建实例前
  beforeCreate() {
    //组件实例对象vc可以访问到Vue原型上的属性和方法,往Vue原型上添加$bus属性 $bus为傀儡
    //那么子组件可以使用$bus,而$bus值为vm(this) 因为vm可以调用$on $emit这些方法
    Vue.prototype.$bus = this;
  },
});

1.5.2.使用事件总线

接收数据: A组件想接收数据,则在A组件中给$bus绑定自定义事件,事件的回调留在A组件自身。

methods(){
  demo(data){......}
}
......
//mounted():初始化操作,绑定自定义事件
//xxx为自定义事件 this.demo为回调函数
mounted() {
  this.$bus.$on('xxx',this.demo)
}
//使用完之后 beforeDestroy解绑自定义事件
beforeDestroy() {
    this.$bus.$off("xxx");
 },

发送数据:

this.$bus.$emit('xxx',数据)

案例:兄弟组件传值(Student => School)

main.js
//引入Vue
import Vue from 'vue'
//引入App
import App from './App.vue'
//关闭Vue的生产提示
Vue.config.productionTip = false

//创建vm
new Vue({
	el:'#app',
	render: h => h(App),
	beforeCreate() {
		Vue.prototype.$bus = this //安装全局事件总线
	},
})
School.vue
<template>
  <div class="school">
    <h2>学校名称:{{ name }}</h2>
    <h2>学校地址:{{ address }}</h2>
  </div>
</template>

<script>
export default {
  name: "School",
  data() {
    return {
      name: "学习猿地",
      address: "北京",
    };
  },
  methods: {
    demo(data) {
      console.log("我是School组件,收到了数据", data);
    },
  },
  mounted() {
    //在School组件给傀儡绑定自定义事件hello,借助傀儡身上的$on方法获取数据
    this.$bus.$on("hello", this.demo);
  },
  beforeDestroy() {
    //解绑当前组件用到的事件
    this.$bus.$off("hello");
  },
};
</script>

<style scoped>
.school {
  background-color: skyblue;
  padding: 5px;
}
</style>
Student.vue
<template>
	<div class="student">
		<h2>学生姓名:{{name}}</h2>
		<h2>学生性别:{{sex}}</h2>
		<button @click="sendStudentName">把学生名给School组件</button>
	</div>
</template>

<script>
	export default {
		name:'Student',
		data() {
			return {
				name:'张三',
				sex:'男',
			}
		},
	
		methods: {
			sendStudentName(){
				this.$bus.$emit('hello',this.name)
			}
		},
	}
</script>

<style lang="less" scoped>
	.student{
		background-color: pink;
		padding: 5px;
		margin-top: 30px;
	}
</style>

图片.png

1.6 消息订阅与发布(pubsub-js 库)

消息订阅与发布:适用于任意组件间通信。
安装pubsub-js 库:

npm i pubsub-js 

引入:

 import pubsub from 'pubsub-js'

接收数据:A组件想接收数据,则在A组件中订阅消息,订阅的回调留在A组件自身。

1.6.1.接收数据

 methods: {
    demo(msgName, data) {
    ...
    },
  },
  mounted() {
    //订阅消息 每一次订阅都会产生一个id
    //msgName代表数据名xxx data代表接收的数据
    this.pubId = pubsub.subscribe("xxx", this.demo);
  },
  beforeDestroy() {
    //通过id取消订阅
    pubsub.unsubscribe(this.pubId);
  },

1.6.2. 发送数据

  methods: {
    sendStudentName() {
      //发布消息
      pubsub.publish("hello", this.name);
    },
  },

案例:兄弟组件传值(Student => School)

School.Vue
<template>
  <div class="school">
    <h2>学校名称:{{ name }}</h2>
    <h2>学校地址:{{ address }}</h2>
  </div>
</template>

<script>
import pubsub from "pubsub-js";
export default {
  name: "School",
  data() {
    return {
      name: "学习猿地",
      address: "北京",
    };
  },
  methods: {
    demo(msgName, data) {
      console.log("我是School组件,收到了数据", msgName, data);
    },
  },
  mounted() {
    //订阅消息 每一次订阅都会产生一个id
    //msgName代表数据名hello data代表接收的数据
    this.pubId = pubsub.subscribe("hello", this.demo);
  },
  beforeDestroy() {
    //通过id取消订阅消息
    pubsub.unsubscribe(this.pubId);
  },
};
</script>

<style scoped>
.school {
  background-color: skyblue;
  padding: 5px;
}
</style>
Student.Vue
<template>
  <div class="student">
    <h2>学生姓名:{{ name }}</h2>
    <h2>学生性别:{{ sex }}</h2>
    <button @click="sendStudentName">把学生名给School组件</button>
  </div>
</template>

<script>
import pubsub from "pubsub-js";
export default {
  name: "Student",
  data() {
    return {
      name: "张三",
      sex: "男",
    };
  },
  methods: {
    sendStudentName() {
      //发布消息
      pubsub.publish("hello", this.name);
    },
  },
};
</script>

<style lang="less" scoped>
.student {
  background-color: pink;
  padding: 5px;
  margin-top: 30px;
}
</style>

图片.png

2 组件插槽

组件插槽是Vue的内置组件,为了让我们封装的组件更加具有扩展性,让使用者可以决定组件内部的一些内容到底展示什么
作用:让父组件可以向子组件指定位置插入html结构,也是一种组件间通信的方式,适用于 父组件 ===> 子组件
分类:默认插槽、具名插槽、作用域插槽
插槽的使用:子组件定义插槽的位置,父组件定义插槽的内容, 控制内容的显示与隐藏
如何封装:抽取共性,保留不同。最好的封装方式就是将共性抽取到组件中,将不同预留为插槽。

默认(匿名)插槽:唯一存在 <slot></slot>
具名插槽:可存在多个 <slot name="up"></slot>
作用域插槽:父组件对子组件的内容进行加工处理

2.1 默认插槽

父组件
<Category>
   <div>html结构1</div>
</Category>
子组件
<template>
    <div>
       <!-- 定义插槽 -->
       <slot>插槽默认内容...</slot>
    </div>
</template>

案例

App.vue
<template>
	<div class="container">
		<Category title="美食" >
			<img src="https://s3.ax1x.com/2021/01/16/srJlq0.jpg" alt="">
		</Category>

		<Category title="游戏" >
			<ul>
				<li v-for="(g,index) in games" :key="index">{{g}}</li>
			</ul>
		</Category>

		<Category title="电影">
			<video controls src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"></video>
		</Category>
	</div>
</template>

<script>
	import Category from './components/Category'
	export default {
		name:'App',
		components:{Category},
		data() {
			return {
				foods:['火锅','烧烤','小龙虾','牛排'],
				games:['红色警戒','穿越火线','劲舞团','超级玛丽'],
				films:['《教父》','《拆弹专家》','《你好,李焕英》','《学习猿地》']
			}
		},
	}
</script>

<style scoped>
	.container{
		display: flex;
		justify-content: space-around;
	}
</style>
Category.vue
<template>
	<div class="category">
		<h3>{{title}}分类</h3>
		<!-- 定义一个插槽(挖个坑,等着组件的使用者进行填充) -->
		<slot>我是一些默认值,当使用者没有传递具体结构时,我不会出现</slot>
	</div>
</template>

<script>
	export default {
		name:'Category',
		props:['title']
	}
</script>

<style scoped>
	.category{
		background-color: skyblue;
		width: 200px;
		height: 300px;
	}
	h3{
		text-align: center;
		background-color: orange;
	}
	video{
		width: 100%;
	}
	img{
		width: 100%;
	}
</style>

图片.png

2.2 具名插槽

父组件
<Category>
  <!--   slot ="xxx"  向插槽名为xxx的插槽里面放内容-->
    <template slot="center">
      <div>html结构1</div>
    </template>

    <template v-slot:footer>
       <div>html结构2</div>
    </template>
</Category>
子组件
<template>
    <div>
       <!-- 定义具名插槽  name="xxx"  xxx为插槽名 -->
       <slot name="center">插槽默认内容...</slot>
       <slot name="footer">插槽默认内容...</slot>
    </div>
</template>

案例

App.vue
<template>
	<div class="container">
		<Category title="美食" >
			<img slot="center" src="https://s3.ax1x.com/2021/01/16/srJlq0.jpg" alt="">
			<a slot="footer" href="http://www.atguigu.com">更多美食</a>
		</Category>

		<Category title="游戏" >
			<ul slot="center">
				<li v-for="(g,index) in games" :key="index">{{g}}</li>
			</ul>
			<div class="foot" slot="footer">
				<a href="http://www.atguigu.com">单机游戏</a>
				<a href="http://www.atguigu.com">网络游戏</a>
			</div>
		</Category>

		<Category title="电影">
			<video slot="center" controls src="http://clips.vorwaerts-

gmbh.de/big_buck_bunny.mp4"></video>
			<template v-slot:footer>
				<div class="foot">
					<a href="http://www.atguigu.com">经典</a>
					<a href="http://www.atguigu.com">热门</a>
					<a href="http://www.atguigu.com">推荐</a>
				</div>
				<h4>欢迎前来观影</h4>
			</template>
		</Category>
	</div>
</template>

<script>
	import Category from './components/Category'
	export default {
		name:'App',
		components:{Category},
		data() {
			return {
				foods:['火锅','烧烤','小龙虾','牛排'],
				games:['红色警戒','穿越火线','劲舞团','超级玛丽'],
				films:['《教父》','《拆弹专家》','《你好,李焕英》','《学习猿地》']
			}
		},
	}
</script>

<style scoped>
	.container,.foot{
		display: flex;
		justify-content: space-around;
	}
	h4{
		text-align: center;
	}
</style>
Category.vue
<template>
	<div class="category">
		<h3>{{title}}分类</h3>
		<!-- 定义一个插槽(挖个坑,等着组件的使用者进行填充) -->
		<slot name="center">我是一些默认值,当使用者没有传递具体结构时,我会出现1</slot>
		<slot name="footer">我是一些默认值,当使用者没有传递具体结构时,我会出现2</slot>
	</div>
</template>

<script>
	export default {
		name:'Category',
		props:['title']
	}
</script>

<style scoped>
	.category{
		background-color: skyblue;
		width: 200px;
		height: 300px;
	}
	h3{
		text-align: center;
		background-color: orange;
	}
	video{
		width: 100%;
	}
	img{
		width: 100%;
	}
</style>

2.3 作用域插槽

理解:数据在组件的自身,但根据数据生成的结构需要组件的使用者来决定。(games数据在Category组件中,但使用数据所遍历出来的结构由App组件决定)

父组件
<Category>
	<template scope="scopeData">
		<!-- 生成的是ul列表 -->
		<ul>
		<!-- scopeData.games就是子组件中的数据 -->
			<li v-for="g in scopeData.games" :key="g">{{g}}</li>
		</ul>
	</template>
</Category>
子组件
<template>
    <div>
        <slot :games="games"></slot>
    </div>
</template>

<script>
    export default {
        name:'Category',
        props:['title'],
        //数据在子组件自身
        data() {
            return {
                games:['红色警戒','穿越火线','劲舞团','超级玛丽']
            }
        },
    }
</script>

案例

App.vue
<template>
	<div class="container">

		<Category title="游戏">
			<template scope="atguigu">
				<ul>
					<li v-for="(g,index) in atguigu.games" :key="index">{{g}}</li>
				</ul>
			</template>
		</Category>

		<Category title="游戏">
			<template scope="{games}">
				<ol>
					<li style="color:red" v-for="(g,index) in games" :key="index">{{g}}</li>
				</ol>
			</template>
		</Category>

		<Category title="游戏">
			<template slot-scope="{games}">
				<h4 v-for="(g,index) in games" :key="index">{{g}}</h4>
			</template>
		</Category>

	</div>
</template>

<script>
	import Category from './components/Category'
	export default {
		name:'App',
		components:{Category},
	}
</script>

<style scoped>
	.container,.foot{
		display: flex;
		justify-content: space-around;
	}
	h4{
		text-align: center;
	}
</style>
Category.vue
<template>
	<div class="category">
		<h3>{{title}}分类</h3>
		<slot :games="games" msg="hello">我是默认的一些内容</slot>
	</div>
</template>

<script>
	export default {
		name:'Category',
		props:['title'],
		data() {
			return {
				games:['红色警戒','穿越火线','劲舞团','超级玛丽'],
			}
		},
	}
</script>

<style scoped>
	.category{
		background-color: skyblue;
		width: 200px;
		height: 300px;
	}
	h3{
		text-align: center;
		background-color: orange;
	}
	video{
		width: 100%;
	}
	img{
		width: 100%;
	}
</style>

图片.png

3 Vue封装的过渡与动画

3.1.过渡与动画作用

在插入、更新或移除DOM元素时,在合适的时候给元素添加样式类名

3.2.图示

图片.png

3.3.写法

准备好样式:
v-enter(进入的起点) v-enter-active(进入的过程) v-enter-to(进入的终点)
v-enter(离开的起点) v-enter-active(离开的过程) v-enter-to(离开的终点)

使用<transtion>包裹要过渡的元素,并配置name属性:

<transition name="hello" >
  <h1 v-show="isShow">你好啊!</h1>
</transition>

备注:若有多个元素需要过渡,则需要使用,且每个元素都要指定key值

App.vue
<template>
  <div>
    <Test />
    <Test2 />
    <Test3 />
  </div>
</template>

<script>
import Test from "./components/Test";
import Test2 from "./components/Test2";
import Test3 from "./components/Test3";
export default {
  name: "App",
  components: { Test, Test2, Test3 },
};
</script>

<style>
</style>

使用动画代码实现

Test.vue
<template>
	<div>
		<button @click="isShow = !isShow">显示/隐藏</button>
		<transition name="hello" appear>
			<h1 v-show="isShow">你好啊!</h1>
		</transition>
	</div>
</template>

<script>
	export default {
		name:'Test',
		data() {
			return {
				isShow:true
			}
		},
	}
</script>

<style scoped>
	h1{
		background-color: orange;
	}

	.hello-enter-active{
		animation: atguigu 0.5s linear;
	}

	.hello-leave-active{
		animation: atguigu 0.5s linear reverse;
	}

	@keyframes atguigu {
		from{
			transform: translateX(-100%);
		}
		to{
			transform: translateX(0px);
		}
	}
</style>

使用过渡代码实现

Test2.vue
<template>
  <div>
    <button @click="isShow = !isShow">显示/隐藏</button>
    <transition-group name="hello" appear>
      <h1 v-show="isShow" key="1">你好啊!</h1>
      <h1 v-show="isShow" key="2">学习猿地!</h1>
    </transition-group>
  </div>
</template>

<script>
export default {
  name: "Test",
  data() {
    return {
      isShow: true,
    };
  },
};
</script>

<style scoped>
h1 {
  background-color: orange;
}
/* 进入的起点 离开的终点  */
.hello-enter,
.hello-leave-to {
  transform: translateX(-100%);
}
/* 进入的整个过程 离开的整个过程 */
.hello-enter-active,
.hello-leave-active {
  transition: 0.5s linear;
}
/* 进入的终点 离开的起点 */
.hello-enter-to,
.hello-leave {
  transform: translateX(0);
}
</style>

使用第三方动画库实现(https://animate.style/)

Test3.vue
<template>
  <div>
    <button @click="isShow = !isShow">显示/隐藏</button>
    <transition-group
      appear
      name="animate__animated animate__bounce"
      enter-active-class="animate__swing"
      leave-active-class="animate__backOutUp"
    >
      <h1 v-show="!isShow" key="1">你好啊!</h1>
      <h1 v-show="isShow" key="2">学习猿地!</h1>
    </transition-group>
  </div>
</template>

<script>
import "animate.css";
export default {
  name: "Test",
  data() {
    return {
      isShow: true,
    };
  },
};
</script>

<style scoped>
h1 {
  background-color: orange;
}
</style>

4 使用vue-cli解决Ajax跨域问题

使用vue-cli开启代理服务器ajax跨域问题
方法一:
在vue.config.js中添加如下配置:

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

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

方法二:
编写vue.config.js配置具体代理规则:

module.exports = {
devServer: {
    proxy: {
      '/api1': {
        // 匹配所有以 '/api1'开头的请求路径
        target: 'http://localhost:5000', // 将请求代理到目标服务器上
        changeOrigin: true,
        //重写路径 将请求中的/api1 重写为为空字符串
        pathRewrite: { '^/api1': '' },
        ws: true, //用于支持websocket
        changeOrigin: true, //用于控制请求头中的host值
      },
      '/api2': {
        // 匹配所有以 '/api2'开头的请求路径
        target: 'http://localhost:5001', // 代理目标的基础路径
        changeOrigin: true,
        pathRewrite: { '^/api2': '' },
        ws: true, //用于支持websocket
        changeOrigin: true, //用于控制请求头中的host值
      },
    },
  },
}
/*
   changeOrigin设置为true时,服务器收到的请求头中的host为:localhost:5000
   changeOrigin设置为false时,服务器收到的请求头中的host为:localhost:8080
   changeOrigin默认值为true
*/

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

开启两个资源服务器

图片.png

app.vue
<template>
  <div id="app">
    <!-- 在8080端口上获取5000和5001端口上的数据  -->
    <button @click="getStudents">获取学生信息</button>
    <button @click="getCars">获取汽车信息</button>
  </div>
</template>

<script>
import axios from "axios";
export default {
  name: "App",
  methods: {
    getStudents() {
      axios.get("http://localhost:8080/api1/students").then(
        (response) => {
          console.log("请求成功了", response.data);
        },
        (error) => {
          console.log("请求失败了", error.message);
        }
      );
    },
    getCars() {
      axios.get("http://localhost:8080/api2/cars").then(
        (response) => {
          console.log("请求成功了", response.data);
        },
        (error) => {
          console.log("请求失败了", error.message);
        }
      );
    },
  },
};
</script>

图片.png

发表评论

0/200
0 点赞
0 评论
收藏