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

1 单文件组件

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

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

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

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

单文件组件的优点在于:

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

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

bash 复制代码
<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 指向当前组件的实例对象:

bash 复制代码
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 对象空间可以由函数名来访问:

javascript 复制代码
function Person() {}
console.log(Person.prototype) // 是一个对象

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

javascript 复制代码
function Person() {}
Person.prototype.name = 'prototype'
Person.prototype.sayHi = function () {}

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

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

那实例化对象怎么使用?

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

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

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

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

javascript 复制代码
function Person() {}
var p1 = new Person()
console.log(p1.__proto__ === Person.prototype) // true

我们发现实例对象的 __proto__ 和所属的构造函数的 prototype 是一个对象空间,我们可以通过构造函数名称来向 prototype 中添加成员。Person.prototype.name = 'prototype'

对象在访问的时候自己没有,可以自动去自己的 __proto__ 中查找

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

javascript 复制代码
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 中查找,那么每一个对象使用的函数,其实都是同一个函数。

javascript 复制代码
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 中找

那么两个实例化对象就是找到的一个方法,也是执行的一个方法。

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



相关推荐
王俊山IT33 分钟前
C++学习笔记----7、使用类与对象获得高性能(二)---- 理解对象生命周期(7)
开发语言·c++·笔记·学习
林九生1 小时前
【Redis】个人笔记
数据库·redis·笔记
OEC小胖胖1 小时前
MyBatis系统学习(四)——MyBatis的关联映射和缓存机制
java·后端·学习·缓存·mybatis·web
清流君1 小时前
【自动驾驶】控制算法(八)横向控制Ⅳ | 调试与优化——让车辆行驶更平稳!
人工智能·笔记·算法·自动驾驶·控制算法
QGC二次开发1 小时前
Vue3:mitt实现组件通信
前端·javascript·vue.js·vue
牢鹅出海1 小时前
Facebook开发者篇 - API拉取广告投放数据对接流程
经验分享·笔记·facebook
杳戢2 小时前
技术美术百人计划 | 《4.1 Bloom算法》笔记
人工智能·笔记·深度学习·计算机视觉·unity·图形渲染·技术美术
Pandaconda2 小时前
【计算机网络 - 基础问题】每日 3 题(十三)
开发语言·经验分享·笔记·后端·计算机网络·面试·职场和发展
达不溜方3 小时前
智谱清影 CogVideoX-2b:深度解析部署流程与高效使用指南
学习·创业创新·学习方法
customer083 小时前
【开源免费】基于SpringBoot+Vue.JS服装商城系统(JAVA毕业设计)
java·vue.js·spring boot·后端·开源