Vue 父级子级信息传递

273 阅读1分钟

父级子级信息传递

父级传递数据给子级可以给父级里面引入的子级模块添加自定义标签比如:

父级里面可以这样写

    <template>
    <div>
        <ListNode @click="parentClickEvt" :list="list" v-if='show'/>
    </div>
    </template>
    
    <script>
    import ListNode from './list.vue'
    
    //注册组件
     export default {
        components: {
            ListNode,
        },
        data() {
            return {
                list: Array(10).fill().map((_, i) => {
                    return {id: i, name: 'pgone' + i, count: 1}
                })
            }
        },
</script>
    

子级里面可以这样写

    <template>
    <ul>
        <!-- [vue/require-v-for-key] Elements in iteration expect to have 'v-bind:key' directives. -->
        <li v-for="item in list" :key="item.id">
            {{item.name}} -- {{item.count}}
            <button @click="itemEvt(item)">增加</button>
        </li>
    </ul>
</template>

    <script>
        import Child from './child.vue'

            // 子组件先定义,当前组件需要的属性数据
            props: {
                list: {
                    type: Array,
                    // 设置默认值   
                    // 当数据类型为Object或则Array的时候,必须使用工厂函数返回默认值
                    default: () => ([{id: 0, name: '华为手机', count: 1}])
                }
            },
    </script>

子级被点反馈给父级

这里我们要实现的就是 子级点击了增加数量之后呢,返回给父级,让父级也知道点的是那条数据然后进行数据的修改哦

父级里面可以这样写(给引入的模块添加自定义事件)

    <template>
    <div>
        <ListNode @click="parentClickEvt" :list="list" v-if='show'/>
    </div>
    </template>
    
    <script>
    import ListNode from './list.vue'
    
    //注册组件
     export default {
        components: {
            ListNode,
        },
        data() {
            return {
                list: Array(10).fill().map((_, i) => {
                    return {id: i, name: 'pgone' + i, count: 1}
                })
            }
        },
        methods: {
            // 定义的是自定义事件的回调方法
            parentClickEvt(item) {
                console.log(arguments)
                this.list = this.list.map(it => {
                    // 当遍历到当前数据项的时候,对数量+1
                    if (it.id === item.id) it.count += 1
                    return it
                })
            }
        },
</script>
    

子级里面可以这样写

    <template>
    <ul>
        <!-- [vue/require-v-for-key] Elements in iteration expect to have 'v-bind:key' directives. -->
        <li v-for="item in list" :key="item.id">
            {{item.name}} -- {{item.count}}
            <button @click="itemEvt(item)">增加</button>
        </li>
    </ul>
    </template>

    <script>
        import Child from './child.vue'

            // 子组件先定义,当前组件需要的属性数据
            props: {
                list: {
                    type: Array,
                    // 设置默认值   
                    // 当数据类型为Object或则Array的时候,必须使用工厂函数返回默认值
                    default: () => ([{id: 0, name: 'phone', count: 1}])
                }
            },
            methods: {
            itemEvt(item) {
                // console.log(item)
                // Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. 
                // Instead, use a data or computed property based on the prop's value. Prop being mutated: "list"
                // props 中的数据都是只读的,不能进行修改
                // this.list = this.list.map(it => {
                //     // 当遍历到当前数据项的时候,对数量+1
                //     if (it.id === item.id) it.count += 1
                //     return it
                // })
                // 触发自定义事件 -- 必须使用vue自定义的事件触发方法
                // $emit(event: string, ...args: any[])
                // event: string => 自定义事件名字
                // ...args: any[] => ...[a, b, c] => $emit(事件名, a, b, c)
                // $emit方法第一个参数固定为事件名字,从第二个参数开始都为传递的数据

                // <ListNode @click="parentClickEvt" :list="list" v-if='show'/>
                // @click="parentClickEvt" => click是绑定的事件名字,parentClickEvt是自定义事件的回调函数
                this.$emit('click', item, 'test', 12, false, function() {}, [])
            }
        }
            
    </script>