Vue 组件传参 prop向下传递、emit向上传递

发布时间:2023年12月21日

组件传参


学习了组件用法,就像一种嵌套引用关系,在这个关系中,经常会涉及相互传数据的需求,即父组件传子组件,子组件传父组件。

父、子组件的关系可以总结为 : prop 向下传递(和事件无关), emit 事件(包含事件)向上传递。
如下图所示: 所有的组件组成了完整的页面,但是组件里里面的数据与组件之间的数据是相互进行数据传递的。( 组件之间存在着相互引用,这就存在了父子关系

有时候子组件页面的展示,展示什么样的内容是由父组件决定的,这时候父组件给子组件传参的时候就需要通过参数告诉子组件需要展示什么样的内容。

父组件里面:<HelloWorld msg="Welcome to Your Vue.js App"/>
--------------------------------------------------------------------
子组件里面:
<script>
export default {
  name: 'HelloWorld',
//父组件App.vue传给子组件HelloWorld的数据
//谁使用了这个页面就给这个组件传值
  props: {
    msg: String
  }
}
</script>

//然后将要传递的值放在template里面的h1里面去做展示
<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
  </div>
</template>

HelloWorld这个组件(页面),它的标题是由父组件App.vue来决定内容的。

 <HelloWorld msg="父亲组件App 子组件HelloWorld"/>

?

?

?

?props向下传递


先去子组件里面定义props,在props里面定义要向下传递的数据content。

<template>
    <div>
        <button type="button" @click="btn()">TestVue</button><br>
        {{ content }}
    </div>    
</template>


<script>
//这里不使用vue2的语法
export default ({
    //定义父组件传递给子组件的数据,属性名字为content,类型为string
    data() {
        return{
        }
    },
    methods:{
        //在js当中使用props数据
        btn(){
            alert("content内容为:" + this.content)
        }
    },
    props:{
        content: String,
    }
})
</script>

然后去父亲组件里面定义要传递的数据。?

<template>
  <img alt="Vue logo" src="./assets/logo.png">
  <Test content="父亲组件App 子组件Test"></Test>
  <HelloWorld msg="父亲组件App 子组件HelloWorld"/>
</template>

上面就是父传子的一个方式,有点像定义了一个标签,然后将属性传递进去,这个属性在子组件里面可以放在模板里面使用或者放在script里面使用,都行。

v-bind的方式传参:这样可以通过动态绑定的方式传递进去,子组件可以使用父组件的数据,相当于子组件就是父组件里面的html标签

<template>
    <div>
        <button type="button" @click="btn()">TestVue</button><br>
        {{ content }}<br> 
        {{ name }}
    </div>    
</template>


<script>
//这里不使用vue2的语法
export default ({
    //定义父组件传递给子组件的数据,属性名字为content,类型为string
    data() {
        return{

        }
    },
    methods:{
        //在js当中使用props数据
        btn(){
            alert("content内容为:" + this.content + this.name)
        }
    },
    props:{
        content: String,
        name: String
    }
})
</script>


<template>
  <img alt="Vue logo" src="./assets/logo.png">

//这里使用v-bind使用父组件的数据
  <Test :name="AppName" content="父亲组件App 子组件Test"></Test>

  <HelloWorld  msg="父亲组件App 子组件HelloWorld" />
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'

export default {
  name: 'App',
  components: {
    HelloWorld
  },
  data(){
    return{
      AppName: "lucas"
    }
  }
}
</script>

?

?

emit子传父


如果子组件里面的数据发生了变化,父组件要拿到变化的数据,这怎么办?在子组件里面定义好emit事件名称,在父组件里面使用v-on进行接收。接受的是一个方法,方法并且不能使用括号。

这里的事件名称自定义即可。之前大部分事件都是内置的click keybord:enter这种事件,现在可以在子组件里面去定义自己的事件了。

如果你要监听很多数据,可以将这些数据放在一个对象里面统一做处理。

<template>
    <div>
        <button type="button" @click="btn()">子传父按钮</button><br>
    </div>    
</template>


<script>
//这里不使用vue2的语法
export default ({
    //定义父组件传递给子组件的数据,属性名字为content,类型为string
    data() {
        return{

        }
    },
    methods:{
        //在js当中使用props数据
        btn(){
            //vue自带的emit事件,将数据传递给父组件
            //第一个参数是事件名,第二个参数是数据名称
            this.$emit('childEvent',"子组件事件childEvent传来的数据")
        }
    },
    props:{

    }
})
</script>

?父组件

<template>
  <img alt="Vue logo" src="./assets/logo.png">
  <!--监听子组件childEvent事件,绑定receive方法接受子组件传过来的参数,
    然后就是赋值操作,赋值完之后在模板里面显示
  -->
  <Test @childEvent="receive"></Test><br>
  <p style="color:brown">子组件Test传来的数据:{{ TestMsg }}</p>
  <HelloWorld  msg="父亲组件App 子组件HelloWorld" />
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'

export default {
  name: 'App',
  components: {
    HelloWorld
  },
  data(){
    return{
      TestMsg: ''
    }
  },
  methods:{
    receive(data){
      alert(data)
      this.TestMsg = data
    }
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>
文章来源:https://blog.csdn.net/qq_34556414/article/details/135123760
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。