vue 不使用Vue-CLI 实现兄弟组件通信 props和mitt方法

props

: 主要思想:父组件 == (props)==>子组件1,子组件1拿到值进行渲染。当需要数据传递给兄弟组件2时 ==(事件的触发) ==>父组件接收 ==(props) ==>子组件2

代码:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>清单</title>
    <script src="https://unpkg.com/vue@next"></script>
    <link rel="stylesheet" href="./animate.min.css" />
    <script src="https://unpkg.com/uuid@latest/dist/umd/uuidv4.min.js"></script>

    <style>
         :root {
            --animate-delay: 1.5s;
        }
    </style>
</head>

<body>
    <div id="app"></div>

    <template id="box">
        <div>
            <input type="text" v-model="content"> <button @click="send">提交</button>
            <br>
            <unfinished :listitem="listitem" @hand-complete="handComplete"></unfinished>
            <br>
            <complete :list-complete="listComplete"></complete>
        </div>
    </template>

    <!-- 子组件 已完成 -->
    <template id="complete">
        <div>
            <h3>已完成</h3>
            <br>
            <ul>
                <!-- 动画 -->
                <transition-group enter-active-class="animate__animated animate__rotateInUpLeft" leave-active-class="animate__animated animate__rotateOutDownRight">
                <li v-for="item in listx" :key="item.id">{{item.content}} <button @click="dellist(item)">删除</button></li>
                </transition-group>
            </ul>
            <button @click="alldel()">全部删除</button>
        </div>
    </template>

    <!-- 子组件 未完成 -->
    <template id="unfinished">
        <div>
            <h3 >未完成</h3>
            <br>
            <ul>
                <!-- 动画 -->
                <transition-group enter-active-class="animate__animated animate__rotateInUpLeft" leave-active-class="animate__animated animate__rotateOutDownRight">
                <li v-for="(item,num) in mylistitem" :key = 'num'>{{item.content}} <button @click="hand(item)">完成</button></li>
                </transition-group>

            </ul>
        </div>
    </template>

    <script>
        const {
            toRefs,
            toRef,
            reactive,
            ref,
            unref,
            toRaw,
            computed,
            watchEffect,
            watch,
            onMounted
        } = Vue

        // 子组件 已完成
        let complete = {
            template: '#complete',
            // 声明接收参数的类型
            props: {
                listComplete: Object
            },
            setup(props, context) {
                // 展示的数据
                let listx = reactive([])
                    // 监听数据接收,
                    // 使用watch监听,需要写监听对象,并且监听reactive里面的属性,需要将监听对象写成函数
                watch(() => props.listComplete.id, () => {
                    if (props.listComplete.id) {
                        //另外开辟一个内存空间
                        // let listdemo = {}
                        // listdemo.id = props.listComplete.id
                        // listdemo.content = props.listComplete.content
                        // listx.push(props.listComplete)
                        listx.push(JSON.parse(JSON.stringify(props.listComplete)))
                    }
                    // return list
                })

                // 删除单个数据
                function dellist(data) {
                    listx.splice(listx.indexOf(data), 1)
                }
                // 全部删除
                function alldel() {
                    listx.splice(0)
                }
                return {
                    listx,
                    dellist,
                    alldel
                }
            }
        }

        // 子组件 未完成
        let unfinished = {
            template: '#unfinished',
            // 声明接收参数的类型
            props: {
                listitem: String
            },
            setup(props, context) {
                // 展示的数据
                let mylistitem = reactive([])
                    // 监听props的listitem有没有变化。
                    // watchEffect不需要写监听对象,函数里使用了哪些数据,会自动监听
                watchEffect(() => {
                        if (props.listitem) {
                            let item = {
                                    'id': uuidv4(),
                                    'content': props.listitem
                                }
                                // 添加接收的数据
                            mylistitem.push(item)
                        }
                    })
                    // 向父组件传递 已完成数据
                function hand(item) {
                    // 触发事件,传递参数
                    context.emit('hand-complete', item)
                        // 删除已完成数据
                    mylistitem.splice(mylistitem.indexOf(item), 1)
                }
                return {
                    mylistitem,
                    hand
                }
            }
        }

        // 父组件
        let app = Vue.createApp({
            template: '#box',
            components: {
                complete,
                unfinished
            },
            setup() {
                // v-model绑定的值
                let content = ref('');
                // v-bind绑定的值,传递给 未完成子组件的值 传递字符串 id在子组件上加
                let listitem = ref('');
                // v-bind绑定的值,传递给 完成子组件的值 传递对象,id也要一并穿
                let listComplete = reactive({});
                // 添加发送到 未完成组件
                function send() {
                    listitem.value = ''
                    listitem.value = content.value
                        // 发送后清空输入框
                    content.value = ''
                }
                //接收 未完成组件,传递过来,已完成的数据.复制后,子元素会接收到
                function handComplete(data) {
                    // 存id
                    listComplete.id = data.id;
                    // 存值
                    listComplete.content = data.content;
                }

                return {
                    content,
                    listitem,
                    send,
                    handComplete,
                    listComplete
                }
            }
        })


        app.mount('#app')
    </script>
</body>

</html>

mitt

主要思想:传递参数的一方 mitt.emit( ’ 事件名 ’ , 传递的数据)。接收参数的一方 mitt.on(’ 事件名 ’ , (数据)=>{ 对数据进行处理 } )

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>清单</title>
    <script src="https://unpkg.com/vue@next"></script>
    <link rel="stylesheet" href="./animate.min.css" />
    <script src="https://unpkg.com/mitt/dist/mitt.umd.js"></script>
    <script src="https://unpkg.com/uuid@latest/dist/umd/uuidv4.min.js"></script>
    <style>
         :root {
            --animate-delay: 1.5s;
        }
    </style>
</head>

<body>
    <div id="app"></div>

    <template id="box">
        <div>
            <input type="text" v-model="content"> <button @click="send">提交</button>
            <br>
            <unfinished></unfinished>
            <br>
            <complete></complete>
            
        </div>

    </template>

    <!-- 子组件 已完成 -->
    <template id="complete">
        <div>
            <h3 >已完成</h3>
            <br>
            <ul>
                <transition-group enter-active-class="animate__animated animate__rotateInUpLeft" leave-active-class="animate__animated animate__rotateOutDownRight">
                <li v-for="item in doneList" :key="item.id">{{item.text}}<button @click="delDone(item)">删除</button></li>
                </transition-group>
            </ul>
            <button @click="delAll()">全部删除</button>
        </div>
    </template>

    <!-- 子组件 未完成 -->
    <template id="unfinished">
        <div>
            <h3 >未完成</h3>
            <br>
            <ul>
                <transition-group enter-active-class="animate__animated animate__rotateInUpLeft" leave-active-class="animate__animated animate__rotateOutDownRight">
                <li v-for="item in undoneList" :key="item.id">{{item.text}}<button @click="done(item)">完成</button></li>
                </transition-group>

            </ul>
        </div>
    </template>

    <script>
        const mitt = window.mitt()
        const {
            toRefs,
            toRef,
            reactive,
            ref,
            unref,
            toRaw,
            computed,
            watchEffect,
            watch,
            onMounted
        } = Vue

        // 子组件 已完成
        let complete = {
            template: '#complete',
            setup(props, context) {
                // 展示的列表
                let doneList = reactive([])
                    // 绑定事件,接收参数
                mitt.on('done', (obj) => {
                        doneList.push(JSON.parse(JSON.stringify(obj)))
                    })
                    // 删除对应数据
                function delDone(data) {
                    doneList.splice(doneList.indexOf(data), 1)
                }
                // 删除全部数据
                function delAll() {
                    doneList.splice(0)
                }

                return {
                    doneList,
                    delDone,
                    delAll
                }
            }
        }

        //子组件 未完成
        let unfinished = {
            template: '#unfinished',
            setup(props, context) {
                // 展示的列表
                let undoneList = reactive([])
                    // 绑定事件,接收参数
                mitt.on('undone', (obj) => {
                        // 转换指针,避免push后数组数据相同
                        undoneList.push(JSON.parse(JSON.stringify(obj)))
                    })
                    // 完成列表任务
                function done(item) {
                    // 删除对应完成数据
                    undoneList.splice(undoneList.indexOf(item), 1)
                        // 触发事件,传递数据
                    mitt.emit('done', item)
                }
                return {
                    undoneList,
                    done
                }
            }
        }

        // 父组件
        let app = Vue.createApp({
            template: '#box',
            components: {
                complete,
                unfinished
            },
            setup() {
                let content = ref('')

                function send() {
                    mitt.emit('undone', {
                        'id': uuidv4(),
                        'text': content.value
                    })
                    content.value = ''
                }
                return {
                    content,
                    send
                }
            }
        })


        app.mount('#app')
    </script>
</body>

</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值