1 模块及组件简介

   组件(component)是vue.js最强大的功能之一。组件的作用就是封装可重用的代码,通常一个组件就是一个功能体,便于在多个地方都能够调用这个功能体。 每个组件都是Vue的实例对象。 我们实例化的Vue对象就是一个组件,而且是所有组件的根组件。

  组件可以很好地把代码分成一块块的,清洗明了,并且能够提高复用性

 

 

 

2 定义组件语法

2.1 全局组件

<body>
    <div id="app">
      <my-header></my-header>
      <my-header></my-header>
      <my-header></my-header>
    </div>
  </body>
 
  <script>
    Vue.component("my-header", {
      data: function() {
        return {
          title: "头部标题内容"
        };
      },
      template: `
      <div>
          <button @click='handle'>点击</button>
          <div>{{title}}</div>
      </div>
      `,
      methods: {
        handle: function() {
          console.log(this.title);
        }
      }
    });
    var vue = new Vue({
      el: "#app",
      data: {},
      methods: {},
      computed: {}
    });
  </script>

 

2.2 局部组件

<body>
    <div id="app">
      <my-header></my-header>
      <my-footer></my-footer>
    </div>
  </body>
 
  <script>
    let myHeader = {
      data: function() {
        return {
          title: "头部标题的内容"
        };
      },
      template: `
      <div>
        <button @click="handle">点击</button>
        <p>{{title}}</p>
      </div>
     `,
      methods: {
        handle: function() {
          console.log(this.title);
        }
      }
    };
    let myFooter = {
      data: function() {
        return {
          title: "底部标题的内容"
        };
      },
      template: `
      <div>
        <button @click="handle">点击</button>
        <p>{{title}}</p>
      </div>
     `,
      methods: {
        handle: function() {
          console.log(this.title);
        }
      }
    };
    var vue = new Vue({
      el: "#app",
      data: {},
      methods: {},
      computed: {},
      components: {
        "my-header": myHeader,
        "my-footer": myFooter
      }
    });
  </script>

 

2.3 注意

  1)组件中的data是一个函数,不是对象,这样子可以保证不同地方是有同一个组件data都是新的对象

  2)组件中必须有一个唯一的根元素

  3)模板中内容较多时候建议使用模板字符串

  4)局部注册的子组件只能在注册过的父组件中使用

  5)components是注册组件的意思

  6)组件名推荐全部小写或者首字母大写

 

3 组件的嵌套

 

 

<title>组件的嵌套</title>
<script type="text/javascript" src="../js/vue.js"></script>

<div id="root"></div>

<script type="text/javascript">
  Vue.config.productionTip = false

  //定义student组件
  const student = Vue.extend({
    name: 'student',
    template: `
                <div>
                    <h4>学生姓名:{{name}}</h4>    
                    <h4>学生年龄:{{age}}</h4>    
              </div>
            `,
    data() {return {name: '尚硅谷',age: 18}}
  })

  //定义school组件
  const school = Vue.extend({
    name: 'school',
    template: `
                <div>
                    <h3>学校名称:{{name}}</h3>    
                    <h3>学校地址:{{address}}</h3>    
                    <student></student>
               </div>
            `,
    data() {return {name: '尚硅谷',address: '北京'}},
    //注册组件(局部)
    components: { student }
  })

  //定义hello组件
  const hello = Vue.extend({
    template: `<h3>{{msg}}</h3>`,
    data() {return {msg: '欢迎来到尚硅谷学习!'}}
  })

  //定义app组件
  const app = Vue.extend({
    template: `
                <div>    
                    <hello></hello>
                    <school></school>
              </div>
            `,
    components: { school, hello }
  })

  //创建vm
  new Vue({
    el: '#root',
    template: '<app></app>',
    //注册组件(局部)
    components: { app }
  })
</script>

 

4 VueComponent

  1)组件的本质是一个名为VueComponent的构造函数,并且不是程序员定义的,而是Vue.extend函数生成的。并且每次生成的都是不一样的VueComponent的构造函数。

  2)每当我们使用组件(写组件标签时,<school></school>),vue解析到组件标签时,会帮我们使用VueComponent构造函数创建一个VueComponent实例对象,帮我们执行 new VueComponent(options)
  3)在组件配置中,data函数,methods中配置的函数,watch中配置的函数,computed中配置的函数的this指向的都是VueComponent组件对象。

 

5 VueComponent.prototype.__proto__===Vue.prototype

 

 

 这个内置关系让组件实例对象可以访问到Vue原先上的属性和方法。因为Vue和VueComponent在很大程度上都是相同的(95%),所以像$mount和$watch方法,定义在Vue的原型对象上,然后VueComponent的原型对象的原型对象指向Vue的原型对象,VueComponent和Vue的实例就可以使用同一份方法和属性,而不用写两份一样的。

 

6 单文件组件示例

 

 

1)school组件

<template>
    <div id='Demo'>
        <h2>学校名称:{{name}}</h2>
        <h2>学校地址:{{address}}</h2>
        <button @click="showName">点我提示学校名</button>
    </div>
</template>

<script>
    export default {
        name:'School',
        data() {
            return {
                name:'UESTC',
                address:'成都'
            }
        },
        methods: {
            showName(){
                alert(this.name)
            }
        },
    }
</script>

<style>
    #Demo{
        background: orange;
    }
</style>

 

2)student组件

<template>
    <div>
        <h2>学生姓名:{{name}}</h2>
        <h2>学生年龄:{{age}}</h2>
    </div>
</template>

<script>
    export default {
        name:'Student',
        data() {
            return {
                name:'cess',
                age:20
            }
        },
    }
</script>

 

3)app组件,作为龙头老大

<template>
    <div>
        <School></School>
        <Student></Student>
    </div>
</template>

<script>
    import School from './School.vue'
    import Student from './Student.vue'

    export default {
        name:'App',
        components:{
            School,
            Student
        }
    }
</script>

 

4)main.js

import App from './App.vue'

new Vue({
    template:`<App></App>`,
    el:'#root',
    components:{App}
})

 

5)index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>单文件组件练习</title>
</head>
<body>
    <div id="root"></div>
    <script src="../../js/vue.js"></script>
    <script src="./main.js"></script>
</body>
</html>