Vue组件参数传递问题

Vue组件参数传递问题

组件中的data为什么是函数?

组件中的数据是保存在哪里呢?顶层的Vue实例中吗?并不是的,组件无法访问Vue实例中的data。即使可以访问,如果所有组件的数据都在顶级Vue实例中,那么Vue中的data会十分的臃肿。组件中的数据应该由自己管理。

组件是一个单独功能模块的封装,这个模块有属于自己的HTML模板,也应该有属于自己的数据data,不过这个data是一个函数。这是为什么呢?

这是为了保证组件复用时,属性之间的隔离。利用方法都会重新开辟内存空间的机制。当创建多个相同组件实例时,不同组件实例之间的data必须保证不被共享

父子组件通讯之props(父->子)

需求1:在页面中,父组件请求得到的数据需要在子组件中展示。

需求2:子组件很多,每次创建都要向后他发送数据,在父组件中进行请求,将数据传递给子组件展示。

Vue中提供了props用于父组件向子组件中传递数据

在子组件中,使用props声明需要从父级接收到的数据

props的值有两种方式:

  • 方式一:字符串数组,数组中的字符串就是传递时的属性名称。
  • 方式二:对象,对象可以设置传递时的类型,也可以设置默认值等。

数组形式的传递

1、在父组件中创建数据

  data() {
    return {
      userId: "rayfoo",
      name:'rayfoo',
      hobby: ['抽烟','喝酒','烫头']
    };
  }

2、在子组件中创建props

props: ['name','hobby']

3、在子组件中使用属性

<h2 v-text="name"></h2>

4、在父组件中导入并使用子组件

import News from "./views/home/news";


  components: {
    News
  }

    <News :name="name" />

对象形式的传递

对象参数的传递需要指定对象类数据类型、[默认值]、[是否必传]等参数

支持的类型类型

  • String
  • Number
  • Boolean
  • Object
  • Data
  • Function
  • Symbol
props:{
        title:{
            //数据类型 参数可以指定多个[String,Number,...]
            type: String,
            //默认值,在没有引入传递参数时渲染
            default: 'Message',
            //是否为必传参数
            required: false
        },
   		 hobby:{
            type: Array,
            default: function(){
                return ['抽烟','喝酒']
            }
        }
    }

需要注意的时,当类型如果是Object或者Array,默认值必须是一个函数。

子组件向父组件传递数据

子组件中配置事件发送:

template:

<button @click="giveAdvice">我是一个小按钮</button>

methods:

methods: {
        giveAdvice: function(){
            this.$emit('give-advice',this.title);
        }
    }

父组件中监听

template:

<News :name="name" @give-advice="showAdvice" />

methods:

showAdvice: function (advice) {
      alert(advice)
    }

需要注意的是,事件如果传递的是驼峰式,需要使用下划线形式发射。具体的操作可以参考官方API

https://cn.vuejs.org/v2/api/#vm-emit

参数同步问题

如果父子间传递的参数需要实时的进行双向绑定,该如何做?

如果修改了props中的值,父组件中的内容不会修改。Vue不推荐在子组件中直接修改props的值。

如果需要修改props中的值,可以在子组件中创建一个data或者computed副本

使用@input事件实现双向绑定

子组件代码:

1、在子组件中声明props,由父组件传递。

2、创建props的副本,当props的副本

3、使用v-model绑定props副本的值

4、监听控件的@input,当值发生改变,修改参数值,并且将值弹回父组件

<template>
    <div name='chidren'>
        <h1 v-text="title"></h1>
        <p v-text="info"></p>
        <input type="text" v-model="dparam" @input="valChange">
        <button @click="giao">发射属性到父组件</button>
    </div>
</template>

<script>
export default {
    name: 'chidren',
    props: {
        title: String,
        info: String
    },
    data(){
        return{
            param: 'GIAO',
            dparam: this.title
        }
    },
    methods:{
        giao: function(){
            this.$emit('giao',this.param);
        },
        valChange: function(event){
            let newVal = event.target.value;
            this.param = newVal;
            this.$emit('title-change',newVal);
        }
    }/*,
    watch:{
        dparam(oldVal,newVal){
            this.param = newVal;
            this.$emit('title-change',newVal);
        }
    }*/
}
</script>

<style>

</style>

父组件代码

父组件中可以直接使用v-model来修改子组件中属性

<template>
    <div name="parent">
        <h1 v-text="title"></h1>
        <input type="text" v-model="title">
        <Childred @giao="giao" @title-change="titleChange" :title="title" :info="info"></Childred>
    </div>
</template>

<script>
import Childred from './Chidren';
export default {
    name: 'parent',
    data(){
        return {
            title: 'rayfoo',
            info: '真帅'
        }
    },
    methods:{
        giao: function(param){
            alert(param);
        },
        titleChange:function(newVal){
            this.title = newVal;
        }
    },
    components:{
        Childred
    }
}
</script>

<style>

</style>

如果数据类型不是String,可能要牵涉一些类型转换问题。

使用watch进行子父组件双向绑定

略。。。

父组件中取得子组件的对象

$children-不常用

上面的案例中我们已经成功的在父组件中取得子组件的属性,也可以从子组件中拿到父组件的属性,下面介绍一个更加简单的操作形式-从父组件中拿到子组件对象。

在父组件中,可以使用:this.\(children[index].属性名、this.\)children[index].方法名来获取子组件内的属性和方法,但是在开发过程中一般不会使用这样的形式,因为其依赖下标,有很多的不确定性。

btnClick: function(){
            console.log(this.$children[0].param);
            this.$children[0].showInfo();
        }

$refs-常用

可以在引用子组件的位置给子组件指定一个ref属性,例如ref='aaa'

此时,this.\(refs.aaa就是子组件对象,就可以在父组件中使用this.\)refs.aaa来访问子组件啦~

btnClick: function(){
            console.log(this.$refs.child.param);
        }

子组件中访问父组件对象

$parent不常用

在子组件中可以直接使用$parent来访问父组件中的内容,但是在子组件中频繁父组件中的内容,会使得组件的耦合度非常的高,所以开发过程中不常用。

        btnClick: function(){
            console.log(this.$parent.title);
        }

$root

使用$root可以获取根组件中的内容

btnClick: function(){
            console.log(this.$root.title);
        }
posted @ 2020-07-28 20:54  张瑞丰  阅读(4101)  评论(0编辑  收藏  举报