路由(仅限于路由跳转使用):通过query、params进行传递

传参方式直接可观,通过路由传参,可以很便捷的将参数传给下一级路由。
通常使用query传递基本类型的数据(如:字符串,整型等)
params传递引用类型的参数(如:对象、数组等)
query传递的参数可以直接在我们的URL地址栏中可以看到(基本上在地址栏的问号(?)后面)
params传递的参数需要在控制台中去看,也可以利用浏览器中的vue插件进行查看

下面给大家两个代码示例看一下应该就很好理解了(这里使用的是vue2的写法,vue3路由的写法需要使用两个函数【useRoute, useRouter】使用方式相较于vue2的写法有一点点差距,如果写过react的朋友就很清楚了,这两个钩子和react的hooks是类似的。先给大家简单演示一下vue3怎么进行路由传参吧)

vue3路由写法

  • 当前路由传参
import { useRoute, useRouter } from "vue-router"; //导入两个方法
const route = useRoute();
const router = useRouter();
const goTest = () => {
      router.push({
        name:"Test",//路由组件配置定义的名字
        query:'测试数据传递'
      });
    };
  • 下级路由接收参数
<script setup>
import {useRoute} from 'vue-router'
const route = useRoute();
console.log(route.query)
</script>

关于vue3 params传参可以看看下面的params,一个写法。这里就不做多赘述了。但要提醒以下两点:

  1. vue3使用params传参的时候版本过高有的时候会提示params参数丢失。可以参考修改一下vue-router的版本
  2. 在vue3中params传递参数被认为是不可靠的,因为在刷新页面的时候,params传递的参数会消失,如果我们使用了params传参,可能会导致页面数据丢失,因此vue3中,我们就尽量不要使用params传递参数了,同时也被认为是路由中的一种反模式,具体的详细信息可以参考:
    https://github.com/vuejs/router/blob/main/packages/router/CHANGELOG.md#414-2022-08-22

2.1 query

  • 当前本级路由的代码,使用query来传递一个ID
this.$router.push({
      //Test表示我们进入下一级路由的名字,这个name也可以换成path,但是相对应的参数也需要修改,主要看得是我们在vue路由中怎么定义的
        name: 'Test', query: { 
          ID
        }
      });
  • 下一级接收参数 路由代码
created () { //生命周期函数
    console.log(this..$route.query.ID) //输出我们这一级通过路由query得到的ID
  }

2.2 params

和query类似,换汤不换药

  • 当前本级路由的代码,使用query来传递一个ID
this.$router.push({
        name: 'Test', params: { 
          person:{ID:'93808',age:12,name:'张三'}
        }
      });
  • 下一级接收参数 路由代码
created () { //生命周期函数
    console.log(this..$route.params.person.ID) //输出我们这一级通过路由params得到的ID
    console.log(this..$route.params.person.age)
    console.log(this..$route.params.person.name)
  }


父子组件:通过props 和 emits传参

第一种事件传递

父组件

<template>
 	<div>
		<Test @sendData="getData"  :name="张三" :age="18" :isMan="true" />
	</div>
</template>
<script>
import Test from "@/components/Test.vue";
export default defineComponent({
  name: "App",
  components: {
   Test
  },
  setup(){
  const getData = (e) => {
     	console.log(e) //输出从子组件哪里得到的数据
    };
    return {getData}
}
  )}

</script>

子组件

<template>
  <button @click="test()">传参给父组件</button>
</template>
<script>
import { defineComponent} from "vue";
export default defineComponent({
  name: "Test",
  components: {},
  props: {
    name: {
      type: String,
      default: '',
    },
    isMan: {
      type: Boolean,
      default: true,
    },
    age:{
    type:Number,
    default:0
    }
  },
  emits: ['sendData'],
  setup(props,{emit}) {
    console.log(props) //输出父组件通过传过来的参数
      const test = () => {
      emit("sendData", '参数送过来了,父组件,查收一下');//第一个是在父组件中定义的方法,第二个是传递参数
    };
    return { 
    test
     };
  },
});
</script>

说明:上面传递参数时分为两种;静态传参和动态传参

静态传参即<子组件 name="李琦" age="20" />

动态传参即<子组件 :name="name" :age="age" /> 此时的"name"和"age"代表的是变量,也可以像上面一样直接使用值

第二种传递参数的方式--

使用setup语法糖,方法和上面都差不多,主要的区别在于 < script>标签的写法

父组件

<template>
 	<div>
		<Test @sendData="getData"  :name="张三" :age="18" :isMan="true" />
	</div>
</template>
<script setup> //这里就直接在script标签上写上setup,就可以使用语法糖了,简洁高效
import Test from "@/components/Test.vue";
    const getData = (e) => {
     	console.log(e) //输出从子组件哪里得到的数据
    };
</script>

子组件

<template>
  <button @click="test()">传参给父组件</button>
</template>
<script setup>
import { defineProps,defineEmits } from "vue";
const props = defineProps({
  name: {
      type: String,
      default: '',
    },
    isMan: {
      type: Boolean,
      default: true,
    },
    age:{
    type:Number,
    default:0
    }
  )}
 	const emits = defineEmits(['sendData'])
	console.log(props) //输出父组件通过传过来的参数
	const test = () => {
      emits("sendData", '参数送过来了,父组件,查收一下');//第一个是在父组件中定义的方法,第二个是传递参数
    };
</script>

第三种方式--事件监听

父组件

<template>
    <div class="wrap">
        <div>我是Father组件</div>
        <Son ref="son"></Son>
    </div>
</template>

<script>
    import Son from './Son'
    export default {
        name: "Father",
        mounted(){
            this.$refs['son'].$on('func',(msg)=>{
                console.log(msg);
            })
        },
        components:{
            Son
        }
    }
</script>

子组件

<template>
    <div>
        <div>我是Son组件</div>
        <button @click="$emit('func','我是子组件传递的消息1!')">Send1</button>
        <button @click="sendMsg">Send2</button>
    </div>
</template>

<script>
    export default {
        name: "Son",
        methods:{
            sendMsg(){
                this.$emit('func','我是子组件传递的消息!');
            }
        }
    }
</script>

兄弟组件传参:通过第三方库(pubsub-js)

这是一个第三方库,需要安装

npm install pbusub-js

个人主要是用在兄弟传参上的,因为在兄弟传参上,再使用props或者emits就太麻烦了,因为这个确实比较简单我就不多说了,直接看下代码。
然后记一下它两个比较重要的方法
publish() : 消息发布
subscribe():消息订阅

  • 🚓兄弟组件Test.vue
<template>
  <div>
    <h1>Test组件</h1>
    <button @click="sendData"></button>
  </div>
</template>
<script setup>
import PubSub from "pubsub-js";
const sendData = ()=>{
	PubSub.publish('test', '发送数据给Test1')
}
</script>
  • 🚕 兄弟组件Test1.vue
<template>
  <div>
     <h1>Test1组件</h1>
  </div>
</template>
<script setup>
import PubSub from "pubsub-js";
PubSub.subscribe('test', (_, value) => {
      console.log(value)
    })
</script>
  • publishSync
    同步发送消息
  • publish
    同步发送消息
  • subscribe
    订阅消息
  • unsubscribe
    卸载特定订阅
  • clearAllSubscriptions
    清除所有订阅

EventBus传参

1.在main.js种挂载全局EventBus

Vue.prototype.$EventBus = new Vue()

2.A组件

<template>
    <div class="wrap">
        <div>我是组件A</div>
        <button @click="sendMsg">发送</button>
    </div>
</template>

<script>
    export default {
        name: "A",
        methods:{
            sendMsg(){
               this.$EventBus.$emit('sendMsg',"这是组件A发送的消息!")
            }
        }
    }
</script>

3.B组件

<template>
    <div>
        <div>我是组件B</div>
    </div>
</template>

<script>
    export default {
        name: "B",
        mounted(){
            this.$EventBus.$on('sendMsg',(msg)=>{
                console.log(msg);//这是组件A发送的消息!
            })
        },
    }
</script>

通过挂载全局Vue对象传递参数。