【vue系列-06】vue的组件化编程

简介: 【vue系列-06】vue的组件化编程

一,vue组件

1,什么是vue组件

下图摘自官网,其底层主要是利用封装的思想,将一个大的组件拆分成多个小组件,并且在一个组件中一定会有一个vm的root根组件。组件和组件之间可以嵌套,组件就是实现应用中局部功能代码和资源的集合。代码主要有一些css,html,js等组成;资源主要由MP3,MP4,zip压缩包等文件组成。这样就可以实现代码复用,简化项目编码,提高开发和运行效率。


30fdc16ac1f04629bc1760d0f6c792c6.png


2,单文件组件和非单文件组件

二者区别


非单文件组件:顾名思义就是不是单文件组件,表示一个文件中包含有n个单文件组件。类似于一个大文件还没有拆分成多个小文件,全部聚集在一起,这样子的代码不容易维护,耦合性高,并且复用性低。


单文件组件:就是说一个组件中只包含一个文件。利用封装的思想,将组件从一个全部挤在一起的大型组件抽取出来,拆分成多个小组件,实现代码复用性高,更加的容易维护。


3,非单组件的基本使用

在创建组件时,和之前最原始的创建组件方式稍有不同,如果不是root根组件,其内部不需要el关键字,由于最终这个组件都是被vm的根节点所管理,因此其内部不需要el关键字,并且通过Vue.extend来创建非根组件,其内部的data元素只能用函数式,不能用对象式。其代码实现如下

<body>
    <!-- 一个容器,可以用于接收vue实力传来的数据,然后展示 -->
    <div id="root">
        <!-- 3,编写组件标签 -->
        <school></school>
        <student></student>
    </div>
    <script type="text/javascript" >
        Vue.config.productionTip = false   //阻止vue启动时提示生产提示
        const school = Vue.extend({ //1,创建school组件
            template:`
                <div>
                    <h1>学校名称是:{{schoolName}}</h1>    
                    <h1>学校地址是:{{address}}</h1>
                </div>
            `,
            data(){  //数据只能以函数式返回,不能以对象式
                return {
                    schoolName:'北京大学',
                    address:'北京'
                }
            }
        })
        const student = Vue.extend({  //1,创建student组件
            template:`
                <div>
                    <h1>学生姓名是:{{studentName}}</h1>    
                    <h1>学生年龄是:{{age}}</h1>
                </div>
            `,
            data(){    //数据只能以函数式返回,不能以对象式
                return {
                    studentName:'zhs',
                    age:18
                }
            }
        })
        //2,注册组件,局部注册
        new Vue({
            el:'#root',
            components:{ //用于注册组件
                school,
                student
            }
        })
    </script>
</body>

总结来说就分三步,第一步就是创建组件,第二步就是注册组件,第三步就是编写组件标签到对应的父组件中。


如果组件需要变成全局组件,那么其第二步的注册组件的方式需要改成如下,这样这个book就变成了全局组件,在所有的vm中都可以使用。

Vue.component('book',book);

4,vue组件命名规范

4.1,一个单词组成

在官方文档中,如果是一个单词组成,那么可以直接使用这个单词作为组件名,也可以将这个单词的首字母大写之后再作为组件名。

Components:{
    school:'school; //方式一
    School:'school'; //方式二
}

4.2,多个单词组成

如果组件名是由多个单词组成的,那么可以全部让字母小写,单词与单词之间用一个 - 连接,也可以让多个单词直接使用大写字母拼接在一起(需要使用脚手架)。

Components:{
    `my-school`:'school;
    MySchool:'school'
}

并且在命名组件时,尽可能回避html中已有的元素名称,如h1,H1等都不行。并且在注册组件时,也可以简写将这个Vue.extend({}) 直接写成 {},如下。

const s = {...}

虽然说这里并没有显示的调用这个 Vue.extend,但是底层源码是会将这个补上的。


5,组件与组件间的嵌套

如上面的school组件,是一个root根组件下面的子组件,现在又想在school组件中再注册一个组件,形成一个嵌套组件,那么其代码实现如下。这里暂时还没有用到脚手架,因此在定义这个组件时,这个幼儿园组件要在这个定义在这个学校的前面,然后需要将子组件注册到这个父组件中,要和谁嵌套就将谁注册哪个组件中。

//定义一个幼儿园组件,实现和学校的嵌套,这里使用简洁式,省去Vue.extend
const kindergarten = {
    template:`
        <div>
            <h1>学校名称是:{{schoolName}}</h1>    
            <h1>学校地址是:{{address}}</h1>
        </div>
    `,
    data(){
        return {
            schoolName:'幼儿园',
            address:'深圳南山区'
        }
    }
}
//1,创建组件
const school = Vue.extend({
    template:`
        <div>
            <h1>学校名称是:{{schoolName}}</h1>    
            <h1>学校地址是:{{address}}</h1>
            <kindergarten></kindergarten>
        </div>
    `,
    data(){
        return {
            schoolName:'北京大学',
            address:'北京'
        }
    },
    components:{
        kindergarten,kindergarten
    }
})

6,VueComponent组件

上面的这个school的组件的本质,其就是一个名为Component的构造函数,由Vue.extend所生成。即在写school这个标签时,vue解析时就会创建这个school的组件的实例对象,即执行如下语句

new VueComponent(options)

在每次调用Vue.extend的时候,返回的都是一个全新的组件对象。其实这个用java理解也很简单,就是

const a1 = new A();
const a2 = new A();

而且通过vue的源码也可以发现,每次这个sub对象都是一个全新的对象,因此也可以得知每次返回的都是

Vue.extend = function (extendOptions) {
    var Sub = function VueComponent(options) {
        this._init(options);
    };
    return Sub;
}

VueComponent的实例对象,也可以简称为vc,也可以称为组件实例对象。并且在这个vue的实例对象vm中,管理着一个个vc对象。


7,Vue和VueComponent的关系

7.1,Vue的原型对象

在引入这个vue.js之后,那么这个Vue组件的对象就有了,并且一定会有一个属性名为prototype,这个值就是对应的原型对象 ,那么这个vue原型对象上面的所有的这个函数,都可以被实例对象直接使用了。


而这个直接引入js所生成的vue对象,这个对象中有一个显示属性prototype,而直接通过new关键字构造出来的实例对象也一定会有一个隐式的__property__属性,那么这个实例对象也会通过这个属性直接指向这个Vue的原型对象。


由于这个实例的隐式属性,永远指向自己的缔造者的对象。这个原型对象也是一个对象,那么肯定也会指向自己的缔造者的对象,因此可知这个vue的原型对象的这个隐式属性 __property__,指向的就是自己的制造者对象Object。


c579a59559c042009ab9b7af47742eff.png

7.2,VueComponent的原型对象

这个VueComponent和这个Vue的底层逻辑是一样的,VueComponent这个组件的原型对象一定会有一个显示属性prototype,该值一定是指向他的缔造者对象;这个VueComponent的实例对象也一定会有一个隐式属性 __property__,该值指向的肯定也是他的缔造者对象,即VueComponent的原型对象。


但是这个VueComponent的原型对象和vue的原型对象不一样,vue的原型对象是直接指向Object对象,但是这个VueComponent的原型对象实例加了一层,是将这个VueComponent的原型对象的隐式属性指向Vue的原型对象,(21:57),


cfad7a13fdf94e629e3e161312d1ffcc.png


通过上图可知,VueComponent这个组件就是想让这个Vue的原型对象做一个兜底,首先去VueComponent的原型对象上找东西,没有的话再去VueComponent的原型对象上找东西,没有的话再去Vue的原型对象上找东西,没有的话再交给Object的原型对象。


这样做的好处就是:让组件实例对象(vc)也可以访问到Vue原型上的属性和方法。

VueComponent.prototype.__proto__ === Vue.prototype

而这个组件实例对象可以近似的认为就是一个小的vm,就是一个vue的实例对象,不同点就是这个vc不能用这个el属性,并且他的data只能写函数式,不能用对象式。


8,单文件组件

上面说了这么多都是在聊多文件组件,接下来主要理解一下什么时单文件组件。在此之前,需要先安装一个插件,这个推荐使用 vetur 这个插件。在安装完插件之后,新建一个.vue的文件,然后其结构主要如下,分别是由组件的结构,组件交互相关的代码(数据,方法等等),组件的样式等组成。在安装了这个插件之后,直接< + 回车就可以出现以下代码。

<template>
    <div>
        <!-- 组件的结构 -->
    </div>
</template>
<script>
  export default {
      //组件交互相关的代码   
  }
</script>
<style>
    /* 组件的样式 */
</style>

8.1,单文件组件的实现

那么接下来就根据这个多文件中的school和Student的这两组件,用这个单文件实现一下,主要会定义一些Student.vue,School.vue,App.vue,main.js,index.js,其步骤如下:


1,School.vue


这里主要编写一些关于学校的样式,数据结构个数据交互

<template>
    <div>
        <h1>学校姓名是:{{name}}</h1>    
        <h1>学校地址是:{{address}}</h1>
    </div>
</template>
<script>
    export default {
        name:'School',
        data(){
            return{
                name:'',
                age:''
            }
        }
    }
</script>
<style>
</style>

2,Student.vue

<template>
    <div>
        <h1>学生姓名是:{{name}}</h1>    
        <h1>学生年龄是:{{age}}</h1>
    </div>
</template>
<script>
    export default {
        name:'Student',
        data(){
            return{
                name:'',
                age:''
            }
        }
    }
</script>
<style>
</style>

3,App.vue


这个组件主要是作为一个汇总组件,将其他的所有的子组件汇总到该组件中。

<template>
    <div>
        <!-- 引入组件 -->
        <School></School>
        <Student></Student>
    </div>
</template>
<script>
    //引入组件
    import School from './School.vue'
    import Student from './School.vue'
    export default {
        name:'App',
        components:{
            School,
            Student
        }
    }
</script>
<style>
</style>

4,main.js

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

5,index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue的单文件组件学习</title>
</head>
<body>
    <!-- 根组件 -->
    <div id="root"></div>
    <!-- 先引入vue.js -->
    <script type="text/javascript" src="../js/vue.js"></script> 
    <!-- 再引入main.js -->
    <script type="text/javascript" src="./main.js"></script>
</body>
</html>

这样就就完全的通过单文件代替多文件的编写了,当然这里只是一个初步的示例,具体的还得安装脚手架来跑通整个流程

<title>Vue的单文件组件学习</title>

这样就就完全的通过单文件代替多文件的编写了,当然这里只是一个初步的示例,具体的还得安装脚手架来跑通整个流程


相关文章
|
7天前
|
缓存 JavaScript 前端开发
vue学习第四章
欢迎来到我的博客!我是瑞雨溪,一名热爱JavaScript与Vue的大一学生。本文介绍了Vue中计算属性的基本与复杂使用、setter/getter、与methods的对比及与侦听器的总结。如果你觉得有用,请关注我,将持续更新更多优质内容!🎉🎉🎉
vue学习第四章
|
7天前
|
JavaScript 前端开发
vue学习第九章(v-model)
欢迎来到我的博客,我是瑞雨溪,一名热爱JavaScript与Vue的大一学生,自学前端2年半,正向全栈进发。此篇介绍v-model在不同表单元素中的应用及修饰符的使用,希望能对你有所帮助。关注我,持续更新中!🎉🎉🎉
vue学习第九章(v-model)
|
7天前
|
JavaScript 前端开发 开发者
vue学习第十章(组件开发)
欢迎来到瑞雨溪的博客,一名热爱JavaScript与Vue的大一学生。本文深入讲解Vue组件的基本使用、全局与局部组件、父子组件通信及数据传递等内容,适合前端开发者学习参考。持续更新中,期待您的关注!🎉🎉🎉
vue学习第十章(组件开发)
|
13天前
|
JavaScript 前端开发
如何在 Vue 项目中配置 Tree Shaking?
通过以上针对 Webpack 或 Rollup 的配置方法,就可以在 Vue 项目中有效地启用 Tree Shaking,从而优化项目的打包体积,提高项目的性能和加载速度。在实际配置过程中,需要根据项目的具体情况和需求,对配置进行适当的调整和优化。
|
13天前
|
存储 缓存 JavaScript
如何在大型 Vue 应用中有效地管理计算属性和侦听器
在大型 Vue 应用中,合理管理计算属性和侦听器是优化性能和维护性的关键。本文介绍了如何通过模块化、状态管理和避免冗余计算等方法,有效提升应用的响应性和可维护性。
|
12天前
|
JavaScript 前端开发 UED
vue学习第二章
欢迎来到我的博客!我是一名自学了2年半前端的大一学生,熟悉JavaScript与Vue,目前正在向全栈方向发展。如果你从我的博客中有所收获,欢迎关注我,我将持续更新更多优质文章。你的支持是我最大的动力!🎉🎉🎉
|
12天前
|
JavaScript 前端开发 开发者
vue学习第一章
欢迎来到我的博客!我是瑞雨溪,一名热爱JavaScript和Vue的大一学生。自学前端2年半,熟悉JavaScript与Vue,正向全栈方向发展。博客内容涵盖Vue基础、列表展示及计数器案例等,希望能对你有所帮助。关注我,持续更新中!🎉🎉🎉
|
13天前
|
存储 缓存 JavaScript
在 Vue 中使用 computed 和 watch 时,性能问题探讨
本文探讨了在 Vue.js 中使用 computed 计算属性和 watch 监听器时可能遇到的性能问题,并提供了优化建议,帮助开发者提高应用性能。
|
13天前
|
存储 缓存 JavaScript
Vue 中 computed 和 watch 的差异
Vue 中的 `computed` 和 `watch` 都用于处理数据变化,但使用场景不同。`computed` 用于计算属性,依赖于其他数据自动更新;`watch` 用于监听数据变化,执行异步或复杂操作。
|
14天前
|
存储 JavaScript 开发者
Vue 组件间通信的最佳实践
本文总结了 Vue.js 中组件间通信的多种方法,包括 props、事件、Vuex 状态管理等,帮助开发者选择最适合项目需求的通信方式,提高开发效率和代码可维护性。
下一篇
无影云桌面