FE_Vue学习笔记 - 组件的理解vue vc

本文介绍了Vue中的单文件组件,包括其组成部分(template,script,style),以及其优点如封装、模块化和团队协作。同时概述了VueComponent和VM的概念,强调了它们在组件化开发中的角色和区别。
摘要由CSDN通过智能技术生成

1 单文件组件

在Vue应用中,单文件组件(Single File Components)是一种特殊的文件格式,以 .vue 为后缀,它允许开发者在一个文件中定义一个Vue组件的全部内容。

每个单文件组件由三个部分组成:template(模板)、script(脚本)和style(样式)。这些部分分别代表Vue组件的结构、逻辑和样式。

具体而言,一个单文件组件的构成如下:

  • template部分:这部分使用HTML语法编写,包含了组件的HTML结构。
  • script部分:这部分包含JavaScript代码,定义了组件的逻辑和行为。这部分也包含了一个特殊的<template>标签,用于包含模板内容。
  • style部分:这部分包含CSS样式,用于定义组件的外观和样式。

单文件组件的优点在于:

  • 将模板、脚本和样式封装在一个文件中,方便管理和维护。
  • 可以在需要时导入到项目中,有助于代码的模块化和可重用性。
  • 每个组件都有独立的.vue文件,方便在团队中进行分工协作。

总的来说,单文件组件是Vue框架中一个重要的特性,它帮助开发者更高效地开发和管理复杂的用户界面。

<template>
  <div id="app">
    <input v-model="name" type="text"/>
    <p>Name: {{ name }}</p>
    <p>Reversed Name: {{ reversedName }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      name: 'John Doe'
    };
  },
  computed: {
    reversedName: function () {
      console.log('this => ', this)
      return this.name.split(' ').reverse().join(' ');
    }
  },
  mounted: function () {
    this.$watch('name', function (newVal, oldVal) {
      console.log('Name changed from ' + oldVal + ' to ' + newVal);
    });
  }
};
</script>

2 VueComponent

在Vue中,VueComponent是组件化开发的核心概念。VueComponent是一个构造函数,用于创建Vue组件。通过VueComponent,我们可以定义组件的属性、方法、生命周期钩子、计算属性等等。

在Vue中,组件是可复用的Vue实例,接受相同的选项对象(除了一些根特定的选项)并且可以拥有完全独立的作用域。组件可以扩展HTML元素,封装可重用的代码。在较高层面上,组件是自定义元素,通过Vue提供的全局API(vue-loader/vueify)进行注册,然后在HTML中就可以使用这些自定义元素了。

在VueComponent中,我们可以定义以下选项:

  • data:组件的数据对象,用于存储组件的状态。
  • props:组件的属性,用于接收来自父组件的数据。
  • methods:组件的方法,用于实现组件的功能。
  • computed:计算属性,根据组件的数据和属性计算得出的结果。
  • watch:监听器,用于监听组件的数据和属性的变化,并在变化时触发回调函数。
  • template:组件的模板,定义了组件的HTML结构。
  • components:子组件对象,用于在组件中使用其他组件。
  • lifecycle hooks:生命周期钩子函数,用于在组件的生命周期的不同阶段执行相应的逻辑。

通过VueComponent,我们可以将复杂的UI拆分成多个独立的、可复用的组件,提高代码的可维护性和可重用性。

在Vue组件的钩子函数中,this 关键字通常指向当前组件的实例对象。这个实例对象包含了组件的数据、方法、计算属性等信息。
在这里插入图片描述

例如,在 created 钩子函数中,this 指向当前组件的实例对象:

new Vue({  
  data: {  
    message: 'Hello, world!'  
  },  
  created: function() {  
    console.log(this.message); // 输出:Hello, world!  
  }  
});

在上面的例子中,this.message 表示组件实例对象的 message 属性。

但是,在某些情况下,this 的指向可能会发生变化,比如在回调函数或者箭头函数中。在这些情况下,需要格外小心,确保 this 指向正确的对象。可以使用箭头函数或者使用 bind 方法来确保 this 的正确指向。

关于this指向:

  1. Vue.extend({}) 组件配置中:

data函数、methods中的函数、watch中的函数、computed中的函数,他们的this均是VueComponent实例对象

  1. new Vue()配置中:

data函数、methods中的函数、watch中的函数、computed中的函数,他们的this均是Vue实例对象

3 VM

在Vue中,VM是ViewModel的缩写,是视图模型的意思,是连接View和Model的桥梁,负责业务逻辑处理,并对数据进行加工后交给View展示。通过Vue类创建的对象叫Vue实例化对象,这个对象就是MVVM模式中的VM层,模型通过它可以将数据绑定到页面上,视图可以通过它将数据映射到模型上。

4 既然vc和vm中的内容一样,为什么不能把vc和vm直接划上等号?

  1. vc是由VueComponent缔造的,vm是由Vue缔造的。这两个缔造的过程肯定不可能完全一样。
  2. 比如说在创建组件实例对象、传入配置项的时候,是不可以写el的,但是在创建vm的时候,配置对象中就可以写el。也就是说vm可以写自己为哪个容器服务,但是vc不能指定服务容器,只能跟着vm走。
  3. 再比如说,vc的数据配置项(data)就必须写成函数。可以说,它们俩身上99%的东西一样,但是有这1%就是不一样。就像是两个双胞胎,长得一模一样,但是不能说他们是同个人。

5 一个重要的内置关系- VueComponent.prototype.__proto__ === Vue.prototype

原型是Javascript中的继承的基础,JavaScript的继承就是基于原型的继承。每一个JS对象都可以获得自己的原型,通过原型可以共享函数对象和实例对象之间的属性和方法。

原型的出现,就是为了解决 构造函数 的缺点:

在这里插入图片描述
每一次new一个对象时,都会创建一份render()代码浪费资源。通过原型,我们提供了一个给对象添加函数的方法,不然构造函数只能给对象添加属性,不能合理的添加函数就太 LOW 了。

在这里插入图片描述
prototype 每一个函数天生自带一个成员 - prototype,是一个对象空间,即然每一个函数都有,构造函数也是函数,构造函数也有这个对象空间。这个 prototype 对象空间可以由函数名来访问:

function Person() {}
console.log(Person.prototype) // 是一个对象

即然是个对象,那么我们就可以向里面放入一些东西:

function Person() {}
Person.prototype.name = 'prototype'
Person.prototype.sayHi = function () {}

我们发现了一个叫做 prototype 的空间是和函数有关联的,并且可以向里面存储一些东西。

重点: 在函数的 prototype 里面存储的内容,不是给函数使用的,是给函数的每一个实例化对象使用的。

那实例化对象怎么使用?

每一个对象都天生自带一个成员,叫做__proto__,是一个对象空间,即然每一个对象都有,实例化对象也是对象,那么每一个实例化对象也有这个成员。这个 __proto__ 对象空间是给每一个对象使用的:

当你访问一个对象中的成员的时候,如果这个对象自己本身有这个成员,那么就会直接给你结果,如果没有,就会去 __proto__ 这个对象空间里面找,里面有的话就给你结果。

那么这个 __proto__ 又指向哪里呢?

这个对象是由哪个构造函数 new 出来的,那么这个对象的 __proto__ 就指向这个构造函数的 prototype。

function Person() {}
var p1 = new Person()
console.log(p1.__proto__ === Person.prototype) // true

我们发现实例对象的 __proto__ 和所属的构造函数的 prototype 是一个对象空间,我们可以通过构造函数名称来向 prototype 中添加成员。Person.prototype.name = 'prototype'
对象在访问的时候自己没有,可以自动去自己的 __proto__ 中查找

我们可以把函数放在构造函数的 prototype 中,实例化对象访问的时候,自己没有,就会自动去 __proto__ 中找。

function Person() {}Person.prototype.sayHi = function () {
   console.log('hello Person')
}var p1 = new Person()
p1.sayHi()

1 p1 自己没有 sayHi 方法,就会去自己的 __proto__ 中查找 p1.__proto__ 就是 Person.prototype
我们又向 Person.prototype 中添加了 sayHi 方法 所以 p1.sayHi 就可以执行了

到这里,当我们实例化多个对象的时候,每个对象里面都没有方法,都是去所属的构造函数的 protottype 中查找,那么每一个对象使用的函数,其实都是同一个函数。

function Person() {}Person.prototype.sayHi = function () {
   console.log('hello')
}var p1 = new Person()
var p2 = new Person()
​
console.log(p1.sayHi === p2.sayHi)

p1 是 Person 的一个实例
p2 是 Person 的一个实例
也就是说 p1.__proto__p2.__proto__ 指向的都是 Person.prototype
当 p1 去调用 sayHi 方法的时候是去 Person.prototype 中找
当 p2 去调用 sayHi 方法的时候是去 Person.prototype 中找
那么两个实例化对象就是找到的一个方法,也是执行的一个方法。

总结: 当我们写构造函数的时候,属性我们直接写在构造函数体内,方法我们写在原型上。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值