vue组件间传值


一、父子传值

1.props(父传子),也叫:动态属性绑定

在父组件中使用Props(动态属性绑定)的方式将数据传递给子组件。父组件可以动态更新绑定的属性,从而影响子组件的数据。
在父组件中通过v-bind或简写的冒号语法绑定属性,如右 :propsName=“data”。
在子组件中声明props接收数据,例如props: { data: {} }。

// 父组件中
  <ExportPdfTableItem :desItem="items" :threeDTOS="items.threeDTOS" :taskNoId="taskNoId"
:reportId="reportId" :textList="textList" :sort="sort"  :specialFlag="specialFlag"></ExportPdfTableItem>


// 子组件中
name: 'PrintModelTabelItem',
  props: ['sort', 'desItem', 'threeDTOS', 'taskNoId', 'specialFlag', 'reportId', 'textList', 'flag'],
  data() {
    return {
      loading: false
    }
  },

2.事件(子传父emit)

通过在子组件中触发自定义事件,并在父组件中监听该事件来传递数据。
● 在子组件中使用emit方法触发自定义事件,例如this. e m i t 方法触发自定义事件,例如 t h i s . emit方法触发自定义事件,例如this. emit方法触发自定义事件,例如this.emit(‘eventName’, data)。
● 在父组件中使用@或v-on指令监听该事件,例如@eventName=“handleEvent”,然后在methods中实现handleEvent方法来接收传递的数据。

3.refs传值

可以通过$refs属性在父组件中直接访问子组件实例,并通过子组件实例来获取或修改子组件的数据。这种方式适用于父组件需要主动操作子组件的情况。

// 父组件
<template>
    <div>
        <h1>{{ meaasge }}</h1>
        <SonCompont ref="myChild"> </SonCompont>
        <span>{{ mg }}</span>
    </div>
</template>
<script >
import SonCompont from '../components/SonComponent'
export default {
    name: 'About',
    components: {
        SonCompont
    },
    data() {
        return {
            meaasge: '世界真美好',
            msg: '大头大图',
            mg: ''
        }
    },
    mounted() {
        this.mg = this.$refs.myChild.giveParent
    },
}
</script>
// 子组件
<template>
    <div class="hello">
        <p>{{ msg }}</p>
        <button @click="give">点击传值</button>
    </div>
</template>
  
<script>
export default {
    name: 'HelloWorld',
    props: {
        msg: String
    },
    data(){
        return{
            giveParent:'来自56595'
        }
    },
   
}
</script>
  

4.parent和children

通过访问父组件的this. p a r e n t 或子组件的 t h i s . parent或子组件的this. parent或子组件的this.children属性来直接访问父组件或子组件的实例,并进行数据传递,但是这种方式在多层级嵌套时不够灵活,容易造成耦合。
在父组件中使用 this. c h i l d r e n 拿到的是一个数组类型,它包含所有子组件实例。 t h i s . children 拿到的是一个数组类型,它包含所有子组件实例。this. children拿到的是一个数组类型,它包含所有子组件实例。this.children[0].子组件属性

// 父组件
<template>
    <div>
        <h1>{{ meaasge }}</h1>
        <span style="color: aqua;"> {{ mg }}</span>
    </div>
</template>
<script >
import SonCompont from '../components/SonComponent'
export default {
    name: 'About',
    components: {
        SonCompont
    },
    data() {
        return {
            meaasge: '世界真美好',
            msg: '大头大图',
            mg: '',
            parentMessage:'父亲数据'
        }
    },
    mounted() {
        this.mg = this.$refs.myChild.giveParent
        // 属性都在下标为0上
        let r=this.$children[0].h
        r()  //打印666
    },
}
</script>
// 子组件
<template>
    <div class="hello">
        <p>{{ msg }}</p>
        <button @click="give">点击传值</button>
        <span style="color: red;">{{ fromParent }}</span>
    </div>
</template>
  
<script>
export default {
    name: 'HelloWorld',
    props: {
        msg: String
    },
    data(){
        return{
            giveParent:'来自56595',
            fromParent:'',
            fromSon: '来自儿子',
            h(){
                console.log(6666);
            }
        }
    },
    methods:{
        give(){
            this.fromParent=this.$parent.parentMessage
        }
    }
}
</script>
  

5.Provide和Inject

通过在父组件中使用provide提供数据,在子组件中使用inject注入数据。这种方式可以实现跨级组件之间的数据传递。vue3 Composition API也提供了相应的功能
父组件:provide与data同一级别
在这里插入图片描述
子组件中:

// 子组件
<template>
    <div class="hello">
        {{ sharedMessage }}
    </div>
</template>
  
<script>
export default {
    name: 'HelloWorld',
    inject: ['sharedMessage'],
    data(){
        return{
        }
    },
}
</script>
  

6.Vuex状态管理

1、vue2安装npm i vuex@3 vue3安装npm i vuex@4

//父组件
<template>
    <div>
        <ChildA />
        <ChildB />
        <h1>数字:{{ $store.state.num }}</h1>
        <button @click="plusOne">点击加1</button>
    </div>
</template>
<script>
import ChildA from '../components/ChildA' // 导入A组件
import ChildB from '../components/ChildB' // 导入B组件
export default {
    components: { ChildA, ChildB },// 注册组件
    data() {
        return {
            counter: 0,
        };
    },
    methods: {
        plusOne() {
            // 调用vuex的API。dispatch是vuex的API。调用这个方法之后,store对象中的add这个action回调函数会被自动调用。
            this.$store.dispatch("add", this.counter);
        },
    },
}
</script>

//子组件一
<template>
    <div id="childA">
        <h1>我是A组件</h1>
        <button @click="transform">点我让B组件接收到数据</button>
        <p>因为点了B,所以信息发生了变化:{{ BMessage }}</p>
        <div>{{ $store.state.BMsg }}</div>
        <h1>数字:{{ $store.state.num }}</h1>
    </div>
</template>
<script>
export default {
    data() {
        return {
            AMessage: 'Hello,B组件,我是A组件'
        }
    },
    computed: {
        BMessage() {
            // 这里存储从store里获取的B组件的数据
            return this.$store.state.BMsg
        }
    },
    methods: {
        transform() {
            // 触发receiveAMsg,将A组件的数据存放到store里去
            this.$store.commit('receiveAMsg', {
                AMsg: this.AMessage
            })
        }
    }
}
</script>

```typescript
//子组件二
<template>
 <div id="childB">
   <h1>我是B组件</h1>
   <button @click="transform">点我让A组件接收到数据</button>
   <p>点了A,我的信息发生了变化:{{AMessage}}</p>
 </div>
</template>

<script>
 export default {
   data() {
     return {
       BMessage: 'Hello,A组件,我是B组件'
     }
   },
   computed: {
     AMessage() {
       // 这里存储从store里获取的A组件的数据
       return this.$store.state.AMsg
     }
   },
   methods: {
     transform() {
       // 触发receiveBMsg,将B组件的数据存放到store里去
       this.$store.commit('receiveBMsg', {
         BMsg: this.BMessage
       })
     }
   }
 }
</script>
//vuex
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const state = {
    AMsg: '',
    BMsg: '',
    num: 0
}

const mutations = {
    receiveAMsg(state, payload) {
        // 将A组件的数据存放于state
        console.log(payload, "pay");
        state.AMsg = payload.AMsg
    },
    receiveBMsg(state, payload) {
        // 将B组件的数据存放于state
        state.BMsg = payload.BMsg
    },
    add(state, val) {
        state.num += val
    }
}
const actions = {
    add(context, val) {
        val = val + 1
        context.commit("add", val)
    }
}
export default new Vuex.Store({
    state,
    mutations,
    actions
})

// 创建store对象, 管理三个核心对象
// const store = new Vue({
//     //负责执行某个行为的对象
//     actions: actions,
//     //负责更新的对象
//     mutations: mutations,
//     //状态对象
//     state: state
// })

7.路由传参、sessionStorage传参、插槽(Slots)

二、兄弟间传值

1.EventBus

(1)在src中新建一个Bus.js的文件,然后导出一个空的vue实例
(2)在传输数据的一方引入Bus.js 然后通过Bus.emit(“事件名”,“参数”)来来派发事件,数据是以emit()的参数形式来传递
(3)在接受的数据的一方引入Bus.js 然后通过 Bus.$on(“事件名”,(data)=>{data是接受的数据})

// Bus.js
import Vue from 'vue'
export default new Vue()
// 兄弟一组件
<template>
  <div class="hello">
    <div style="width: 200px;height: 200px;background-color:pink;" v-show="show"></div>
  </div>
</template>

<script>
import Bus from '@/meaasge/Bus';
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
  data() {
    return {
      show: true
    }
  },
  mounted() {
    Bus.$on('getData', (data) => { this.show = data })
  },
}
</script>
// 兄弟二组件
<template>
    <div class="hello">
        <button @click="showPopup">点击传值</button> 
    </div>
</template>
  
<script>
import Bus from '@/meaasge/Bus';
export default {
    name: 'HelloWorld',
    data() {
        return {
            show: false
        }
    },
    methods: {
        showPopup() {
            Bus.$emit('getData', this.show)
        }
    }
}
</script>
  

2.Mitt传值(Vue3)

安装:npm install mitt -S
main.ts挂载全局

//main.ts
import { createApp } from 'vue'
import App from './App.vue'
import mitt from 'mitt'
 
const Mit = mitt()
 
//TypeScript注册
// 由于必须要拓展ComponentCustomProperties类型才能获得类型提示
declare module "vue" {
    export interface ComponentCustomProperties {
        $Bus: typeof Mit
    }
}
 
const app = createApp(App)
 
//Vue3挂载全局API
app.config.globalProperties.$Bus = Mit
 
app.mount('#app')
//A.vue子组件
<template>
    <div>
        <h1>我是A</h1>
        <button @click="emit1">emit1</button>
        <button @click="emit2">emit2</button>
    </div>
</template>
 
<script setup lang='ts'>
import { getCurrentInstance } from 'vue'
const instance = getCurrentInstance();
const emit1 = () => {
    instance?.proxy?.$Bus.emit('on-num', 100)
}
const emit2 = () => {
    instance?.proxy?.$Bus.emit('*****', 500)
}
</script>
 
//B.vue子组件
<template>
    <div>
        <h1>我是B</h1>
    </div>
</template>
 
<script setup lang='ts'>
 
import { getCurrentInstance } from 'vue'
const instance = getCurrentInstance()
instance?.proxy?.$Bus.on('on-num', (num) => {
    console.log(num,'===========>B')
})
 
//多个事件:监听所有事件
instance?.proxy?.$Bus.on('*',(type,num)=>{
    console.log(type,num,'===========>B')
})
</script>

三、祖孙间传值

1、在父组件中的孙组件上v-bind=“ a t t r s " 传递给孙组件数据 2 、在父组件中的孙组件上 v − o n = " attrs" 传递给孙组件数据 2、在父组件中的孙组件上v-on=" attrs"传递给孙组件数据2、在父组件中的孙组件上von="listeners"传递给祖组件数据
3、v-bind在vue中是”:“,v-on是”@"

//祖组件
<template>
    <section>
        <parent :name="grandParent" firstName="吴" sex="男" age="88" hobby="code" @sayKnow="sayKnow"></parent>
    </section>
</template>

<script>
    import Parent from './Father.vue'
    export default {
        name: "GrandParent",
        components: {
          Parent
        },
        data() {
            return {
              grandParent:'啦啦啦'
            }
        },
        methods: {
          sayKnow(val){
            console.log(val)
          }
        },
        mounted() {
        }
    }
</script>

//父组件
<template>
  <section>
    <p>父组件收到</p>
    <p>祖父的名字:{{ name }}{{ firstName }}</p>
    <children v-bind="$attrs" v-on="$listeners"></children>
  </section>
</template>

<script>
import Children from './son.vue'

export default {
  name: "Parent",
  components: {
    Children
  },
  // 父组件接收了name,所以name值是不会传到子组件的
  props: ['name', 'firstName'],
  data() {
    return {}
  },
  methods: {},
  mounted() {
    console.log(this.firstName);
  }
}
</script>

//孙组件
<template>
    <section>
      <p>子组件收到</p>
      <p>祖父的名字:{{name}}</p>
      <p>祖父的性别:{{sex}}</p>
      <p>祖父的年龄:{{age}}</p>
      <p>祖父的爱好:{{hobby}}</p>
  
      <button @click="sayKnow">点击传给祖父</button>
    </section>
  </template>
  
  <script>
    export default {
      name: "Children",
      components: {},
      // 由于父组件已经接收了name属性,所以name不会传到子组件了
      props:['sex','age','hobby','name'],
      data() {
        return {
         flag:'我来自孙组件'
        }
      },
      methods: {
        sayKnow(){
          this.$emit('sayKnow',this.flag)
        }
      },
      mounted() {
      }
    }
  </script>
  
  

  • 29
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值