vue2.x和vue3.x多种通信方式

一、父组件props传值给子组件

子组件定义props接收父组件传递的值

(一)vue2.x

。◕‿◕。 父组件

<template>
  <div>
    <child :title="title" :list="list" type="1" />
  </div>
</template>

。◕‿◕。 子组件

<template>
  <div class="hello">
    <h1>{{ title }}</h1>
  </div>
</template>

<script>
export default {
  props:["title","list","type"] // 接收传递过来的值
}
</script>

// 因为有的对象可能赋值会失败,或者可以这样写
<script>
export default {
  props:{
    title:{
      type:String,
      default:''
    },
    list:{
      type:Array,
      default: () => {
         return []
      }
    },
    type:{
      type:Number,
      default:-1
    }
  } // 接收传递过来的值
}
</script>

(二)vue3.x

。◕‿◕。 父组件

// 跟vue2.x写法一样
<template>
  <div>
    <child :title="title" :list="list" type="1" />
  </div>
</template>

。◕‿◕。 子组件

<script lang='ts' setup>
const props = defineProps({
  title: {
    type: Object,
    default: ""
  },
  list: {
    type: Array,
    default: () => {
      return []
    }
  },
  type: {
    type: Number,
    default: -1
  }
})
const { title, list, type} = toRefs(props)
</script>

二、子组件$emit传值给父组件

子组件传值给父组件,需要在子组件中触发一个事件,在事件中,调用$emit(‘父组件的方法名’, ‘传递的值’),然后在父组件中,通过在子组件标签上自定义事件函数,接收传递过来的值。

(一)vue2.x

。◕‿◕。 父组件

<template>
  <div>
    <child @childEvent="parentEvent" />
  </div>
</template>

<script>
import child from "../components/child.vue";

export default {
  components: {
    child
  },
  data() {
    return {}
  },
  methods: {
    parentEvent(value) {
      // 子组件传递过来的值
      console.log(value)
    }
  }
}
</script>

。◕‿◕。 子组件

<template>
  <div>
    <h1 @click="handle">{{ age }}</h1>
  </div>
</template>

<script>
export default {
  name: "child",
  data() {
    return {
      age:18
    }
  },
  methods: {
    handle(){
      this.age++
      this.$emit("childEvent", this.age)
    }
  }
}
</script>

(一)vue3.x

。◕‿◕。 父组件

<template>
  <div>
    <child @childEvent="parentEvent" />
  </div>
</template>

<script lang='ts' setup>
import child from './child
function parentEvent(value) {
  // 子组件传递过来的值
  console.log(value)
}

</script>

。◕‿◕。 子组件

<template>
  <div>
    <h1 @click="handle">{{ age }}</h1>
  </div>
</template>

<script lang='ts' setup>
import { ref } from 'vue'
const age = ref(18)
const emit = defineEmits(['childEvent'])

function handle() {
  age.value++
  emit('childEvent',age)
}
</script>

(三)$emit补充

①$emit传递多个参数

$emit的第一个参数后面添加,父组件按顺序接收。或者直接传递一个Object

// 子组件
this.$emit("childEvent", this.age, 'xxx', 'xxxx')
// or
this.$emit("childEvent", { a: 1, b: 2 })

// 父组件
parentEvent(value1, value2) {
  console.log(value1)
  console.log(value2)
}
②$emit触发时的同时,父组件也传递参数

。◕‿◕。 父组件

<template>
  <div class="home">
    <son
      @btnClick="btnClick($event, '父组件参数aaaa')"
      @moreValueClick="moreValueClick(arguments, '父组件自己的参数')"
      @fatherNoValueClick="fatherNoValueClick"
    ></son>
  </div>
</template>

<script>
import son from '@/components/son.vue'
export default {
  name: 'Home',
  components: {
    son
  },
  methods: {
    btnClick (item, b) {
      console.log(item)
      console.log(b)
    },
    moreValueClick (vals, item) {
      console.log(vals) //数组
      console.log(item)
    },
    fatherNoValueClick(a,b,c){
      console.log(a);
      console.log(b);
      console.log(c);
    },
  }
}
</script>

。◕‿◕。 子组件

<template>
  <div class="son">
    <div class="border">
      <div>我是子组件的内容</div>
      <button @click="btnClick">子组件传递一个参数,父组件自定义参数触发事件</button>
      <button @click="moreValueClick">子组件传递多个参数,父组件自定义参数触发事件</button>
      <button @click="fatherNoValueClick">子组件传递多个参数,父组件无参数触发事件</button>
    </div>
  </div>
</template>

<script>
export default {
  methods: {
    btnClick(){
      this.$emit('btnClick','子组件的参数')
    },
    moreValueClick(){
      this.$emit('moreValueClick','子组件参数1','子组件参数2','子组件参数3')
    },
    fatherNoValueClick(){
      this.$emit('fatherNoValueClick','参数1','参数2','参数3')
    },
  },
}
</script>

<style lang="less" scoped>
.son{
  .border{
    button{
      display: block;
    }
  }
}
</style>

三、祖先组件provide传递孙子组件inject接收

就是当前根组件,可以向子组件传递数据,也可以向孙组件传递数据,这就是provide提供依赖数据的方式,其中接受数据为 inject的方式;注意:provide 和 inject 绑定并不是可响应的,然而,如果传入了一个可监听的对象,那么其对象的 property 还是可响应的。

  • 跨级通信第一步: 祖先组件通过provide配置选项来提供数据
  • 跨级通信第二步: 后代组件通过inject配置选项来接收数据

(一)vue2.x

①传固定的值

。◕‿◕。 祖先组件

provide:{
  message:"先传一个具体的值, 测试看看"
},

。◕‿◕。 后代组件

inject:['message']
②传组件里面的属性

。◕‿◕。 祖先组件

data () {
    return {   
      msg:'祖先组件信息, 要跨一级直接传递给后代组件',      
    }
  },  
provide(){
    return {
      message:this.msg     
    }
  },

。◕‿◕。 后代组件

inject:['message']
③响应式跨级传递数据

provideinject并不是响应式的, 是一个单项数据流(祖先组件改变的数据, 后代组件不改变), 但是可以通过传递一个 property 或 reactive对象给provide来改变这种行为,变成响应式的。

。◕‿◕。祖先组件

data () {
    return {        
      obj:{
        msg:'祖先组件信息, 要跨一级直接传递给后代组件'
      }   
    }
  }, 
provide(){
    return {    
      obj:this.obj // 响应式对象的方式     
    }
  }, 

。◕‿◕。后代组件

// 模版展示
<p>祖先组件跨级传过来的值:  {{ obj.msg }} </p>
// 接收对象
inject:['obj']
④函数返回响应式数据

。◕‿◕。祖先组件

<template>
  <div>     
    <p>祖先信息:  {{ msg }}</p>
    <Content> </Content> 
    <button @click="msg='我是祖先组件msg改变的结果'">改变msg</button>
  </div>
</template>

<script>
import Content from './components/Content.vue'
export default {
  data () {
    return {   
      // 要把msg传递给孙组件
      msg:'祖先组件信息, 要跨一级直接传递给后代组件'      
    }
  },  
  components:{
    Content, 
  },
  
  provide(){
    return {
      message:()=>this.msg // 函数返回响应式数据
    }
  }
}
</script>


。◕‿◕。后代组件

<template>
  <h2>{{ msg }}</h2>
  <p>祖先组件跨级传过来的值:  {{ newMsg }} </p>
</template>

<script>
export default{
  data()
  {
    return {
      msg:'我是后代组件的数据展示'
    }
  },
  /**
   * 跨级通信第二步: 
   * 后代组件通过`inject`配置选项来`接收`数据
   * 
   * inject接收到的函数不要直接显示在模板中, 
   * 转化为计算属性后展示, 后面维护起来更轻松
   */
  inject:['message'],
  computed:{
    newMsg(){
      return this.message()
    }
  }
}
</script>

(二)vue3.x

①传非响应式数据,也就是非 ref,reactive定义的数据

传递到后代组件的时候,是无法对此数据进行响应式处理的,也就是在后代组件修改它的值,不会影响视图

。◕‿◕。 祖先组件

<template>
  <div>
    <Content></Content>
  </div>
</template>

<script setup lang="ts">
import { provide, ref } from 'vue'
import Content from './components/Content.vue'
provide('flag', true) // 传递的是 普通的值 非响应式的值

</script>


。◕‿◕。 后代组件

<template>
  <div>
    {{ childFlag }}
  </div>
</template>

<script setup lang="ts">
import { inject } from 'vue'
let childFlag = inject('flag')
</script>

②提供响应式数据,也就是ref ,reactive定义的数据

传递到后代组件时候,是可以修改数据的值,同时影响的是注入的依赖值,同时发生变化的,视图也会更新

。◕‿◕。 祖先组件

<template>
  <div>
    <Content></Content>
  </div>
</template>

<script setup lang="ts">
import { provide, ref } from 'vue'
import Content from './components/Content.vue'
provide('num', ref<Number>(0)) // 传递的是 响应式的数据

</script>

。◕‿◕。 后代组件

<template>
  <div>
    <button @click="changeNum">我修改了num值</button>
  </div>
</template>

<script setup lang="ts">
import { inject } from 'vue'
let childNum = inject('num')
const changeNum = () => {
  childNum.value++ //祖先组件的num也会更新
}
</script>
③传递对象,在子孙组件之中修改组件的值,同时响应效果

。◕‿◕。 祖先组件

<template>
  <div class="main">
    我是祖先组件
    <B></B>
  </div>
</template>

<script setup lang="ts">
import { provide, reactive, ref } from 'vue'
import B from './childCom/B.vue'
type Person = {
  name: String
  age: Number
}
provide(
  'Person',
  reactive<Person>({
    name: 'pink',
    age: 0,
  })
)
</script>

。◕‿◕。 子组件

<template>
  <div class="b">
    我是子组件B bPerson - {{ bPerson }} <br />
    <button @click="changName">我是修改 name</button>
    <BSon></BSon>
  </div>
</template>

<script setup lang="ts">
import { inject, reactive } from 'vue'
import BSon from './BSon.vue'
const bPerson = inject('Person', reactive({ name: 'pink', age: 0 }))
const changName = () => {
  bPerson.name = '我是B组件修改的'
}
</script>

// inject 函数有两个参数:
// inject(name,default)
// name:接收 provide 提供的属性名。
// default:设置默认值,可以不写,是可选参数。

。◕‿◕。 孙组件

<template>
  <div class="bSon">
    我是B组件的子组件 bSonPerson -- {{ bSonPerson }} <br />
    <button @click="changePerson">我修改了Person值</button>
  </div>
</template>

<script setup lang="ts">
import { inject, reactive, Ref, ref } from 'vue'
let bSonPerson = inject('Person', reactive({ name: 'pink', age: 0 }))
const changePerson = () => {
  bSonPerson.name = '我是BSon组件修改的'
  bSonPerson.age = 20
}
</script>

点击bSon组件事件

子组件:我是子组件B bPerson - {{ name:我是BSon组件修改的,age:20 }}

孙组件:我是子组件B bPerson - {{ name:我是BSon组件修改的,age:20 }}

点击B组件事件

子组件:我是子组件B bPerson - {{ name:我是B组件修改的,age:20 }}

孙组件:我是子组件B bPerson - {{ name:我是B组件修改的,age:20 }}

四、父组件通过$refs获取子组件数据

在子组件标签上写上ref属性,父组件通过this.$refs.name.方法名或者this.$refs.name.属性名的方式可以访问子组件的数据和方法

(一)vue2.x

。◕‿◕。 父组件

<template>
  <div>
    <Son :title="msg" ref="hello" />
    <button @click="parentEvent">我是父亲</button>
  </div>
</template>

<script>
import Son from "../components/son.vue";

export default {
  name: "parent",
  data() {
    return {
      msg: "搜索音乐",
    };
  },

  methods: {
    parentEvent() {
      this.$refs.hello.add();
      console.log(this.$refs.hello.age);
    },
  },
  components: {
    HelloWorld
  },
};
</script>

。◕‿◕。 子组件

<template>
  <div class="hello">
    <h1>{{ title }}</h1>
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  props: ["title"],
  data() {
    return {
      age:18
    }
  },
  methods: {
    add(){
      console.log("我是子组件")
    }
  }
}
</script>

(二)vue3.x

在 Vue 3 中的 Composition API 中,$refs并不直接可用于 setup函数。这是因为 $refs是 Vue 2 的实例属性,而在 Vue 3 中,setup函数是与模板实例分离的,不再使用实例属性。

实际工作中确实有需求,在 setup函数使用$refs,下面有两种方法。

需要注意,如果想让父组件获取子组件的数据或者方法需要通过defineExpose对外暴露,因为vue3中组件内部的数据对外“关闭的”,外部不能访问
getCurrentInstance

。◕‿◕。 父组件

<template>
  <div>
    <Son :title="msg" ref="hello" />
    <button @click="parentEvent">我是父亲</button>
  </div>
</template>

<script setup lang="ts">
import { ref, getCurrentInstance } from 'vue'
import Content from './components/Son.vue'

const { proxy } = getCurrentInstance()

const parentEvent = ()=> {
   proxy.$refs.hello.num.value
   proxy.$refs.hello.getData()
}
</script>

。◕‿◕。 子组件

<template>
  <div>
    {{ num }}
  </div>
</template>

<script setup lang="ts">
const num = ref(1)

const getData = ()=> {
   console.log('获取数据方法')
}

defineExpose({
  num,
  getData
})
</script>
②ref

。◕‿◕。 父组件

<template>
  <div>
    <Son :title="msg" ref="hello" />
    <button @click="parentEvent">我是父亲</button>
  </div>
</template>

<script setup lang="ts">
import { ref, getCurrentInstance } from 'vue'
import Content from './components/Son.vue'

const hello= ref()

const parentEvent = ()=> {
   proxy.$refs.hello.num.value
   proxy.$refs.hello.value.getData()
}
</script>

。◕‿◕。 子组件

<template>
  <div>
    {{ num }}
  </div>
</template>

<script setup lang="ts">
const num = ref(1)

const getData = ()=> {
   console.log('获取数据方法')
}

defineExpose({
  num,
  getData
})
</script>

五、子组件$parent获取父组件数据

在子组件中,可以使用多层$parent访问其上级父组件的数据和方法。如果是多重嵌套,也可以使用多层parent层层往上。

如果要找父组件的父组件,this.parent.parent.xxx,如此类推

(一)vue2.x

。◕‿◕。 父组件

<template>
  <div>
    <Son :title="msg" ref="hello" />
  </div>
</template>

<script>
import Son from "../components/son.vue";

export default {
  name: "parent",
  components: {
    Son
  },
  data() {
    return {
      msg: "搜索音乐",
    };
  },

  methods: {
    parentEvent() {
      console.log("我是父组件的方法");
    },
  }
}
</script>

。◕‿◕。 子组件

<template>
  <div class="hello">
    <h1 @click="add">{{ title }}</h1>
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  props: ["title"],
  data() {
    return {
      age:18
    };
  },
  methods: {
    add(){
      console.log(this.$parent.msg)
      this.$parent.parentEvent();
    }
  },
};
</script>

(二)vue3.x

父组件的数据与方法需要通过defineExpose方法对外暴露

。◕‿◕。 父组件

<template>
  <div class="box">
    </child ref="child"> 
  </div>
</template>

<script setup lang="ts">
//$parent:可以在子组件内部获取到父组件的实例
import child from './child.vue'
import { ref } from 'vue';
//父组件钱数
let money = ref(100000000);

//获取子组件的实例
let child = ref();

//对外暴露
defineExpose({
   money
})
</script>

。◕‿◕。 子组件

<template>
  <div class="child">
     <h1>我是子组件,我有{{money}} 元</h1>
     <button @click="handler($parent)">点击我父组件给我10000元</button>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';
//子组件钱数
let money = ref(999999);

//闺女按钮点击回调
const handler = ($parent)=>{
   money.value+=10000; 
   $parent.money-=10000;//父亲钱数减少
}
</script>

六、attrs和listeners多级组件间传递

多层级组件之间传参可以使用$attrs, 如果使用普通的父子组件传参prop和$emit,每一级组件都需要进行接收,然后向下传递,就很麻烦。

在使用$attrs时,如果组件中不使用props进行接收,这些参数(class 和 style 除外)将会作为此组件的HTML元素特性。如果这个组件中使用了props进行了接收,那么被接收的参数将不会向下传递。

$attrs 是传递参数变量的

$listenters 是传递函数的

(一)vue2.x

。◕‿◕。 祖先组件

<template>
  <div class='grand-father-view'>
    <fatherView :row="row" :column="column" @friendly="friendly" @diss="diss"> </fatherView>
  </div>
</template>
 
<script>
import fatherView from './fatherView.vue'
export default {
 components:{ fatherView },
 data() {
    return {
      isOpen: false,
      row: {name: 'nicholas', age: 23},
      column:{sex: '男', id : 12},
    }
  },
  methods: {
    diss() {
      console.log('diss');
    },
    friendly() {
      console.log('friendly');
    },
  }
}
<script>

。◕‿◕。 父组件

fatherView组件中,拦截row参数,column将通过$attrs继续传递

<template>
  <div class='father-view'>
    <p>{{ row.name }}</p>
    <p>{{ row.age }}</p>
    <childView v-bind="$attrs" v-on="$listeners"> </childView >
  </div>
</template>
 
<script>
import childView from './childView .vue'
export default {
 inheritAttrs: true, // 浏览器F12调试可以看到 此组件的根元素,:column="[objcet, object]"
 components:{ childView  },
 data() {
    return { }
 },
 props:{
    row: {
        type: object,
        default: () => {}
    }
 },
 mounted(){
     this.$listeners.friendly()
 }
}
<script>

。◕‿◕。 子组件

childView组件中,接收column参数

<template>
  <div class='child-view'>
    <p>{{ column.sex }}</p>
    <p>{{ column.id }}</p>
  </div>
</template>
 
<script>
export default {
 data() {
    return { }
 },
 props:{
    column: {
        type: object,
        default: () => {}
    }
 },
 mounted(){
     this.$listeners.diss()
     this.$listeners.friendly()
 }
}
<script>

(二)vue3.x

$attrs 对象包含了除组件所声明的 props 和 emits 之外的所有其他 attribute,例如 class,style,v-on 监听器等等。

Vue3 中 template 不再要求只有一个根元素了。所以 attrs 在 template 中分2种情况使用。

①只有一个根元素

。◕‿◕。 祖先组件

<template>
<div class="test-con">
  <fatherView
      msg="我是消息"
      data="123"
      name="张三"
      style="color: red;"
  >
  </fatherView>
</div>
</template>
<script setup lang="ts">
import fatherView from "./fatherView.vue";

。◕‿◕。 父组件

fatherView组件中,拦截data参数,其他将通过$attrs继续传递

<template>
<div class="test-con">
  </son v-bind="$attrs" >
</div>
</template>
<script setup lang="ts">
import Son from "./Son.vue";
const props = defineProps({
  data: {
    type: String,
    default: ""
  }
})
const { data } = toRefs(props)

。◕‿◕。 子组件

<template>
  <div class="child-con">
    {{ msg }}
  </div>
</template>
<script setup lang="ts">
defineProps({
  msg:{
    type:String
  }
})
</script>

没被props接收的属性都被绑定到根元素上了,可以得出结论:只有1个根元素的情况下,子组件中,没被 props 接收的属性,都会绑定在根元素上。

可以在子组件中这样操作,使用 $attrs.xxx ,这里的 xxx 是对应的属性名

。◕‿◕。 子组件

<template>
  <div class="child-con">
    {{ msg }}
    {{ $attrs.name }}
  </div>
</template>
<script setup lang="ts">
defineProps({
  msg:{
    type:String
  }
})
</script>

有2个根元素的情况下

 。◕‿◕。 祖先组件

<template>
<div class="test-con">
  <fatherView
      msg="我是消息"
      data="123"
      name="张三"
      style="color: red;"
  >
  </fatherView>
</div>
</template>
<script setup lang="ts">
import fatherView from "./fatherView.vue";

。◕‿◕。 父组件

fatherView组件中,拦截data参数,其他将通过$attrs继续传递

<template>
<div class="test-con">
  </son v-bind="$attrs" >
</div>
</template>
<script setup lang="ts">
import Son from "./Son.vue";
const props = defineProps({
  data: {
    type: String,
    default: ""
  }
})
const { data } = toRefs(props)

。◕‿◕。 子组件

<template>
  <div>
    {{ msg }}
  </div>
  <div>
    {{ msg }}
  </div>
</template>
<script setup lang="ts">
defineProps({
  msg:{
    type:String
  }
})
</script>

传入是 style 样式都不生效了,可以得出结论:2个根元素的情况下,子组件中,没被 props 接收的属性,都不会生效

如果我们此时希望第二个元素绑定所有没被 props 接收的属性,可以使用 v-bind=“$attrs” 的方法实现。

。◕‿◕。 子组件

<template>
  <div>
    {{ msg }}
  </div>
  <div v-bind="$attrs">
    {{ msg }}
  </div>
</template>
<script setup lang="ts">
defineProps({
  msg:{
    type:String
  }
})
</script>

③语法补充
(1)Options API语法
<!-- 父组件 ParentCom.vue -->
<template>
  <ChildCom
    msg="雷猴"
    data="123"
    name="鲨鱼辣椒"
    style="color: red;"
  />
</template>
 
<script setup>
import ChildCom from './ChildCom.vue'
</script>
 
 
 
<!-- 子组件 ChildCom.vue 暂不关注 template 部分 -->
<script>
export default {
  props: {
    msg: {
      type: String
    }
  },
  mounted() {
    console.log(this.$attrs)
  }
}
</script>
(2)Composition API 3.0的语法 
<!-- 父组件 ParentCom.vue -->
<template>
  <ChildCom
    msg="雷猴"
    data="123"
    name="鲨鱼辣椒"
    style="color: red;"
  />
</template>
 
<script setup>
import ChildCom from './ChildCom.vue'
</script>
 
 
 
<!-- 子组件 ChildCom.vue 暂不关注 template 部分 -->
<script>
export default {
  props: {
    msg: {
      type: String
    }
  },
  setup(props, context) {
    console.log('props: ', props)
    console.log('attrs: ', context.attrs)
  }
}
</script>
(3)Composition API 3.2的语法 
<!-- 父组件 ParentCom.vue -->
<template>
  <ChildCom
    msg="雷猴"
    data="123"
    name="鲨鱼辣椒"
    style="color: red;"
  />
</template>
 
<script setup>
import ChildCom from './ChildCom.vue'
</script>
 
 
 
<!-- 子组件 ChildCom.vue 暂不关注 template 部分 -->
<script setup>
import { useAttrs } from 'vue'
 
const props = defineProps({
  msg: {
    type: String
  }
})
 
const attrs = useAttrs()
 
console.log('props: ', props)
console.log('attrs: ', attrs)
</script>

七、事件总线event-bus

涉及到跨页面时需要用到vuex或者缓存的方式传值。一般来说用vuex做状态管理是项目的首选,但有一些小型而且快消的项目,对后期维护要求不高的,也可以考虑用EventBus作为通信方式。EventBus的有点在于灵活,去中心化,代码量少。

(一)vue2.x

①入口man.js注册

Vue.prototype.$EventBus = new Vue()

②在需要传值的地方,$emit(‘事件名’,‘参数’)传递参数

this.$EventBus.$emit('incident',data)

③在接收值的地方,mounted周期中使用$on(‘事件名’, function(data){})接收

this.$EventBus.$on('incident')

(二)vue3.x

在 Vue3 中,Vue 不再是构造函数,而是 Vue.createApp({}) 返回一个没有$on、$emit和 $once 方法的对象。简单的说就是没有event-bus,根据官方文档 Vue 3 迁移指南所建议的,我们可以使用 mitt 或 tiny-emitter 库在组件之间调度事件。

八、vue-router传值

(一)vue2.x

①router-link路由导航方式传参

父组件:<router-link to="/跳转到的路径/传入的参数"></router-link>
子组件:this.$route.params.参数key 接受父组件传递过来的参数

例如:

路由配置:

bashbash{path:'/father/son/:num',name:A,component:A}```

地址栏中的显示:

http://localhost:8080/#/father/son/44

调用方法:

<router-link to="/father/son/传入的参数">父亲组件<router-link>
 子组件通过  this.$route.params.num 接受参数

②调用$router.push实现路由传参

路由配置:

{path: '/d/:id', name: D, component: D}

地址栏中显示:

http://localhost:8080/d/123

。◕‿◕。 父组件

<template>
  <div>
    <button @click="clickHand(123)">push传参</button>
  </div>
</template>

<script>
  methods: {
    clickHand(id) {
      this.$router.push({
        path: `/d/${id}`
      })
    }
  }
</<script>

。◕‿◕。子组件

mounted () {
  this.id = this.$route.params.id
}
③通过路由属性name匹配路由,再根据params传递参数

路由配置:路径后不需要在加上传入的参数,但是name必须和父组件中的name一致

{path: '/b', name: 'B', component: B}

地址栏中的显示:地址栏不会带有传入的参数,而且再次刷新页面后参数会丢失

http://localhost:8080/#/b

。◕‿◕。父组件

<template>
  <div>
    <button @click="ClickByName()">params传参</button>
  </div>
</template>

<script>
  methods: {
    ClickByName() {
      this.$router.push({
        name: 'B',
        params: {
          context: '内容'
        }
      })
    }
  }
</<script>

。◕‿◕。子组件

mounted () {
  this.context = this.$route.params.context
}
④通过query来传递参数

配置路由:

{path: '/c', name: 'C', component: C}

地址栏中的显示(中文转码格式):

http://localhost:8080/#/c?sometext=%E8%BF%99%E6%98%AF%E5%B0%8F%E7%BE%8A%E5%90%8C%E5%AD%A6

 。◕‿◕。父组件

<template>
  <div>
    <button @click="clickQuery()">query传参</button>
  </div>
</template>

<script>
  methods: {
    clickQuery() {
      this.$router.push({
        path: '/c',
        query: {
          context: '内容'
        }
      })
    }
  }
</<script>

。◕‿◕。子组件

mounted () {
  this.context = this.$route.query.context
}

(二)vue3.x

1、首先在需要跳转的页面引入API—useRouter

<template>
  <router-link to="/home/userId"></router-link
</template>

<script lang="ts" setup>
import { useRouter } from 'vue-router'

//先在setup中定义
 const router = useRouter()

// 字符串
router.push('home')

// 对象
router.push({ path: 'home' })

// 命名的路由
router.push({ name: 'user', params: { userId: '123' }})

// 带查询参数,变成 /register?userId=123
router.push({ path: 'register', query: { userId: '123' }})

// 如果提供了 path,params 会被忽略,但query 没有这种情况,此时需要提供路由的 name 或手写完整的带有参数的 path
const userId = '123'
router.push({ name: 'user', params: { userId }})
router.push({ path: `/user/${userId}` })
// 这里的 params 不生效
router.push({ path: '/user', params: { userId }})

</script>

2、在跳转页面定义router变量

<script lang="ts" setup>
import { useRoute } from 'vue-router'

//首先在setup中定义
const route = useRoute()
//query
let userId=route.query.userId;
//params
let userId=route.params.userId;

</script>

九、vuex传值

多个组件需要共享数据时使用

参考文章

Vue2中关于vuex的应用,包括Vuex模块化+命名空间的使用,四个map方法的使用等_vue2 vuex使用-CSDN博客

终于有人可以将 Vue3《Vuex》说的如此直白_vue3 vuex 怎么使用语法糖-CSDN博客

参考网址:

超详细 vue组件通信的10种方式_vue组件间通信-CSDN博客

Vue3进阶<5>vue3中的$attrs的使用_vue3 $attrs-CSDN博客

$attrs 和 $listeners (vue2&&vue3)_vue3 $listeners-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值