Vue2-组件,组件的使用及注意点,组件嵌套,VueComponent构造函数,单文件组件

🥔:功不唐捐

更多Vue知识请点击——Vue.js

组件与使用组件的三大步

组件:实现应用中局部功能代码和资源的集合

传统方式编写缺点:

  • 依赖关系混乱
  • 代码复用率不高

使用组件编写优点:

  • 依赖关系明晰
  • 复用率较高
  • 提高运行效率

非单文件组件与单文件组件:

  • 非单文件组件:一个文件中包含n个组件

  • 单文件组件:一个文件中只包含1个组件

如何使用组件,三大步:

1、定义组件(创建组件)
2、注册组件
3、使用组件(写组件标签)

1、定义组件(创建组件)

使用Vue.extend(options)创建,其中options和new Vue(options)时传入的那个options几乎一样,但也有点区别

区别如下:

(1)el不要写,为什么?
最终所有的组件都要经过一个vm的管理,由vm中的el决定服务哪个容器。备注:使用template可以配置组件结构。

(2)data必须写成函数,为什么?
避免组件被复用时,数据存在引用关系,比如我父组件要多次复用一个子组件,那如果其中一个子组件做了修改数据操作,其他复用的地方数据也会被修改。如果某个组件中的data写成对象形式,且组件内有对数据的操作,那么该组件在多次复用时,每次点击某一个按钮,其他组件实例的数据都会改变,这样是不行的。

2、注册组件

①局部注册

创建vmnew Vue的时候传入components选项

   <!-- 准备一个容器 -->
    <div id="root">
        <xuexiao></xuexiao>
        <hr>
        <xuesheng></xuesheng>
    </div>

    <script>
        //第一步:创建school组件
        const school = Vue.extend({
        	name: 'dj', //可以使用name配置项指定组件在开发者工具中呈现的名字(只是开发者工具里用的名字)。
            // el: '#hello'  el不能写
            template: `
                <div>
                    <h2>学校名字{{schoolName}}</h2>
                    <h2>学校地址{{address}}</h2>
                </div>
            `,
            data() {
                return {
                    schoolName: 'web',
                    address: '广州',
                }
            }
        })

        //第一步:创建student组件
        const student = Vue.extend({
            template: `
                <div>
                    <h2>学生名字{{studentName}}</h2>
                    <h2>学生年龄{{age}}</h2>
                    <button @click="add">点击年龄+1</button>
                </div>
            `,
            data() {
                return {
                    studentName: 'potato',
                    age: 18
                }
            },
            methods: {
                add() {
                    this.age++;
                }
            },
        })

        //创建一个vm带领小弟接管root容器
        const vm = new Vue({
            el: '#root',
            // 第二步:注册组件(局部注册)
            components: {
                //组件名:组件
                //这里最好写成school:school,简写为school
                xuexiao: school,
                //这里最好写成student:student,简写为student
                xuesheng: student
            }
        })
    </script>
②全局注册

Vue.component('组件名',组件)

   <!-- 准备一个容器 -->
    <div id="root">
        <sayhello></sayhello>
    </div>

    <!-- 准备第二个容器 -->
    <div id="root2">
        <sayhello></sayhello>
    </div>

    <script>
        //第一步:创建组件
        const hello = Vue.extend({
            template: `
                <div>
                    <h2>{{msg}}</h2>
                </div>
            `,
            data() {
                return {
                    msg: 'hello world'
                }
            }
        })
        //第二步:全局注册组件
        Vue.component('sayhello', hello);

        //创建第一个vm接管root
        const vm = new Vue({
            el: '#root'
        })

        //创建第二个vm接管root2
        new Vue({
            el: '#root2'
        })
    </script>

3、使用组件

直接写组件名的标签就可以,一般我们定义组件时,组件名和定义的名字最好一样,这样就可以简写。

   <!-- 准备一个容器 -->
    <div id="root">
        <xuexiao></xuexiao>
        <xuesheng></xuesheng>
    </div>

小案例:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>组件初识</title>
    <script src="../js/vue.js"></script>
  </head>
  <body>
    <div id="root">
      <!-- 编写组件标签 -->
      <school></school>
      <hr />
      <student></student>
    </div>

    <script>
      // 创建school组件
      const school = Vue.extend({
        template: `
        <div>
            <h2>学校名称:{{schoolName}}</h2>
            <h2>学校地址:{{address}}</h2>
        </div>
        `,
        data() {
          return {
            schoolName: "新东方",
            address: "山东",
          };
        },
      });
      // 创建student组件
      const student = Vue.extend({
        template: `
        <div>
            <h2>学生姓名:{{studentName}}</h2>
            <h2>学生年龄:{{age}}</h2>
        </div>
        `,
        data() {
          return {
            studentName: "张三",
            age: 18,
          };
        },
      });
      //  创建vm
      new Vue({
        el: "#root",
        // 注册组件
        components: {
          school,
          //   xuexiao: school,
          student,
          //   xuesheng: student,
        },
      });
    </script>
  </body>
</html>

使用组件的一些注意点

1.关于组件名

一个单词组成:
第一种写法(首字母小写):school
第二种写法(首字母大写):School
多个单词组成:
第一种写法(kebab-case命名):‘my-school’
第二种写法(CamelCase命名):MySchool (需要Vue脚手架支持)
备注:
(1).组件名尽可能回避HTML中已有的元素名称,例如:h2、H2都不行。
(2).可以使用name配置项指定组件在开发者工具中呈现的名字(不影响注册的名字)。

2.关于组件标签

第一种写法:<school></school>
第二种写法:<school/>
备注:不用使用脚手架时,<school/>会导致后续组件不能渲染。

3.一个简写方式

const school = Vue.extend(options) 可简写为:const school = options

组件的嵌套

这里要注意,vm里要写el,其他都不写。vm里的template可以不用写根节点,因为vm里的东西是放到容器里的,而组件的template要用根节点包起来(如div)。注意创建组件时,要先创建子组件才能创建父组件。

案例(仔细看看代码,观察如何实现嵌套):

  • 嵌套图示:

请添加图片描述

  • 代码:
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>组件的嵌套</title>
    <script src="../js/vue.js"></script>
  </head>
  <body>
    <div id="root">
      <!-- 编写组件标签 -->
      <!-- <app></app> 可以不在这写,可以写在new Vue的template里-->
    </div>

    <script>
      // 创建student组件
      const student = Vue.extend({
        template: `
        <div>
            <h2>学生姓名:{{studentName}}</h2>
            <h2>学生年龄:{{age}}</h2>
        </div>
        `,
        data() {
          return {
            studentName: "张三",
            age: 18,
          };
        },
      });
      // 创建school组件
      const school = Vue.extend({
        template: `
        <div>
            <h2>学校名称:{{schoolName}}</h2>
            <h2>学校地址:{{address}}</h2>
            <student></student>
        </div>
        `,
        data() {
          return {
            schoolName: "新东方",
            address: "山东",
          };
        },
        components: {
          student,
        },
      });
      //创建hello组件
      const hello = Vue.extend({
        template: `<h1>{{msg}}</h1>`,
        data() {
          return {
            msg: "欢迎大家一起学习Vue",
          };
        },
      });
      //创建app组件
      const app = Vue.extend({
        template: `
        <div>
          <hello></hello>
          <school></school>
        </div>
        `,
        components: {
          school,
          hello,
        },
      });
      //  创建vm
      new Vue({
        template: `<app></app>`,
        el: "#root",
        // 注册组件(局部)
        components: {
          app,
        },
      });
    </script>
  </body>
</html>

VueComponent构造函数

组件是一个Vue.extend生成的构造函数,当组件写到页面上时,Vue开始解析,同时自动new了一下,这才创建了组件的实例对象

1、什么是VueComponent?

  1. school组件本质是一个名为VueComponent的构造函数,且不是程序员定义的,是Vue.extend生成的。

  2. 我们只需要写<school/><school></school>,Vue解析时会帮我们创建school组件的实例对象,即Vue帮我们执行的:new VueComponent(options)。

  3. 特别注意:每次调用Vue.extend,返回的都是一个全新的VueComponent构造函数,而不是返回VueComponent的实例(这个地方不要陷入误区),只有当Vue解析组件时,才会返回所对应组件(如school)的VueComponent的实例对象

2、VueComponent中的this指向

VueComponent的实例对象,以后简称vc(也可称之为:组件实例对象)。Vue的实例对象,以后简称vm

  • 组件配置中:data函数、methods中的函数、watch中的函数、computed中的函数。它们的this均是【VueComponent实例对象】。
  • new Vue(options)配置中:data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【Vue实例对象】

一个重要的内置关系

这里用到了原型的知识,可以倒回去复习一下点击此处

1、一个重要的内置关系:VueComponent.prototype.__proto__ === Vue.prototype
2、为什么要有这个关系:让组件实例对象(vc)可以访问到 Vue原型上的属性、方法。

请添加图片描述

单文件组件

为了确保vue开发者工具里的名称和组件名称一致,组件命名最好采取首字母大写形式(如下面案例:School.vue,Student.vue,App.vue)

  • School.vue

    // 组件的结构
    <template>
      <div class="demo">
        <h2>学校名称:{{ name }}</h2>
        <h2>学校地址:{{ address }}</h2>
        <button @click="showName">点我提示学校名称</button>
      </div>
    </template>
    
    // 组件交互相关的代码(数据、方法等)
    <script>
    // 也可以写export default Vue.extend({})
    export default {
      name: "School",
      data() {
        return {
          name: "新东方",
          address: "山东",
        };
      },
      methods: {
        showName() {
          alert(this.schoolName);
        },
      },
    };
    </script>
    
    // 组件的样式
    <style>
    .demo {
      background-color: pink;
    }
    </style>
    
  • Student.vue

    // 组件的结构
    <template>
      <div class="demo">
        <h2>学生姓名:{{ name }}</h2>
        <h2>学生年龄:{{ age }}</h2>
      </div>
    </template>
    
    // 组件交互相关的代码(数据、方法等)
    <script>
    // 也可以写export default Vue.extend({})
    export default {
      name: "School",
      data() {
        return {
          name: "张三",
          age: 18,
        };
      },
    };
    </script>
    
  • App.vue

    <template>
      <div>
        <School></School>
        <Student></Student>
      </div>
    </template>
    
    <script>
    import School from "./School";
    import Student from "./Student";
    
    export default {
      name: "App",
    
      components: {
        School,
        Student,
      },
    };
    </script>
    
  • main.js

    import App from "./App";
    
    new Vue({
      el: "#root",
      template: `<App></App>`,
      components: { App },
    });
    
  • index.html

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <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>
    
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值