【Vue】Vue全家桶(三)Vue组件通信+Vue组件插槽+动画与过渡+使用vue-cli解决Ajax跨域问题

视频帧插学习(三):ema-vfi代码拆解和分析 video interp EMA-VFI 阅读详情

1 Vue组件通信

1.1 组件间通信基本原则

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

1.2 vue 组件间通信方式

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

1.3 props

props:让组件接收外部传过来的数据,此方式用于父组件向子组件传递数据
props传递数据原则:单向数据流,只能父传子
注意:

  • 如果需要向非子后代传递数据必须多层逐层传递
  • 兄弟组件间也不能直接props 通信, 必须借助父组件才可以
  • 所有标签属性都会成为组件对象的属性, 模板页面可以直接引用

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>

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>

在这里插入图片描述

1.4 自定义事件

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

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>

在这里插入图片描述

1.5 全局事件总线(GlobalEventBus)

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

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;
  },
});

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>

在这里插入图片描述

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

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

npm i pubsub-js 

引入:

 import pubsub from 'pubsub-js'

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

1.接收数据

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

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>

在这里插入图片描述

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>

在这里插入图片描述

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>

在这里插入图片描述

3 Vue封装的过渡与动画

1.过渡与动画作用
在插入、更新或移除DOM元素时,在合适的时候给元素添加样式类名
2.图示
在这里插入图片描述
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
*/

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

开启两个资源服务器

在这里插入图片描述

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>

请添加图片描述

基于LED可见光通信的物联网系统设计_344 随着物联网技术的不断发展,传统无线通信在工业环境中面临电磁干扰强、通信质量不稳定等问题。为此,本文设计了一种基于LED可见光通信的物联网系统,实现工厂车间内设备状态的稳定、高效、低干扰数据传输。系统主要由设备节点、设备主机、华为云物联网服务器以及可视化上位机构成。 设备节点采集机器的出货量、运行状态、机身温度等关键信息,通过调制后的LED可见光信号发送至设备主机。主机利用红外接收器接收光信号后进行解调处理,并通过WIFI模块将数据上传至华为云IOT服务器。 阅读详情

相关推荐

安卓逆向实战:用Batch Apktool 3.8.0快速汉化APK的完整流程

本文详细解析了如何使用Batch Apktool 3.8.0进行安卓APK汉化的完整流程,包括环境配置、反编译、资源解析、深度汉化、重构建与签名优化等关键步骤。通过这款集成化逆向工具,开发者可以高效完成APK汉化,提升工作效率。

s1t2u3的博客 1099

vue组件间的通讯的10种方法

1.props/$emit props主要用于父组件传递数据给子组件,父==>子。 Vue自定义事件 父组件可以在使用子组件的地方直接用 v-on来监听子组件触发的事件 。即父组件中使用 v-on绑定自定义事件,然后在子组件中使用 $emit(eventName,data)触发事件 仅仅用于父子组件传递,不适用于 三层及其以上 2. $emit/$on 这种方法通过一个空的Vue实例作为中央事件总线(事件中心),用它来触发事件和监听事件,巧妙而轻量地实现了任何组件间的通信,包括父子、兄弟、跨级。当

Serena_tz的博客 7169

开源CC6920差分霍尔电流传感器模块实战指南——从选型到波形分析

本文详细介绍了CC6920差分霍尔电流传感器模块的选型、硬件连接、参数计算及波形分析技巧。通过实战案例,展示了该开源硬件在电流测量中的优势,包括超低内阻、电气隔离和抗干扰能力,适用于电机控制、开关电源保护等场景。

weixin_28738397的博客 376

Vue3 节点之间连线

目前每个节点的连线的偏移量是根据其在list中的索引有关,因此越靠后的节点其偏移量也越大,感觉不美观,想要修改成根据其是当前第几个连接的元素来控制偏移量,但是试了很多次都无法实现,好像偏移量在第一次初始化后就无法更改了,再次进行初始化是无效的,偏移量仍然是第一次初始化时设置的值,待解决。创建一个全局数组用来存放连接信息,在连接connection和connectionDetached时,对其进行push和splice操作。在initLeaf中初始化每个节点的信息。利用jsPlumb进行节点的连线操作。

leoz1的博客 2807

【YOLO 系列】基于YOLO V8的智能车载交通标志识别系统【python源码+Pyqt5界面+数据集+训练代码】

本文详细介绍了基于YOLO V8构建智能车载交通标志识别系统的完整流程。从环境搭建、数据集准备、模型训练到PyQt5图形界面开发,提供了Python源码和实战代码,帮助开发者快速实现高精度、实时的交通标志检测应用,提升驾驶辅助系统的开发效率。

wdx012345的博客 966

17【Protues单片机仿真】基于51单片机的太阳能智能谷物翻晒机器人

基于51单片机,避障,低于50CM报警,LED灯亮起,自动翻晒用光敏电阻,光照强度大,电机转动,相当于翻晒粮食,远程控制用按键代替,按下去电机就转动,相当于翻晒粮食,然后光照强度和超声波的距离都在LCD1602显示屏显示出来。

weixin_70360261的博客 1448

Vue的样式穿透(在父组件中为子组件定义样式)

在使用Vue开发前端项目时,我们经常需要引入第三方组件,比如下面的例子(假设我们已经注册了element-ui): <template> <div class="root"> <el-button type="plain">点击我</el-button> </div> </template> 这是一个来自element-ui的按钮组件,它会渲染成这样: 那我如果我们想修改这个第三方组件的样式该怎么办呢? 下面的样式并

夕山雨的博客 6284

開機自動進入UEFI Interactive Shell無法正常開機怎麼辦?

BIOS/UEFI,啟動後進入UEFI Interactive Shell大多數人都告訴你沒有安裝系統去裝系統吧,但你明明昨天還在運行系統?今天就這樣?有沒有解決辦法?

sheaahhoi1的博客 7740

vue+高德API搭建前端环境页面

html 这部分使用Vue的模板语法,定义了组件的HTML结构。 包含一个元素,类名为,它可能是整个页面的容器。 内部有一个元素,其为,该元素很可能是用来承载地图的容器,后续的地图会被渲染在这个元素中。 二、脚本部分() javascript 导入和组件声明: :从导入高德地图的JavaScriptAPI加载器。 :定义一个Vue组件,组件名为。 数据部分(): :存储地图对象,初始化为。

weixin_66547608的博客 1485

【无人机设计与控制】基于PID控制的四旋翼无人机系统Matlab仿真

本文设计并仿真了基于PID控制的四旋翼无人机系统。首先,建立了四旋翼无人机的数学模型,涵盖了无人机的动力学和控制系统。通过PID控制器对四旋翼的姿态和位置进行控制,以实现其稳定飞行。使用MATLAB/Simulink对该系统进行仿真,验证了PID控制算法在四旋翼控制中的有效性。仿真结果表明,PID控制能够较好地调节四旋翼的飞行姿态,并有效抑制外部干扰,使得无人机能够保持平稳飞行。

2401_84610415的博客 1804

避坑指南:Abaqus网格划分中90%用户会遇到的5个质量陷阱(附解决方案)

本文深入剖析Abaqus网格划分中90%用户会遇到的5个典型质量陷阱,包括单元扭曲、扫掠网格失败、尺寸梯度控制等,并提供工程级解决方案。通过Python脚本和虚拟拓扑等技巧,帮助用户提升网格质量,确保有限元分析结果的可靠性,适用于CAE工程师和仿真分析师。

weixin_29243279的博客 99

vue实现连线效果

vue+jsplumb实现连线效果

weixin_47330492的博客 7229

RK3576 PCIE接口调试:基于RTL8111HS的网卡驱动移植

检查项方法电源电压复位时序检查设备树 reset-gpios链路速率设备识别lspci -vvv驱动加载。

小灰灰的博客 731

Vue全家桶(Vue基础看这篇就够了)

第一章:vue核心 1.1.Vue 简介 1.1.1 官网 1.英文官网:Vue.js - The Progressive JavaScript Framework | Vue.js 2.中文官网:Vue.js 1.1.2 Vue是什么? 一套用于构建用户界面的渐进式Javascript框架 作者:尤雨溪 1.1.3 Vue的特点 1.采用组件化模式,提高代码复用率、且让代码更好维护 2.声明式代码,让编码人员无需直接操作DOM,提高开发效率 3...

qq_63533863的博客 1万+

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

Vue 04 Vue 中的 Ajax、slot 插槽

Vue 中的 Ajax、slot 插槽

yavlgloss的博客 1291

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Vue2进阶——插槽/ajax问题

Vue2进阶——插槽/ajax问题

ning_xiao_xuan的博客 1011

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Vue学习笔记05 组件的自定义事件-组件通信-$nextTick-脚手架解决ajax跨域-插槽-过渡动画

文章目录Vue学习笔记05组件的自定义事件子组件给父节点传值第一种写法 @或v-on第二种写法:使用ref + $on事件触发解绑 \$emit \$off Vue学习笔记05 组件的自定义事件 内置指令->HTML元素使用 自定义指令-> 组件使用 子组件给父节点传值 第一种写法 @或v-on @或v-on 绑定在子组件的vc上 绑定事件:使用@或v-on:将回调函数绑定在子组件的vc上 触发事件:在子组件中触发,$emit(‘事件名’,参数1…,参数2…) <!-- 第一种写法,使用

好好学习天天向上 1026

Vue中使用ajax技术

Vue自学笔记

m0_62475892的博客 4749

系统性学习vue-vue中的ajax

public目录下的内容会被代理服务器纳为己用,而当我们的请求代理服务器可以自己回答时,就不会再将请求转发给后端(是不是挡板?让父组件可以向子组件指定位置插入html结构,也是一种组件间通信的方式,适用于父组件===>子组件。: 插槽内容的样式可以写在子组件里,也可以写在使用者上。同源策略是规定了三个东西必须一致:协议名,主机名,端口号。而请求中的地址也要改为代理服务器地址,但要带着请求信息。需要加个配置,将转发的请求按规则重写。目前不常使用了,因为不咋维护了。请求是成功的 但是请求资源是。

qq_39685400的博客 1725

Vue2.x - 组件化编程

目录初识组件化什么是组件、组件化为什么需要组件化简单了解Vue组件和vm的关系Vue组件分类非单文件组件定义组件不能使用el,只能使用template关于template属性的说明data不能使用对象式写法,只能使用函数式写法注册组件局部注册全局注册定义组件的简写形式使用(创建)组件组件标签创建组件实例的时机组件名的定义组件名定义的两种情况组件名的命名规则以及Vue DevTools显示规则组件标签对于组件命名的限制组件嵌套实现组件嵌套app管理员组件深入理解组件VueComponentVueCompone

优快云 3708

Vue中的ajax请求、Vuex、Vue UI组件库

😹 作者: gh-xiaohe 😻 gh-xiaohe的博客 😽 觉得博主文章写的不错的话,希望大家三连(✌关注,✌点赞,✌评论),多多支持一下!!!

gh_xiaohe的博客 1313

Vue 中的 ajax(使用axios发请求,vue脚手架配置代理服务器 (解决开发环境 Ajax 跨域问题),vue 项目中常用的 2 个 Ajax 库(axios,vue-resource)插槽)

Vue 中的 ajax(使用axios发请求,vue脚手架配置代理服务器 (解决开发环境 Ajax 跨域问题),插槽)

weixin_51249285的博客 590

Vue3系统入门与项目实战学习笔记

文章目录1 Vue 语法初探1-1 课前须知1-2 初学编写 HelloWorld 和 Counter1-3 编写字符串反转和内容隐藏小功能1-4 编写TodoList 小功能,了解循环和双向绑定1-5 组件概念初探,对 TodoList 进行组件代码拆分2 Vue 基础语法2-1 Vue 中应用和组件的基础概念2-2 理解 Vue 中的生命周期函数2-3 常用模版语法讲解2-4 数据,方法,计算属性和侦听器2-5 样式绑定语法2-6 条件渲染2-7 列表循环渲染2-8 事件绑定2-9 表单中双向绑定指令的

倩mys的博客 6970

Vue笔记04-Vue中的Ajax

解决开发环境中Ajax跨域问题 在使用jQuery的时候,前后端交互通常使用$.ajax,但是会存在跨域问题。在jQuery中,有大量操作DOM的方法,但是在Vue中,我们不会主动操作DOM,所以配合Vue使用的时候,大多使用axios,使用npm i axios进行安装。 首先使用命令node server1.js和node server2.js启动两个本地服务。 在axios中,使用代理的方式解决了跨域问题。通过Vue-CLI的devServer.proxy配置可以看到两种配置方式。需要手动创建vue.

王劭阳的博客 602

前端开发面试题总结-vue2框架篇(三)

摘要 本文整理了Vue开发中的核心知识点,包括浏览器安全策略、跨域解决方案、状态管理和组件通信等。重点内容:1)浏览器同源策略及CORS、代理服务器两种跨域解决方案;2)Vuex和Pinia在状态管理上的差异对比;3)组件通信的多种方式(Props/$emit、Event Bus、Vuex等);4)插槽机制和作用域插槽的应用;5)虚拟DOM的工作原理和性能优化。还涉及过滤器、路由守卫等实用技巧,以及组件封装的实际经验。这些知识构成Vue开发生态的核心技术栈,对构建高效、安全的前端应用具有重要意义。

分享前端与鸿蒙开发技术、面试题总结 1220

学习 Vue中的Ajax 这一篇就够了

vue-resource axios 插槽slot

Laptoy的博客 963
上一篇: 【Git】Git常见操作指令
下一篇: &&运算符、||运算符、?.可选链运算符、? ?空位合并运算符
前端More
博客等级 码龄7年 301粉丝 72原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值