zoukankan      html  css  js  c++  java
  • 子组件以及父子组件之间的传参

    子组件

    栗子:

    需要注意的点都在代码中注释标出来了

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style>
            .wrap {
                 calc(200px * 4 + 80px);
                margin: 0 auto;
                user-select: none;
            }
            .box {
                 200px;
                height: 260px;
                /*border: 1px solid black;*/
                background-color: rgba(10, 200, 30, 0.5);
                border-radius: 10px;
                float: left;
                margin: 10px;
            }
            .box img {
                 100%;
                /*height: 200px;*/
                border-radius: 50%;
            }
            .box p {
                text-align: center;
            }
        </style>
    </head>
    <body>
        <div id="app">
            <div class="wrap">
                <tag></tag> <!-- 可以复用子组件 -->
                <tag></tag>
                <tag></tag>
                <tag></tag>
            </div>
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        //定义了一个子组件
        let titleTag = {
            template: `
            <p>
                <b>
                    这是一种纯二哈
                </b>
            </p>
            `,
        };
    
        let tag = {
            template: `
            <div class="box">
                <img src="img/001.jpg" alt="">
                <title-tag />
                <p @click="fn">
                    锤它:<b>{{ num }}下</b>
                </p>
            </div>
            `,
            // 能被复用的组件(除了根组件),数据都要做局部化处理,因为复用组件后,组件的数据是相互独立的,也就是说每个子组件都有属于自己的数据,不共用。
            // data的值为绑定的方法的返回值,返回值是存放数据的字典,和根组件的data方式不一样。
            data () {
                return {
                    num: 0
                }
            },
            methods: {
                fn() {
                    this.num ++
                }
            },
            //子组件中还能放他的子组件,可以无限的放下去。
            components: {
                titleTag,
            }
        };
    
    	new Vue({
    		el: '#app',
            components: {
    		    tag,
            }
    	});
    
    
    </script>
    </html>
    

    组件标签不能添加系统事件,只能添加自定义事件,自定义事件在组件内部通过$emit主动触发,因为你只能给一个标签加点击事件,而组件标签里面是很多标签,所以不能给组件标签加系统事件,什么是系统事件,就是 @click ,但是你可以给他加上自定义事件,在后面的子组件给父组件传数据的时候会讲。

    组件传参-父传子

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <title>父传子</title>
        <style>
            .wrap {
                 calc(200px * 4 + 80px);
                margin: 0 auto;
                user-select: none;
            }
            .box {
                 200px;
                height: 260px;
                /*border: 1px solid black;*/
                background-color: rgba(10, 200, 30, 0.5);
                border-radius: 10px;
                float: left;
                margin: 10px;
            }
            .box img {
                /* 100%;*/
                height: 160px;
                border-radius: 50%;
                margin: 0 auto;
                display: block;
            }
            .box p {
                text-align: center;
            }
        </style>
    </head>
    <body>
        <div id="app">
            <div class="wrap">
                <tag v-for="dog in dogs" v-bind:dog="dog" :a="1" :b="2" />
            </div>
        </div>
    </body>
        
    <script src="js/vue.js"></script>
    <script>
        let dogs = [
            { title: '二哈1号', img: 'img/1.jpg', },
            { title: '二哈2号', img: 'img/2.jpg', },
            { title: '二哈3号', img: 'img/3.jpg', },
            { title: '二哈4号', img: 'img/4.jpg', },
            { title: '二哈1号', img: 'img/1.jpg', },
            { title: '二哈2号', img: 'img/2.jpg', },
            { title: '二哈3号', img: 'img/3.jpg', },
            { title: '二哈4号', img: 'img/4.jpg', },
        ];
    
        let tag = {
            // 在组件内部就可以通过设置的自定义属性,拿到外部选择子组件提供给属性的值
            props: ['dog', 'a', 'b', 'z'],
            template: `
            <div class="box">
                <img :src="dog.img" alt="">
                <p>
                    <b>
                        {{ dog.title }}
                    </b>
                </p>
                <p @click="fn">
                    锤它:<b>{{ num }}下</b>
                </p>
            </div>
            `,
            data () {
                return {
                    num: 0,
    
                }
            },
            methods: {
                fn() {
                    this.num ++
                }
            },
        };
    
    	new Vue({
    		el: '#app',
            data: {
    		    dogs,
            },
            components: {
    		    tag,
            }
    	});
        /** 总结
         *  1.数据在父组件中产生
         *  2.在父组件中渲染子组件,子组件绑定自定义属性,附上父组件中的数据
         *  3.子组件自定义属性在子组件的props成员中进行声明(采用字符串发射机制)
         *  4.在子组件内部,就可以用props声明的属性(直接作为变量)来使用父组件中的数据
         */
    </script>
    </html>
    

    因为这个dogs的数据是根组件的,要在子组件中被渲染出来,所以是父传子。

    组件传参-子传父

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <title>子传父</title>
        <style>
            ul {
                list-style: none;
            }
            .d-btn {
                font-size: 12px;
                 15px;
                display: inline-block;
            }
            .d-btn:hover {
                color: red;
                cursor: pointer;
            }
        </style>
    </head>
    <body>
        <div id="app">
            <input type="text" v-model="msg">
            <button @click="send_comment">留言</button>
            <ul>
                <tag v-for="(v, i) in comments" :msg="v" :index="i" @f1="deleteMsg"/>
            </ul>
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        let tag = {
            props: ['msg', 'index'],
            template: `
            <li>
                <i class="d-btn" @click="fn">x</i>
                <b>{{ msg }}</b>
            </li>
            `,
            methods: {
                fn () {
                    // 点击子集,要告诉父级删除第几条数据,因为comments在父级中
                    // 需要通知父级
                    // 只要一执行到这句,就会马上通知父级,然后父级就会调用deleteMsg,同时接受你传过去的index
                    this.$emit('f1', this.index);
                }
            }
        };
    
    
        new Vue({
            el: '#app',
            data: {
                msg: '',
                //因为空的数组反序列化会报错,所以要在这里加判断。
                comments: localStorage.comments ? JSON.parse(localStorage.comments) : [],
            },
            components: {
                tag,
            },
            methods: {
                send_comment() {
                    if (this.msg) {
                        this.comments.push(this.msg);
                        this.msg = '';
                        localStorage.comments = JSON.stringify(this.comments);
                    }
                },
                deleteMsg(index) {
                    this.comments.splice(index, 1);
                    localStorage.comments = JSON.stringify(this.comments);
                }
            }
        })
    </script>
    <script>
        // localStorage,sessionStorage不能直接存储数组和对象,需要序列化为json
        localStorage.arr = JSON.stringify([1, 2, 3]);
        let res = JSON.parse(localStorage.arr);
        console.log(res, res[2]);
    </script>
    </html>
    

    vue模板

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
    <div id="app">
        <h1> {{ title }} </h1>
        <!-- 组件标签不能添加系统事件,只能添加自定义事件,自定义事件在组件内部通过$emit主动触发 -->
        <tag @self_action="changeTitle"/>
    </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        let tag = {
            template: `
            <div>
                <input v-model="sub_title" />
            </div>
            `,
            data() {
                return {
                    sub_title: ''
                }
            },
            watch: {
                sub_title() {
                    // 将sub_title与父级的title建立关联
                    // 激活(触发)self_action自定义事件
                    this.$emit('self_action', this.sub_title)
                }
            }
        };
    
        new Vue({
            el: '#app',
            components: {
                tag,
            },
            data: {
                title: '父级初始标题'
            },
            methods: {
                changeTitle(sub_title) {
                    this.title = sub_title ? sub_title : '父级初始标题';
                }
            }
        })
    </script>
    </html>
    

    简述以上

    子组件
    let tag = {
        template: `...`,
        data() {
            return {
               	// 数据...
            }
        }
    }
    // 在哪个组件模板中出现的属性变量和方法变量,都由当前所属组件自己提供
    
    父传子
    <div id="app">
    	<tag :sub_msg="msg" />
    </div>
        
    <script>
    let tag = {
        props: ['sub_msg']
        template: `<div>{{ sub_msg }}</div>`,
    }
    
    new Vue({
        el: '#app',
        components: {
            tag,
        },
        data: {
            msg: '父级数据'
        }
    })
    </script>  
    
    
    子传父(了解)
    <div id="app">
        <h1> {{ title }} </h1>
        <!-- 组件标签不能添加系统事件,只能添加自定义事件,自定义事件在组件内部通过$emit主动触发 -->
        <tag @self_action="changeTitle"/>
    </div>
        
    <script>
    	let tag = {
            template: `
            <div>
                <input v-model="sub_title" />
            </div>
            `,
            data() {
                return {
                    sub_title: ''
                }
            },
            watch: {
                // 监听sub_title属性,值一改变就会触发
                sub_title() {
                    // 将sub_title与父级的title建立关联
                    // 激活(触发)self_action自定义事件
                    this.$emit('self_action', this.sub_title)
                }
            }
        };
    
        new Vue({
            el: '#app',
            components: {
                tag,
            },
            data: {
                title: '父级初始标题'
            },
            methods: {
                changeTitle(sub_title) {
                    this.title = sub_title ? sub_title : '父级初始标题';
                }
            }
        })
    </script>  
    
  • 相关阅读:
    RTT设备与驱动之串口
    RTT设备与驱动之PIN设备
    RTT之ENV
    MQTT学习之一
    思维导图软件
    英语单词学习方法
    RTT之POSIX
    10 个强大的JavaScript / jQuery 模板引擎推荐
    30个实用的jQuery选项卡/导航教程推荐
    jquery 自动完成 Autocomplete插件汇总
  • 原文地址:https://www.cnblogs.com/chanyuli/p/11854116.html
Copyright © 2011-2022 走看看