vue组件传值的技巧

1,332 阅读2分钟

1:父级组件向子级组件传值的方法=>props

//Parent
<template>
    <div id="app">
        <child :title="title" :propObj="propObj"></child>
        <button @click="testProp">点击我</button>
    </div>
</template>

<script>
    import child from "./components/child.vue";

    export default {
        name: 'app',
        components: {
            child
        },
        data() {
            return {
                title:"我是为了给子组件传值用的",
                propObj:{
                    title:"我是对象里面的title属性"
                }
            }
        },
        methods: {
            testProp: async function(){
                this.propObj.title = this.title = await this.title+"测试是否是响应式属性的!!!";
                return {title:this.title};
            }
        },
    }
</script>

//child
<template>
    <div>
        <div>
            {{title}}
        </div>
        <div>
            {{propObj.title}}
        </div>
    </div>
</template>

<script>
    export default {
        name: "child",
        props: {
            title: String,
            propObj: Object
        },
        data() {
            return {}
        }
    }
</script>

我们可以看到,在子组件中使用props定义的对象中,可以在父组件中绑定到 底层的data函数返回的对象中;

2:子组件通过事件与父组件进行数据交互 =》$emit

//parent
<template>
    <div id="app">
        <child :title="title" :propObj="propObj" @clickObjTitle="clickObjTitle"></child>
        <button @click="testProp">点击我</button>
    </div>
</template>

<script>
    import child from "./components/child.vue";

    export default {
        name: 'app',
        components: {
            child
        },
        data() {
            return {
                title:"我是为了给子组件传值用的",
                propObj:{
                    title:"我是对象里面的title属性"
                }
            }
        },
        methods: {
            testProp: async function(){
                this.propObj.title = this.title = await this.title+"122333";
                return {title:this.title};
            },
            clickObjTitle(params){
                console.log(params.count);
            }
        },
    }
</script>
//child
<template>
    <div>
        <div>
            {{title}}
        </div>
        <div @click="clickObjTitle">
            {{propObj.title}}
        </div>
    </div>
</template>

<script>
    export default {
        name: "child",
        props: {
            title: String,
            propObj: Object
        },
        data() {
            return {
                count:0,
            }
        },
        methods:{
            clickObjTitle(){
                //clickObjTitle相当于在父组件中自定义了一个事件,参考node的Event模块;后面的对象是为了给父组件传值
                this.$emit("clickObjTitle",{
                    count:this.count++
                })
            }
        }
    }
</script>
是不是以为传值就这些就完了,NO,还有我们不常用的=》provider/inject
  • 这一对选项是互相依赖的,只有一个并不会起什么作用;
  • 在父级组件中,使用provider,那么在这个父组件的所有子组件,包括孙子组件都将会拿到这个值;
//parent
<template>
  <child></child>
</template>
<script>
import child from "../components/child.vue"
export default {
    name:"parent",
    components:{child},
    provide(){
        return {
            providerData:"old provider"
        }
    },
}
</script>

//child
<template>
    <div>
        {{providerData}}
        <son></son>
    </div>
</template>
<script>
import son from "./son.vue"
export default{
    name:"child",
    components:{son},
    inject:["providerData"]
}

//son
<template>
    <div>
        {{providerData}}
    </div>
</template>
<script>
export default{
    name:"son",
    inject:["providerData"]
}
</script>
再看官网

提示:provide 和 inject 绑定并不是可响应的。这是刻意为之的!!!
what **** ,哪我要你有什么用?身为一个数据驱动页面更新的框架,这不是神坑吗? 接着往下看
vue官网说,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的。 原来如此

<template>
  <div>
    <child></child>
    <button @click="testProvider">测试provider/inject响应式</button>
  </div>
</template>
<script>
import child from "../components/child.vue"
export default {
    name:"parent",
    components:{child},
    provide(){
        return {
            providerData:this.dataProvider//可监听的对象就是在data中可以对数据进行更行的对象;
        }
    },
    data(){
        return {
            dataProvider:{
                data:"我是测试data中provider和inject的"
            }
        }
    },
    methods:{
        testProvider(){
            this.dataProvider.data = "哇,我可以实现响应了";
        }
    }
}
</script>


//child
<template>
    <div>
        <div @click="test">
            {{providerData.data}}
        </div>
    </div>
</template>
<script>
    export default {
        name: "child",
        inject: ['providerData'],
        methods: {
            test() {//一样可以修改;
                this.providerData.data = "在子组件中修改值";
            }
        }
    }
</script>

还有什么?没错就是强大的 Vuex,当我们做一个大型的系统的时候,Vuex无疑是最好的选择,中小型的项目使用上述三种方式就足够用了。