vue学习【第五篇】:Vue组件

什么是组件

- 每一个组件都是一个vue实例
- 每个组件均具有自身的模板template,根组件的模板就是挂载点
- 每个组件模板只能拥有一个根标签
- 子组件的数据具有作用域,以达到组件的复用

根组件

<div id="app">
    <h1>{{ msg }}</h1>
</div>
<script type="text/javascript">
	// 通过new Vue创建的实例就是根组件(实例与组件一一对应,一个实例就是一个组件)
	// 每个组件组件均拥有模板,template
	var app = new Vue({
		// 根组件的模板就是挂载点,不需要自定义
		el: "#app",
		data : {
			msg: "根组件"
		},
		// 模板: 由""包裹的html代码块,出现在组件的内部,赋值给组件的$template变量
		// 显式书写模块,就会替换挂载点,但根组件必须拥有挂载点
		template: "<div>显式模板</div>"
	})
	// app.$template
</script>

局部组件

<body>
    <div id="app">
        <abc></abc>
        <abc></abc>
        <abc></abc>
    </div>
    <hr>
    <div id="main">
        <local-tag></local-tag>
        <local-tag></local-tag>
    </div>
</body>
<script src="js/vue.js"></script>
<script>
    // 局部组件
    var localTag = {
        // 子组件的数据具有作用域,以达到组件的复用, 每一个复用的组件具有自身独立的一套数据
        data: function () {
            return {  // 返回值是一个数据字典(一套数据)
                count: 0
            }
        },
        template: "<div @click='fn'>点击{{ count }}次</div>",
        methods: {
            fn: function () {
                this.count += 1;
            }
        }
    }

    // app根组件
    new Vue({
        el: "#app",
        // 注册
        components: {
            'abc': localTag
        }
    })
    // main根组件
    new Vue({
        el: "#main",
        components: {
            // localTag    js中键值一样可以简写,只写一个就行     这样写比较装十三,一般不知道js标识符于css/html标识符的相互转换的可能不知道
            'local-tag': localTag
        }
    })
</script> 

全局组件

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>全局组件</title>
</head>
<body>
    <div id="app">
        <global-tag></global-tag>
    </div>
    <div id="main">
        <global-tag></global-tag>
    </div>
</body>
<script src="js/vue.js"></script>
<script>
    // 创建全局组件
    Vue.component('global-tag', {
        template: "<div @click='fn'>全局组件点击了 {{ count }} 次</div>",
        data: function () {
            return {
                count: 0
            }
        },
        methods: {
            fn: function () {
                this.count++;
            }
        }
    });

    new Vue({
        el: "#app",
    });
    new Vue({
        el: "#main",
    });
</script>
</html>

父组件传递数据给子组件

通过绑定属性的方式进行数据传递

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>组件通信父到子</title>
</head>
<body>
    <div id="app">
        <input type="text" v-model="sup_data">

        <global-tag :abcde="sup_msg" :sup_data="sup_data"></global-tag>
    </div>
</body>
<script src="js/vue.js"></script>
<script>
    // 创建全局组件
    Vue.component('global-tag', {
        props: ['abcde', 'sup_data'],
        template: "<div @click='fn'>{{ abcde }}</div>",
        data: function () {
            return {

            }
        },
        methods: {
            fn: function () {
                alert(this.sup_data)
            }
        }
    });
    // 将父组件的信息传递给子组件
    // 采用属性绑定的方式: 1,父级提供数据 2.绑定给子组件的自定义属性 3.子组件通过props的数组拿到自定义属性从而拿到数据
    new Vue({
        el: "#app",
        data: {
            sup_msg: "父级的msg",
            sup_data: ""
        }
    });
</script>
</html>

子组件传递数据给父组件

通过发送事件请求的方式进行数据传递

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>组件通信子到父</title>
</head>
<body>
    <div id="app">
        <!-- abc为子组件的自定义事件,该事件的含义要在子组件内容声明规定 -->
        <global-tag @abc="action"></global-tag>
        <global-tag @abc="action"></global-tag>
        {{ sup_info }}
    </div>

</body>
<script src="js/vue.js"></script>
<script>
    // 创建全局组件
    Vue.component('global-tag', {
        template: "<div><input v-model='info'><p @click='sendMsg'>子组件</p></div>",
        data: function () {
            return {
                info: "",
                msg: "子组件的信息"
            }
        },
        methods: {
            sendMsg: function () {
//                alert(123)
                // 激活自定义事件 abc
                this.$emit('abc', this.msg, this.info)
            },

        }
    });
    // 将子组件的信息传递给父组件
    // 采用发生事件的方式:
    // 1.在子组件的内容系统事件中来定义一个自定义事件,采用$emit发生到自定义组件名上(可以携带子组件内容数据)
    // 2.在父组件复用子组件时, 实现子组件自定义数据的功能, 在父组件中的methods中为功能绑定函数(函数的参数就是携带出来的数据)
    // 3.当在组件内部激活系统事件,就会激活自定义事件,$emit发生给父级,激活父级绑定的函数,该函数被执行,同时拿到数据
    new Vue({
        el: "#app",
        data: {
            sup_info: ""
        },
        methods: {
            action: function (msg, info) {
                alert(msg)
                this.sup_info = info
            }
        }
    });
</script>
</html>

组件实现留言板

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>留言板</title>
    <style>
        ul {
            margin: 0;
            padding: 0;
        }
        a {
            color: black;
            text-decoration: none;
            display: block;
            height: 21px;
        }
        p {
            margin: 0;
            color: orange;
            float: left;
        }
        span {
            color: red;
            float: right;
        }
    </style>
</head>
<body>
    <div id="app">
        <input type="text" v-model="msg">
        <button @click="btnClick">留言</button>
        <hr>
        <ul>
            <!-- 如果每一个渲染的列表项是一个相对复杂的结构, 该复杂的结构可以封装成组件 -->
            <li v-for="(v, i) in list">
                <global-tag :value="v" :index="i" @delete="delAction"></global-tag>
            </li>
        </ul>
        <!--<ul>-->
            <!--<li v-for="(v, i) in list2">-->
               <!--<global-tag :value="v" :index="i" @delete="delAction"></global-tag>-->
            <!--</li>-->
        <!--</ul>-->
    </div>
</body>
<script src="js/vue.js"></script>
<script>
    new Vue({
        el: "#app",
        data: {
            msg: "",
            list: [],
            list2: []
        },
        methods: {
            btnClick: function () {
                if (this.msg) {
                    this.list.push(this.msg);
                    this.msg = "";
                }
            },
            delAction: function (index) {
                this.list.splice(index, 1)
            }
        }
    });
    
    Vue.component('global-tag', {
        props: ['value', 'index'],
        template: "<a href='javascript:void(0)'><p>{{ value }}</p><span @click='sendDel'>x</span></a>",
        methods: {
            sendDel: function () {
                this.$emit('delete', this.index)
            }
        }
    });
</script>
</html>

  

原文地址:https://www.cnblogs.com/596014054-yangdongsheng/p/10385622.html