关于vue-cli组件传值问题

1,288 阅读4分钟

一.组件传值问题分为三大类

1.父子传值,主要用于传递参数

2.子父传值,主要用于触发子组件的点击事件,对父组件的元素产生更改现象

3.非父子组件传值(没有上下级关系),主要用于没有关系的两个组件之间的传值

二.父子传值

原理: 在父组件中使用子组件时,通过自定义属性来进行传值,在子组件中通过props属性来接收父组件传递的数据。(子用父的参数)

(1)首先在父组件中与components同级,创建参数data,注意data是一个函数,而不是一个对象了,因为每个组件都是独立的,互不影响的,所以需要data函数return出来一个新的对象供每个组件使用,返回来讲,就是需要return出来一个新的对象所以data才会是一个函数

(2)其次在父组件中的template的子组件件上绑定一个属性,该属性的属性名为自定义,属性值为data传递的参数名

(3)(父组件)代码:

<template>
    <div>
        <h1>中国新闻</h1>
        <!-- 第三步:使用子组件,并且传递数据 -->
        <my-news :newarr="news"></my-news>
        <p>时间:{{stime|formatTime}}</p>
    </div>
</template>
<script>
<!-- 第一步:引入子组件 -->
import myNews from './news'
export default {
    <!-- 第二步:注册子组件 -->
    components:{
        myNews
    },
    data(){
        return{
            news:[...]
        }
    }
</script>

(4)在子组件的script中,接收父组件传递的数据

props:["在父组件中自定义的属性名"]

(5)注意:这就意味着子组件已经有了参数,参数的名字是”在父组件中自定义的属性名”,这个参数是父组件传递过来的

(6)代码(子组件)

<template>
    <div>
        <!-- 第二步:遍历父组件传递过来的数据 -->
        <div class="item" v-for="(item,index) of newarr" :key="index">
            <p >新闻标题:{{item.title}}</p>
            <p>时间:{{item.time|formatTime}}</p>
        </div>
    </div>
</template>
<script>
export default {
    // 第一步:接收父组件传递的数据
    props:['newarr']
</script>

(7)拿到参数后就可以进行子组件的逻辑了

三.子父传值

(1)原理:自定义事件+$emit

在父组件中使用子组件时,通过自定义事件来传递函数,在子组件中通过$emit('父组件的自定义事件名',传递的参数)来进行触发

(2)首先在子组件中肯定会有个点击按钮(因为子父传值就是触发子组件中的事件操作父组件),在点击按钮上添加点击事件+传参(传参是为了判断点击的是哪个按钮,因为一般多个按钮都是循环遍历出来的)

(3)其次在子组件与props同级处,创建methods,点击事件在methods里面编写逻辑,注意:在methods里面的点击事件函数需要传递形参(该形参是在点击按钮时传递过来的实参 ) (4)在点击事件函数的里面,通过$emit来触发父组件的自定义事件

this.$emit('自定义事件名',参数);

(5)代码:(子组件)

<template>
    <div>
        <div class="item" v-for="(item,index) of newarr" :key="index">
            <p >新闻标题:{{item.title}}</p>
            <p>时间:{{item.time|formatTime}}</p>
            <!-- 第一步:执行子组件的点击事件 -->
            <button @click="newsDel(index)">删除</button>
        </div>
    </div>
</template>
<script>
export default {
    // 接收父组件传递的数据
    props:['newarr'],
    methods:{
        newsDel(i){
            //第二步,通过$emit 触发父组件的自定义事件
            this.$emit('delByNews',i);
        }
    }
}

(6)在父组件中template使用的子组件的标签上,@子定义的自定义事件名=“自定义一个在父组件中事件的名字”

(7)在父组件中的methods中写事件函数,注意;函数需要接收参数,该参数是子组件传递过来,就可以利用该参数来进行逻辑

(8)代码(父组件)

<template>
    <div>
        <h1>中国新闻</h1>
        <!-- 第三步:使用子组件,并且传递数据和自定义事件 -->
        <my-news :newarr="news" @delByNews="del"></my-news>
        <p>时间:{{stime|formatTime}}</p>
    </div>
</template>
<script>
<!-- 第一步:引入子组件 -->
import myNews from './news'
export default {
    <!-- 第二步:注册子组件 -->
    components:{
        myNews
    },
    data(){
        return{
            news:[...]
        }
    },
    methods:{
        del(e){
            this.news.splice(e,1)
        }
    }
</script>

四.非父子组件

1.原理:在main.js里定义一个容器,用来传递数据,在需要发送数据的组件中,通过这个容器来进行数据的发送,在需要接受的组件中,通过这个容器来监听和接收数据。

2.在src目录下的main.js中,设置容器,注意:必须在vue的实例前

Vue.prototype.“自定义一个容器名”= new Vue()
new Vue({
    ...
})

3.需要发送数据的组件

(1)点击事件按钮

(2)在methods中的点击函数将数据发送给接收端

this.”容器名”.$emit('自定义一个名字(该名字是发送端和接收端联系的关键,发送端和接收端这个名字需要一致才能关联上,好比同一个频道)',传递的数据)

(3)代码(需要发送数据的组件)

<template>
    <div>
        <p>第一个组件的数据:{{msg}}</p>
        <button @click="send">发送数据</button>
    </div>
</template>
<script>
export default {
    data(){
        return{
            msg:'异性不存在,唯有代码是真爱'
        }
    },
    methods:{
        send(){
            this.ev.$emit('child1Val',this.msg)
        }
    }
}
</script>

4.需要接收数据的组件, 在生命周期函数的mouted中通过$on监听数据

(1)在与data同级的位置上,创建生命周期函数的mouted,监听

this.”容器名”.$on('频道名',(形参(该形参的实参是发送端传递过来的数据))=>{ 代码逻辑 });

<template>
    <div>
        <h1>这是第二个组件</h1>
        <p>{{str}}</p>
    </div>
</template>
<script>
export default {
    data(){
        return{
            str:''
        }
    },
    mounted(){
        this.ev.$on('child1Val',(e)=>{
            this.str = e
        });
    }
}
</script>