组件: 项目的开发,就是一个组件树,组件可以进行复用。

组件的名字

        1.html标签不区分大小写
        2.不能跟系统标签重名
        3.遵循 W3C 规范中的自定义组件名 (字母全小写且必须包含一个连字符)
        4.支持驼峰命名.myHeader,但是在引用的时候,需要使用my-header的方式组件支持两种定义方式

全局组件

语法:Vue.component('my-component-name', {// ... 选项 ...})
方式一:在{}中写入template模板结构

方式二:将template模板结构写到组件外面,指定对应的模板名,即id属性。

局部组件

语法:在实例中添加components,注入即可。
方式一:在实例中添加components,注入子组件

方式二:将template模板结构写到组件外面,声明变量接收,当使用的时候,在components中注入即可。

代码示例

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

<head>
    <meta charset="UTF-8">
    <title>组件</title>
    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>

<body>
    <div id="app1" style="border: 1px solid #333333;margin: auto;width: 500px;">
        <my-header></my-header>
        <my-cont></my-cont>
        <my-btn></my-btn>
    </div>
    <br>
    <div id="app2" style="border: 1px solid #333333;margin: auto;width: 500px;">
        <my-header></my-header>
        <my-cont></my-cont>
        <genie></genie>
    </div>
</body>

</html>
<template id="weizhuang">
    <section>
        <p>我是my-cont组件中的内容</p>
    </section>
</template>
<template id="child">
    <div>
        <input type="text" placeholder="请输入用户名">
        <br>
        <textarea placeholder="请留言"></textarea>
    </div>
</template>
<script>
    // 1.注册全局组件:可以在任何一个实例中引入

    // 方式一
    Vue.component('my-header', {
        // 指定组件的模板, 只有一个根标签,以下div为跟标签
        template: `
            <div>
                <h1>全局组件my-header的h1标签</h1>
                <p>全局组件my-header的p标签</p>
            </div>
        `
    });

    // 方式二
    // 注意:在进行组件化开发的时候,每一个Vue文件都有一个template模板
    Vue.component('myCont', {
        // 指定组件的模板, 只有一个根标签
        template: '#weizhuang'
    });

    // 2.注册局部组件
    // 方式一:
    new Vue({
        el: '#app1',
        components: {
            myBtn: {
                template: `
                <div>
               <button>我是app1中的button1按钮</button>
               <button>我是app1中的button2按钮</button>
               </div>
               `
            }
        }
    });

    // 方式二:
    // 备注:在组件化开发的时候,使用export defult = 该对象,如果在其他组件中要使用,直接在components中注入即可。
    let child = {
        template: '#child'
    };
    new Vue({
        el: '#app2',
        components: {
            genie: child
        }
    });
</script>

举个栗子

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

<head>
	<meta charset="UTF-8">
	<title>组件</title>
	<script src="https://cdn.jsdelivr.net/npm/vue"></script>
	<style type="text/css">
		* {
			margin: 0;
			padding: 0;
		}

		.wrapper {
			width: 400px;
			margin: auto;
			border: 1px solid #333333;
		}

		.wrapper img {
			font-size: 0;
			vertical-align: middle;
			border-bottom: #333333 1px solid;
		}

		.details {
			width: 100%;
			display: flex;
			user-select: none;
		}

		.details div {
			flex: 1;
			text-align: center;
		}

		.details div:nth-child(1) {
			background: gainsboro;
			line-height: 30px;
		}

		.btn {
			width: 100px;
			height: 30px;
			border: none;
			background: blue;
			color: white;
			font-size: 20px;
			line-height: 30px;
			text-align: center;
			opacity: 0.5;
			cursor: pointer;
		}

		.btn:hover {
			opacity: 1;
		}

		.buy {
			display: flex;
			width: 100%;
		}

		.buy div {
			flex: 1;
		}

		.tip {
			color: red;
			font-size: 18px;
			text-align: center;
			user-select: none;
		}
	</style>
</head>

<body>
	<div id="app">
		<!--注意: 必须引入,才会起效果-->
		<child></child>
	</div>
</body>

</html>
<template id="child">
	<div class="wrapper">
			<img src="http://iph.href.lu/400x400" alt="图片加载失败">
			<div class="details">
				<div>单价 ¥:{{price}}元</div>
				<div class="btn" @click="doClick">购买</div>
			</div>
			<div class="buy">
				<div class="tip" style="background: cadetblue">总计:{{getPrice}}元</div>
				<div v-show="flag2" class="tip" style="background: gold">提示:未购该商品。</div>
				<div v-show="flag" class="tip" style="background: gold">提示:您购{{num}}件商品。</div>
			</div>	
	</div>
</template>
<script>
	// 定义子组件
	let child = {
		template: '#child',
		// 在组件中写data的时候,要把data写成一个函数
		// 防止两个组件公用一个数据源
		// 写法一:
		//        data: function () {
		//            return {
		//                name: '卫庄'
		//            };
		//        }
		// 写法二:es6语法
		data() {
			return {
				num: 0,
				flag: false,
				flag2: true,
				price: 100
			}
		},
		methods: {
			doClick() {
				this.flag = true;
				this.flag2 = false;
				this.num++;
			}
		},
		// 计算属性
		computed: {
			getPrice() {
				return this.num * this.price;
			}
		},
		watch:{
			
		}

	};
	new Vue({
		el: '#app',
		components: {
			// es6语法会把child当做属性值与属性名
			// 注意:定义的子组件一定要在父组件中注入
			child
		}
	});
</script>

效果图

Vue入门-组件基础_组件化