目录
- 非文件组件使用步骤
 - 定义组件
 - 示例(第一部分):使用Vue.extend函数创建三个组件
 
- 注册组件
 - 示例(第二部分):组件的全局和局部注册
 
- 组件使用
 - 示例(第三部分):编写组件标签
 - 最终结果
 
- 组件注意事项
 - 组件嵌套
 - 组件定义
 - 组件注册
 - 组件使用
 
- 其他需要注意的地方
 
本博客参考尚硅谷官方课程,详细请参考
- 【尚硅谷bilibili官方】
 
本博客以vue2作为学习目标(请勿混淆v2与v3的代码规范,否则可能出现报错),详细教程请参考
- 【 v2.x 官方文档】
 
非文件组件使用步骤
- 定义组件(创建组件)
 - 注册组件
 - 使用组件(写组件标签)
 
定义组件
使用Vue.extend(options)创建组件,其中options和new Vue(options)时传入的那个options几乎一样,但也有区别
区别:
- 组件中el配置项不要写,为什么? ——— 最终所有的组件都要经过一个vm的管理,由vm中的el决定服务哪个容器。
 - 组建中data配置项必须写成函数,为什么? ———— 避免组件被复用时,数据存在引用关系。
 
示例(第一部分):使用Vue.extend函数创建三个组件
<script>
	//创建学校组件
    const school = Vue.extend({
      template: `
			<div class="demo">
				<h2>学校名称:{{schoolName}}(school组件)</h2>
				<h2>学校地址:{{address}}</h2>
				<button @click="showName">点我提示学校名</button>	
			</div>
		`,
      data() {
        return {
          schoolName: "尚硅谷",
          address: "北京昌平",
        };
      },
      methods: {
        showName() {
          alert(this.schoolName);
        },
      },
    });
    //创建student组件
    const student = Vue.extend({
      template: `
			<div>
				<h2>学生姓名:{{studentName}}(student组件)</h2>
				<h2>学生年龄:{{age}}</h2>
			</div>
		`,
      data() {
        return {
          studentName: "张三",
          age: 18,
        };
      },
    });
    //创建hello组件
    const hello = Vue.extend({
      template: `
		<div>	
			<h2>你好啊!{{name}}(hello组件)</h2>
		</div>
	`,
      data() {
        return {
          name: "Tom",
        };
      },
    });
</script>
 
注册组件
- 局部注册:
new Vue时传入components选项 - 全局注册:
Vue.component('组件名',组件) 
注意:
- 组件必须先创建后注册,否则会发生报错: “Uncaught ReferenceError: Cannot access ‘school’ before initialization”
 - 完成组件创建和注册后,创建Vue实例指向某个DOM容器是必要的,也就是说组件最外层需要Vue实例包裹,否则vue自定义组件无法渲染,组件无法显示
 
示例(第二部分):组件的全局和局部注册
<script>
    //全局注册组件
    Vue.component("hello", hello);
    //创建Vue实例vm
    new Vue({
      el: "#root",
      data: {
        msg: "此处位于root节点!",
      },
      //注册组件(局部注册)
      components: {
        school,
        student,
      },
    });
    // 创建Vue实例vm
    new Vue({
      el: "#root2",
      data() {
        return {
          msg: "此处位于root2节点!",
        };
      },
    });
</script>
 
组件使用
示例(第三部分):编写组件标签
<body>
  <div id="root">
    <!--编写组件标签-->
    <hello></hello>
    <h1>{{msg}}</h1>
    <!--编写组件标签 -->
    <school></school>
    <!--编写组件标签 -->
    <student></student>
  </div>
  <hr />
  <div id="root2">
    <h1>{{msg}}</h1>
    <hello></hello>
  </div>
</body>
 
最终结果

组件注意事项
- 命名规则
 
(1)一个单词组成时:
第一种写法(首字母小写):school
第二种写法(首字母大写):School
(2)多个单词组成:
第一种写法(kebab-case命名):my-school
第二种写法(CamelCase命名):MySchool (需要Vue脚手架支持)- 组件名尽可能回避HTML中已有的元素名称,例如:h2、H2都不行。
 - 可以使用name配置项指定组件在开发者工具中呈现的名字。
 - 编写组件标签
 
第一种写法:<school></school>
第二种写法:<school/>(这种写法在没有使用脚手架的时候会造成标签没有办法渲染)- 注册组件的简写方法
 
const school = Vue.extend(options) //简写为 const school = options
组件嵌套
组件定义
下面我们将先定义一个student组件,然后再定义一个school组件,在后者注册student组件
<script>
	  //定义student组件
	  const student = Vue.extend({
	    name: "student",
	    template: `
			<div>
				<h2>学生姓名:{{name}}(学生组件)</h2>	
			</div>
			`,
	    data() {
	      return {
	        name: "张三",
	      };
	    },
	  });
	
	  //定义school组件
	  const school = Vue.extend({
	    name: "school",
	    template: `
			<div>
				<h2>学校名称:{{name}}(学校组件)</h2>	
				<student></student>
			</div>
			`,
	    data() {
	      return {
	        name: "尚硅谷",
	      };
	    },
	    //在school组件中注册组件(局部)
	    components: {
	      student,
	    },
	  });
</script>
 
组件注册
<script>
// 全局组件注册
Vue.component("school", school);
// 创建Vue实例vm,用于包裹组件
new Vue({
  el: "#root",
});
</script>
 
组件使用
<body>
  <div id="root">
    <school></school>
  </div>
</body>
 
效果
 
浏览器开发者工具
 
其他需要注意的地方
关于VueComponent组件函数
上面代码中我们曾经定义个多个组件,实际上这些组件本质是一个名为VueComponent的构造函数,由Vue.extend生成。我们只需要写<school/>或<school></school>,Vue解析时会帮我们创建school组件的实例对象,即Vue帮我们执行了:new VueComponent(options)。
每次调用Vue.extend,返回的都是一个全新的VueComponent。
关于this指向的问题
- 在组件配置中(生成一个新组件),data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【VueComponent实例对象】
 - 在new Vue(options)配置中(生成一个Vue实例对象),data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【Vue实例对象】。
 
关于VueComponent与Vue实例对象的关系
一个重要的内置关系:VueComponent.prototype.__proto__ === Vue.prototype,这样组件实例对象(vc)可以访问到 Vue原型上的属性、方法。



















