Vue——子级向父级传递参数


这里不考虑ref的使用,通过ref的方式,可以解决大部分问题,但是就和写html一样,不到万不得已你不会使用id,

而且极端场合下,如何给组件设置id,本身就是一个难题。

 

业务场景:

我们设计一个表单组件,需要用户填写年龄,因此有个输入框,我们使用 v-model 绑定年龄字段,
显然,年龄不能超过200,因此组件还必须给出校验位,当年龄超过200,校验位就置成false,
因为校验位是在组件内部凭空产生的,父组件如何获取校验位就成了一个难题。

 

(表单不会只有1个输入框,因此很难设置 ref )

 

方案1:实现v-model

简单的实现方案,就是实现自定义组件的 v-model 功能,缺点就是 v-model 只能绑定一个值。

(当然,这个方案不适合前面提到的案例,你可以考虑绑定一个对象,而不是一个值,因此列为一种解决方案。)

方案2:传递对象

props使用Object类型,父组件将一整个对象传递给子控件,父子组件都可以对参数进行修改、取值。
以下面代码为例,<data-table>组件的参数是一个Object类型,父子组件只要约定好参数中的内容即可。

这或许是最优解了,写法上不会太过另类,而且,Vue也不会阻止子组件修改Object的字段值

 

感觉上,这种做法似乎有些脱离了Vue设计初衷,Vue不会阻止子组件修改Object参数的内容,
同时,Vue 不会主动侦听 Object 字段的变化,最直接的问题,就是页面数据可能不发生联动了,
不过即便不联动,使用watch、computed也能解决问题,办法总比困难多,主要也看编程如何取舍了。

 

<template xmlns="http://www.w3.org/1999/html">
  <data-table :table="table">
  </data-table>
</template>

<script>
    import DataTable from '@/components/widget/DataTable.vue'

    export default {
        components: {
            DataTable
        },
        data() {
            return {
                table: {
                    //分页配置
                    url: undefined
                    , page: 1
                    , limit: 10
                    , enabledSelection: true
                    , resultParser: undefined
                    , data: [{
                        date: '2016-05-02',
                        name: '王小虎',
                        address: '上海市普陀区金沙江路 1518 弄',
                        isDisabled: false,
                        select: 1,
                        image: 'http://www.baidu.com'
                    }]
                }
            }
        }
    }
</script>

 

方案3:使用provide

与方案2基本一致,不过不用props,而是使用provide,也是将一整个对象传递给子控件。

两种做法,应用场景有些不同。 

 

案例:

可以参考 element-ui 的 table 设计,table 和 column 一般会在代码中同时出现,
我们只把数据传递给了 table 组件,但是 column 明显也获取了我们的数据,
我们并没有看到 table 将数据传递给 column。

 

其他人看不到父子组件之间传递参数,但是子组件确确实实获得了父组件的参数,
如果也希望设计这样的组件,这时候就要用到 provide,provide 能起到暗度陈仓的效果,悄悄地就把参数传给了子组件。

父级控件

通过provide,将自己的参数传递到子级控件。

<script>
    import FormInput from './FormInput.vue'

    export default {
        name: "fast-form"
        , provide() {
            return {
                formGroup: this.formGroup
            };
        }
    }      
<script>

 

子级控件

通过inject接收父级传递的参数。

<script>
    export default {
        name: "form-input"
        , inject: ['formGroup']
        , created: function () {
            //给formGroup增加一个事件回调,此处不符合VUE数据单向数据流的设计要求,但是满足普通JS语法
            let currentWidget = this;
            for (let i = 0; i < currentWidget.formGroup.length; i++) {
                if (currentWidget.formGroup[i].name === this.name) {
                    currentWidget.formGroup[i].isValid = function () {
                        return currentWidget.checkFormInputValidity();
                    }
                }
            }
        }, methods: {
            /**
             * 比较当前值是否有效
             */
            checkFormInputValidity: function (value) {
            }
        }
    }        
<script>

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM