VUE组件

组件

一、子组件

<head>
    <meta charset="UTF-8">
    <title></title>
    <style>
        .wrap {
            width: calc(200px * 4 + 80px);
            margin: 0 auto;
            user-select: none;
        }
        .box {
            width: 200px;
            height: 260px;
            background-color: salmon;
            border-radius: 10px;
            float: left;
            margin: 10px;
        }
        .box img {
            width: 100%;
            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 (){
            return {
                num:0
            }
        },
        methods: {
            fn(){
                this.num ++
            }
        },
        components: {
            titleTag,
        }
    };
    new Vue({
        el: '#app',
        components: {
            tag,
        }

    })
</script>

​ 注意:

​ 1.能被复用的组件(除了根组件),数据都要做局部化处理,因为复用组件后,组件的数据是相互独立的。

	2.data的值为绑定的方法的返回值,返回值是存放数据的字典。

二、父组件向子组件传参

​ 在组件内部可以通过设置的自定义属性,拿到外部选择子组件提供给属性的值。

<head>
    <meta charset="UTF-8">
    <title></title>
    <style>
        .wrap {
            width: calc(200px * 4 + 80px);
            margin: 0 auto;
            user-select: none;
        }
        .box {
            width: 200px;
            height: 260px;
            background-color: aqua;
            border-radius: 10px;
            float: left;
            margin: 10px;
        }
        .box img {
            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', 'c'],
        template:`
        <div class='box'>
            <img :src="dog.img" alt="">
            <p>
                <b>
                    {{ dog.title }}
                </b>
            </p>
        </div>
        `,
        data (){
            return {
                num: 0,
            }
        },
        methods: {
            fun(){
                this.num ++
            }
        },
    };
    new Vue({
        el: '#app',
        data: {
            dogs,
        },
        components: {
            tag,
        }
    });
</script>

​ 总结 :

​ 1.数据在父组件中产生 。

​ 2.在父组件中渲染子组件,子组件绑定自定义属性,附上父组件中的数据 。

​ 3.子组件自定义属性在子组件的props成员中进行声明(采用字符串发射机制) 。

​ 4.在子组件内部,就可以用props声明的属性(直接作为变量)来使用父组件中的数据 。

三、子组件向父组件传参

​ 示例一:

<head>
    <meta charset="UTF-8">
    <title></title>
    <style>
        ul {
            list-style: none;
        }
        .d-btn {
            font-size: 12px;
            width: 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 () { 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.arr = JSON.stringify([1, 2, 3]);
    let res = JSON.parse(localStorage.arr);
    console.log(res, res[2]);
</script>

​ 注意:localStorage,sessionStorage不能直接存储数组和对象,需要序列化为json。

​ 示例二:

<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <div id="app">
        <h1> {{ title }}</h1>
        <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() {
                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>
posted @ 2019-11-13 21:10  唐ceng  阅读(157)  评论(0编辑  收藏  举报