Vue.js Vue JS将数据从父级传递到子级的子级

Vue.js Vue JS将数据从父级传递到子级的子级,vue.js,state,vue-props,Vue.js,State,Vue Props,在Vue.js中,如何正确地将数据从父组件传递到多层子组件链?您有几个选项: 在这里了解更多信息:@RoboKozo为您列出了一些非常好的选择,这取决于您对数据的处理方式 如果是静态数据(并且您喜欢模块化),那么您可以始终使用mixin 从Vue.js文档: mixin是为Vue组件分发可重用功能的一种灵活方式。mixin对象可以包含任何组件选项。当组件使用mixin时,mixin中的所有选项都将“混合”到组件自己的选项中 示例1:混合 文件/文件夹设置: /src/mixins/def

在Vue.js中,如何正确地将数据从父组件传递到多层子组件链?

您有几个选项:


  • 在这里了解更多信息:

    @RoboKozo为您列出了一些非常好的选择,这取决于您对数据的处理方式

    如果是静态数据(并且您喜欢模块化),那么您可以始终使用mixin

    从Vue.js文档:

    mixin是为Vue组件分发可重用功能的一种灵活方式。mixin对象可以包含任何组件选项。当组件使用mixin时,mixin中的所有选项都将“混合”到组件自己的选项中

    示例1:混合 文件/文件夹设置:

    /src/mixins/defaultDataMixin.js // Call this whatever you want
    
    export const default defaultData {
        data() {
            return {
                property1: "Foo",
                property2: "Bar"
            }
        }
    }; 
    
    /src/mixins/defaultDataMixin.js:

    /src/mixins/defaultDataMixin.js // Call this whatever you want
    
    export const default defaultData {
        data() {
            return {
                property1: "Foo",
                property2: "Bar"
            }
        }
    }; 
    
    现在,在您想要访问
    property1
    property2
    的任何组件上,您只需导入mixin即可

    /src/pages/MyComponent.vue

    <template>
        <div id="wrapper">
            <div class="container">
                <div class="row">
                    <div class="col">
                        {{ property1 }}
                    </div>
                    <div class="col">
                        {{ property2 }}
                    </div>
                </div>
            </div>
        </div>
    </template>
    <script>
    import { defaultData } from "@/mixins/defaultDataMixin"
    
    export default {
        mixins: [defaultData],
    }
    </script>
    
    <template>
        <div id="wrapper">
            <div class="container">
                <div class="row">
                    <div class="col">
                        <child-component :defaultDataProp="defaultData" @emitted-text="helloWorld">
                        </child-component>
                    </div>
                </div>
            </div>
        </div>
    </template>
    <script>
    import { defaultData } from "@/mixins/defaultDataMixin"
    import ChildComponent from "@/components/ChildComponent.vue"
    
    export default {
        mixins: [defaultData],
        components: {
            ChildComponent
        },
        data() {
            return {
                emittedText: "",
            }
        },
        methods: {
            helloWorld(e){
                this.emittedText = e;
            }
        }
    }
    </script>
    
    <template>
        <div id="wrapper">
            <div class="container">
                <div class="row">
                    <div class="col">
                        {{ defaultDataProp }}
                    </div>
                </div>
                <div class="row">
                    <div class="col">
                        <button @click="emitData">Emit Data</button>
                    </col>
                </div>
            </div>
        </div>
    </template>
    <script>
    export default {
        props: {
            defaultDataProp: {
                type: String
            }
        },
        data() {
            return {
                text: "Hello, world!"
            };
        },
        methods: {
            emitData() {
                this.$emit('emitted-text', this.text);
            }
        }
    }
    </script>
    
    <template>
        <div id="wrapper">
            <div class="container">
                <div class="row">
                    <div class="col" v-if="firstName != ''">
                        {{ firstName }}
                    </div>
                    <div class="col">
                        <button @click="mutateState">Click Me</button>
                    </div>
                </div>
                <div class="row">
                    <div class="col">
                        <child-component @emitted-text="helloWorld">
                        </child-component>
                    </div>
                </div>
            </div>
         </div>
    </template>
    <script>
    import { defaultData } from "@/mixins/defaultDataMixin"
    import ChildComponent from "@/components/ChildComponent.vue"
    export default {
        mixins: [defaultData],
        components: {
            ChildComponent
        },
        methods: {
            // our new method to mutate the user state 
            mutateState() {
                this.$store.dispatch("loadUser");
            },
            helloWorld(e){
                this.emittedText = e;
            }
        }
    }
    </script>
    
    <template>
        <div id="wrapper">
            <div class="container">
                <div class="row">
                    <div class="col">
                        {{ defaultData }}
                    </div>
                </div>
                <div class="row">
                    <div class="col">
                        <button @click="emitData">Emit Data</button>
                    </col>
                </div>
            </div>
        </div>
    </template>
    <script>
    import { defaultData } from "@/mixins/defaultDataMixin"
    
    export default {
        mixins: [defaultData],
       
        data() {
            return {
                text: "Hello, world!"
            };
        },
        methods: {
            emitData() {
                this.$emit('emitted-text', this.text);
            }
        },
        // Let's watch for the user state to change 
        watch: {
            firstName(newValue, oldValue) {
                console.log('[state] firstName state changed to: ', newValue);
                // Do whatever you want with that information 
            }
        }
    }
    </script>
    
    ParentComponent.vue

    <template>
        <div id="wrapper">
            <div class="container">
                <div class="row">
                    <div class="col">
                        {{ property1 }}
                    </div>
                    <div class="col">
                        {{ property2 }}
                    </div>
                </div>
            </div>
        </div>
    </template>
    <script>
    import { defaultData } from "@/mixins/defaultDataMixin"
    
    export default {
        mixins: [defaultData],
    }
    </script>
    
    <template>
        <div id="wrapper">
            <div class="container">
                <div class="row">
                    <div class="col">
                        <child-component :defaultDataProp="defaultData" @emitted-text="helloWorld">
                        </child-component>
                    </div>
                </div>
            </div>
        </div>
    </template>
    <script>
    import { defaultData } from "@/mixins/defaultDataMixin"
    import ChildComponent from "@/components/ChildComponent.vue"
    
    export default {
        mixins: [defaultData],
        components: {
            ChildComponent
        },
        data() {
            return {
                emittedText: "",
            }
        },
        methods: {
            helloWorld(e){
                this.emittedText = e;
            }
        }
    }
    </script>
    
    <template>
        <div id="wrapper">
            <div class="container">
                <div class="row">
                    <div class="col">
                        {{ defaultDataProp }}
                    </div>
                </div>
                <div class="row">
                    <div class="col">
                        <button @click="emitData">Emit Data</button>
                    </col>
                </div>
            </div>
        </div>
    </template>
    <script>
    export default {
        props: {
            defaultDataProp: {
                type: String
            }
        },
        data() {
            return {
                text: "Hello, world!"
            };
        },
        methods: {
            emitData() {
                this.$emit('emitted-text', this.text);
            }
        }
    }
    </script>
    
    <template>
        <div id="wrapper">
            <div class="container">
                <div class="row">
                    <div class="col" v-if="firstName != ''">
                        {{ firstName }}
                    </div>
                    <div class="col">
                        <button @click="mutateState">Click Me</button>
                    </div>
                </div>
                <div class="row">
                    <div class="col">
                        <child-component @emitted-text="helloWorld">
                        </child-component>
                    </div>
                </div>
            </div>
         </div>
    </template>
    <script>
    import { defaultData } from "@/mixins/defaultDataMixin"
    import ChildComponent from "@/components/ChildComponent.vue"
    export default {
        mixins: [defaultData],
        components: {
            ChildComponent
        },
        methods: {
            // our new method to mutate the user state 
            mutateState() {
                this.$store.dispatch("loadUser");
            },
            helloWorld(e){
                this.emittedText = e;
            }
        }
    }
    </script>
    
    <template>
        <div id="wrapper">
            <div class="container">
                <div class="row">
                    <div class="col">
                        {{ defaultData }}
                    </div>
                </div>
                <div class="row">
                    <div class="col">
                        <button @click="emitData">Emit Data</button>
                    </col>
                </div>
            </div>
        </div>
    </template>
    <script>
    import { defaultData } from "@/mixins/defaultDataMixin"
    
    export default {
        mixins: [defaultData],
       
        data() {
            return {
                text: "Hello, world!"
            };
        },
        methods: {
            emitData() {
                this.$emit('emitted-text', this.text);
            }
        },
        // Let's watch for the user state to change 
        watch: {
            firstName(newValue, oldValue) {
                console.log('[state] firstName state changed to: ', newValue);
                // Do whatever you want with that information 
            }
        }
    }
    </script>
    
    main.js

    import Vue from "vue";
    import Vuex from "vuex";
    import { store } from "@/store/store";
    // ... add whatever else you need to import and use
    
    Vue.use(vuex); // but make sure Vue uses vuex
    
    // Vue can "inject" the store into all child components
    new Vue({
        el: "#app",
        store: store, // <-- provide the store to the vue instance
        // ..
    });
    
    import Vue from "vue";
    import Vuex from "vuex";
    import userModule from "@/store/modules/user"; // Grab our newly created module
    
    Vue.use(Vuex);
    
    export const store = new Vuex.Store({
      modules: {
        userState: userModule,
      },
    });
    
    import { mapGetters } from "vuex";
    
    export const default defaultData {
        data() {
            return {
                property1: "Foo",
                property2: "Bar"
            }
        },
        // We can make use of mapGetters here 
        computed: {
            ...mapGetters(["firstName"]),
        }
    }; 
    
    api.js

    /.env 
    /src/main.js
    /src/store/store.js
    /src/store/modules/user.js
    /src/mixins/defaultDataMixin.js
    /src/util/api.js
    /src/pages/ParentComponent.vue
    /src/components/ChildComponent.vue
    
    VUE_APP_API_URL='http://127.0.0.1:8000'
    
    import axios from "axios";
    import { store } from "@/store/store";
    
    const apiClient = axios.create({
      baseURL: process.env.VUE_APP_API_URL,
    });
    
    export default apiClient;
    
    import apiClient from "@/util/api"
    import { store } from "../store"
    
    const userModule = {
        state: () => ({
            user: {
                firstName: "",
            }
        }),
        mutations: {
            setUser(state, payload) {
                state.user = payload;
            }
        },
        actions: {
            async loadUser({ commit, dispatch }) {
                try {
                    const user = (await apiClient.get("/user")).data;
                    commit("setUser", user); // mutate the vuex state
                } catch (error) {
                    dispatch("logout");
                }
            },
            logout({ commit }) {
                commit("setUser", {});
            }
        },
        getters: {
            firstName: (state) => {
                return state.user.firstName;
            }
        }
       
    };
    
    export default userModule;
    
    user.js

    /.env 
    /src/main.js
    /src/store/store.js
    /src/store/modules/user.js
    /src/mixins/defaultDataMixin.js
    /src/util/api.js
    /src/pages/ParentComponent.vue
    /src/components/ChildComponent.vue
    
    VUE_APP_API_URL='http://127.0.0.1:8000'
    
    import axios from "axios";
    import { store } from "@/store/store";
    
    const apiClient = axios.create({
      baseURL: process.env.VUE_APP_API_URL,
    });
    
    export default apiClient;
    
    import apiClient from "@/util/api"
    import { store } from "../store"
    
    const userModule = {
        state: () => ({
            user: {
                firstName: "",
            }
        }),
        mutations: {
            setUser(state, payload) {
                state.user = payload;
            }
        },
        actions: {
            async loadUser({ commit, dispatch }) {
                try {
                    const user = (await apiClient.get("/user")).data;
                    commit("setUser", user); // mutate the vuex state
                } catch (error) {
                    dispatch("logout");
                }
            },
            logout({ commit }) {
                commit("setUser", {});
            }
        },
        getters: {
            firstName: (state) => {
                return state.user.firstName;
            }
        }
       
    };
    
    export default userModule;
    
    store.js

    import Vue from "vue";
    import Vuex from "vuex";
    import { store } from "@/store/store";
    // ... add whatever else you need to import and use
    
    Vue.use(vuex); // but make sure Vue uses vuex
    
    // Vue can "inject" the store into all child components
    new Vue({
        el: "#app",
        store: store, // <-- provide the store to the vue instance
        // ..
    });
    
    import Vue from "vue";
    import Vuex from "vuex";
    import userModule from "@/store/modules/user"; // Grab our newly created module
    
    Vue.use(Vuex);
    
    export const store = new Vuex.Store({
      modules: {
        userState: userModule,
      },
    });
    
    import { mapGetters } from "vuex";
    
    export const default defaultData {
        data() {
            return {
                property1: "Foo",
                property2: "Bar"
            }
        },
        // We can make use of mapGetters here 
        computed: {
            ...mapGetters(["firstName"]),
        }
    }; 
    
    defaultDataMixin.js

    import Vue from "vue";
    import Vuex from "vuex";
    import { store } from "@/store/store";
    // ... add whatever else you need to import and use
    
    Vue.use(vuex); // but make sure Vue uses vuex
    
    // Vue can "inject" the store into all child components
    new Vue({
        el: "#app",
        store: store, // <-- provide the store to the vue instance
        // ..
    });
    
    import Vue from "vue";
    import Vuex from "vuex";
    import userModule from "@/store/modules/user"; // Grab our newly created module
    
    Vue.use(Vuex);
    
    export const store = new Vuex.Store({
      modules: {
        userState: userModule,
      },
    });
    
    import { mapGetters } from "vuex";
    
    export const default defaultData {
        data() {
            return {
                property1: "Foo",
                property2: "Bar"
            }
        },
        // We can make use of mapGetters here 
        computed: {
            ...mapGetters(["firstName"]),
        }
    }; 
    
    现在,父级和子级都可以访问集中式状态,并可以对其进行变异。例如,让我们从父组件调用
    loadUser()
    ,并观察子组件上的状态更改

    ParentComponent.vue

    <template>
        <div id="wrapper">
            <div class="container">
                <div class="row">
                    <div class="col">
                        {{ property1 }}
                    </div>
                    <div class="col">
                        {{ property2 }}
                    </div>
                </div>
            </div>
        </div>
    </template>
    <script>
    import { defaultData } from "@/mixins/defaultDataMixin"
    
    export default {
        mixins: [defaultData],
    }
    </script>
    
    <template>
        <div id="wrapper">
            <div class="container">
                <div class="row">
                    <div class="col">
                        <child-component :defaultDataProp="defaultData" @emitted-text="helloWorld">
                        </child-component>
                    </div>
                </div>
            </div>
        </div>
    </template>
    <script>
    import { defaultData } from "@/mixins/defaultDataMixin"
    import ChildComponent from "@/components/ChildComponent.vue"
    
    export default {
        mixins: [defaultData],
        components: {
            ChildComponent
        },
        data() {
            return {
                emittedText: "",
            }
        },
        methods: {
            helloWorld(e){
                this.emittedText = e;
            }
        }
    }
    </script>
    
    <template>
        <div id="wrapper">
            <div class="container">
                <div class="row">
                    <div class="col">
                        {{ defaultDataProp }}
                    </div>
                </div>
                <div class="row">
                    <div class="col">
                        <button @click="emitData">Emit Data</button>
                    </col>
                </div>
            </div>
        </div>
    </template>
    <script>
    export default {
        props: {
            defaultDataProp: {
                type: String
            }
        },
        data() {
            return {
                text: "Hello, world!"
            };
        },
        methods: {
            emitData() {
                this.$emit('emitted-text', this.text);
            }
        }
    }
    </script>
    
    <template>
        <div id="wrapper">
            <div class="container">
                <div class="row">
                    <div class="col" v-if="firstName != ''">
                        {{ firstName }}
                    </div>
                    <div class="col">
                        <button @click="mutateState">Click Me</button>
                    </div>
                </div>
                <div class="row">
                    <div class="col">
                        <child-component @emitted-text="helloWorld">
                        </child-component>
                    </div>
                </div>
            </div>
         </div>
    </template>
    <script>
    import { defaultData } from "@/mixins/defaultDataMixin"
    import ChildComponent from "@/components/ChildComponent.vue"
    export default {
        mixins: [defaultData],
        components: {
            ChildComponent
        },
        methods: {
            // our new method to mutate the user state 
            mutateState() {
                this.$store.dispatch("loadUser");
            },
            helloWorld(e){
                this.emittedText = e;
            }
        }
    }
    </script>
    
    <template>
        <div id="wrapper">
            <div class="container">
                <div class="row">
                    <div class="col">
                        {{ defaultData }}
                    </div>
                </div>
                <div class="row">
                    <div class="col">
                        <button @click="emitData">Emit Data</button>
                    </col>
                </div>
            </div>
        </div>
    </template>
    <script>
    import { defaultData } from "@/mixins/defaultDataMixin"
    
    export default {
        mixins: [defaultData],
       
        data() {
            return {
                text: "Hello, world!"
            };
        },
        methods: {
            emitData() {
                this.$emit('emitted-text', this.text);
            }
        },
        // Let's watch for the user state to change 
        watch: {
            firstName(newValue, oldValue) {
                console.log('[state] firstName state changed to: ', newValue);
                // Do whatever you want with that information 
            }
        }
    }
    </script>
    
    
    {{firstName}}
    点击我
    从“@/mixins/defaultDataMixin”导入{defaultData}
    从“@/components/ChildComponent.vue”导入ChildComponent
    导出默认值{
    mixins:[defaultData],
    组成部分:{
    子组件
    },
    方法:{
    //我们改变用户状态的新方法
    (){
    此.$store.dispatch(“loadUser”);
    },
    helloWorld(东){
    this.emittedText=e;
    }
    }
    }
    
    ChildComponent.vue

    <template>
        <div id="wrapper">
            <div class="container">
                <div class="row">
                    <div class="col">
                        {{ property1 }}
                    </div>
                    <div class="col">
                        {{ property2 }}
                    </div>
                </div>
            </div>
        </div>
    </template>
    <script>
    import { defaultData } from "@/mixins/defaultDataMixin"
    
    export default {
        mixins: [defaultData],
    }
    </script>
    
    <template>
        <div id="wrapper">
            <div class="container">
                <div class="row">
                    <div class="col">
                        <child-component :defaultDataProp="defaultData" @emitted-text="helloWorld">
                        </child-component>
                    </div>
                </div>
            </div>
        </div>
    </template>
    <script>
    import { defaultData } from "@/mixins/defaultDataMixin"
    import ChildComponent from "@/components/ChildComponent.vue"
    
    export default {
        mixins: [defaultData],
        components: {
            ChildComponent
        },
        data() {
            return {
                emittedText: "",
            }
        },
        methods: {
            helloWorld(e){
                this.emittedText = e;
            }
        }
    }
    </script>
    
    <template>
        <div id="wrapper">
            <div class="container">
                <div class="row">
                    <div class="col">
                        {{ defaultDataProp }}
                    </div>
                </div>
                <div class="row">
                    <div class="col">
                        <button @click="emitData">Emit Data</button>
                    </col>
                </div>
            </div>
        </div>
    </template>
    <script>
    export default {
        props: {
            defaultDataProp: {
                type: String
            }
        },
        data() {
            return {
                text: "Hello, world!"
            };
        },
        methods: {
            emitData() {
                this.$emit('emitted-text', this.text);
            }
        }
    }
    </script>
    
    <template>
        <div id="wrapper">
            <div class="container">
                <div class="row">
                    <div class="col" v-if="firstName != ''">
                        {{ firstName }}
                    </div>
                    <div class="col">
                        <button @click="mutateState">Click Me</button>
                    </div>
                </div>
                <div class="row">
                    <div class="col">
                        <child-component @emitted-text="helloWorld">
                        </child-component>
                    </div>
                </div>
            </div>
         </div>
    </template>
    <script>
    import { defaultData } from "@/mixins/defaultDataMixin"
    import ChildComponent from "@/components/ChildComponent.vue"
    export default {
        mixins: [defaultData],
        components: {
            ChildComponent
        },
        methods: {
            // our new method to mutate the user state 
            mutateState() {
                this.$store.dispatch("loadUser");
            },
            helloWorld(e){
                this.emittedText = e;
            }
        }
    }
    </script>
    
    <template>
        <div id="wrapper">
            <div class="container">
                <div class="row">
                    <div class="col">
                        {{ defaultData }}
                    </div>
                </div>
                <div class="row">
                    <div class="col">
                        <button @click="emitData">Emit Data</button>
                    </col>
                </div>
            </div>
        </div>
    </template>
    <script>
    import { defaultData } from "@/mixins/defaultDataMixin"
    
    export default {
        mixins: [defaultData],
       
        data() {
            return {
                text: "Hello, world!"
            };
        },
        methods: {
            emitData() {
                this.$emit('emitted-text', this.text);
            }
        },
        // Let's watch for the user state to change 
        watch: {
            firstName(newValue, oldValue) {
                console.log('[state] firstName state changed to: ', newValue);
                // Do whatever you want with that information 
            }
        }
    }
    </script>
    
    
    {{defaultData}}
    发射数据
    从“@/mixins/defaultDataMixin”导入{defaultData}
    导出默认值{
    mixins:[defaultData],
    数据(){
    返回{
    文字:“你好,世界!”
    };
    },
    方法:{
    emitData(){
    this.$emit('emissed-text',this.text);
    }
    },
    //让我们观察一下用户状态的变化
    观察:{
    名字(新值、旧值){
    log(“[state]firstName状态更改为:”,newValue);
    //你想用这些信息做什么就做什么
    }
    }
    }