Vue2_Vue 实例

Vue 实例

image-20250124163102181

创建一个 Vue 实例

每个 Vue 应用都是通过用 Vue 函数创建一个新的 Vue 实例开始的:

var vm = new Vue({
  // 选项
})

Vue 设计受到了 MVVM模型启发,所以文档常用 vm (ViewModel 的缩写) 这个变量名表示 Vue 实例


现在我给出一个标准 HTML 文档结构

这样我们的示例可以方便放入

<!DOCTYPE html> <!-- 声明文档类型为 HTML5 -->
<html lang="zh-CN"> <!-- 根元素,定义页面语言 -->
<head>
  <!-- 元数据区(用户不可见) -->
  <meta charset="UTF-8"> <!-- 字符编码 -->
  <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- 响应式必备 -->
  <title>页面标题</title> <!-- 浏览器标签页标题 -->
  <link rel="stylesheet" href="styles.css"> <!-- 引入外部 CSS -->
  <script src="script.js" defer></script> <!-- 引入 JavaScript(defer 延迟加载) -->
</head>
<body>
  <!-- 用户可见内容区 -->
  <header>网站头部(LOGO/导航)</header>
  
  <nav>
    <a href="#home">首页</a>
    <a href="#news">新闻</a>
  </nav>

  <main> <!-- 页面核心内容 -->
    <article> <!-- 独立内容区块(如博客文章) -->
      <h1>主标题</h1>
      <section> <!-- 内容分组 -->
        <h2>子标题</h2>
        <p>段落文本</p>
        <img src="image.jpg" alt="图片描述">
      </section>
    </article>

    <aside>侧边栏(广告/相关链接)</aside>
  </main>

  <footer>页脚(版权/联系方式)</footer>
</body>
</html>

解释一下 head 中的元数据,元数据 = 数据的信息说明书,也就是用来描述其他数据特征的数据,类似商品标签

我们再给出一个类似的思维导图,这个思维导图中,body 里面还写了 script

内容与上面代码不完全一致,但意思表达出来了

HTML
head
body
meta
title
link
script
header
main
footer
nav
section
article
h1
p
h2
p
p
script

当我们创建一个 Vue 实例的时候,可以传入一个选项对象

比如这个例子里面的对象

new Vue({
  // 选项对象
  el: '#app',              // 指定 Vue 实例挂载的 DOM 元素
  data: {                  // 存储数据
    message: 'Hello Vue!'
  },
  methods: {               // 定义方法
    greet() {
      console.log('Hello World!');
    }
  },
  computed: {              // 定义计算属性
    reversedMessage() {
      return this.message.split('').reverse().join('');
    }
  },
  mounted() {              // 生命周期钩子
    console.log('Vue instance mounted');
  }
});

而使用这些选项的目的是为了创建我们想要的行为

当然文档中有完整的选项列表, API 文档

一个 Vue 应用由

  • 一个通过 new Vue 创建的根 Vue 实例
  • 以及可选的嵌套的、可复用的组件树

组成


举个栗子🌰:

一个 todo 应用的组件树可以是这样

根实例
└─ TodoList
   ├─ TodoItem
   │  ├─ TodoButtonDelete
   │  └─ TodoButtonEdit
   └─ TodoListFooter
      ├─ TodosButtonClear
      └─ TodoListStatistics

根实例通过 props 传递 todos 数据给 TodoList

TodoItem 则循环传递单个 todo 数据

TodoButtonDelete、TodoButtonEdit 则通过事件 emit 触发

TodoListFooter 内可以通过 props 接收统计信息

总之,所有的 Vue 组件都是 Vue 实例,并且接受相同的选项对象 (一些根实例特有的选项除外)

数据与方法

当一个 Vue 实例被创建时,它将 data 对象中的所有的 property 加入到 Vue 的响应式系统

解释一下,在 JS 中,对象是由 { key: value } 组成的

每个 key 就是对象的一个 property(属性)

当这些 property 的值发生改变时,视图将会产生“响应”,即匹配更新为新的值

// 我们的数据对象
var data = { a: 1 }

// 该对象被加入到一个 Vue 实例中
var vm = new Vue({
  data: data
})
image-20250124150000130

当这些数据改变时,视图会进行重渲染

注意:只有当实例创建时就已经存在 data 中的 property 才是响应式

比如这时候我们在加入一个新的 property

vm.b = 'hi'

那么 b 的改动不会触发任何的视图更新

所有如果我们后面还需要用到 property,一开始它是空或者不存在,那么我们可以设置一些初始值

例如:

data: {
  newTodoText: '',
  visitCount: 0,
  hideCompletedTodos: false,
  todos: [],
  error: null
}

不过还有方法可以阻值修改现有的 property,那就是 Object.freeze()

意味着响应系统无法再追踪变化

image-20250124151511776

除了数据 property,Vue 实例还暴露了一些有用的实例 property 与方法

其实就是内置的 property,Vue 自动挂载到实例上的工具属性和方法

它们都有前缀 $,以便与用户定义的 property 区分开来

比如说:

var data = { a: 1 }
var vm = new Vue({
  el: '#example',
  data: data
})
// 访问 data 对象
vm.$data === data // => true
// 访问根 DOM 元素
vm.$el === document.getElementById('example') // => true

// $watch 是一个实例方法,监听数据变化
vm.$watch('a', function (newValue, oldValue) {
  // 这个回调将在 `vm.a` 改变后调用
})

API 参考,可以通过链接查阅到完整的实例 property 和方法的列表

实例生命周期钩子

每个 Vue 实例在被创建时都要经过一系列的初始化过程

例如:

  • 需要设置数据监听
  • 编译模板
  • 将实例挂载到 DOM 并在数据变化时更新 DOM 等

同时在这个过程中也会运行一些叫做生命周期钩子的函数

这样我们可以在不同阶段添加自己的代码

比如:created 钩子可以用来在一个实例被创建之后执行代码

image-20250124171830809

还有一些其他钩子,在实例生命周期的不同阶段被调用

如: mountedupdateddestroyed

生命周期钩子的 this 上下文指向调用它的 Vue 实例

❗注意

不要在选项 property 或回调上使用箭头函数

比如 created: () => console.log(this.a)vm.$watch('a', newValue => this.myMethod())

因为箭头函数并没有 thisthis 会作为变量一直向上级词法作用域查找,直至找到为止,经常导致 Uncaught TypeError: Cannot read property of undefinedUncaught TypeError: this.myMethod is not a function 之类的错误

模板编译

我这里简单讲解一下模板编译

模板编译通常分为三个核心阶段,分别是解析、优化和代码生成

  1. 解析
    • 步骤
      • 使用 HTML 解析器分析模板结构
      • 识别 Vue 特有的语法(指令、插值、组件标签等)
      • 生成 抽象语法树(Abstract Syntax Tree, AST)

举个例子,解析 <div>{{ message }}</div>

输出示例:

{
  type: 1, // 元素节点
  tag: 'div',
  children: [{
    type: 2, // 文本节点
    expression: '_s(message)' // 插值表达式转换后的代码
  }]
}
  1. 优化

    • 通常会遍历 AST(抽象语法树),标记静态节点
    • 通过复用静态节点可以减少内存消耗
  2. 代码生成

    • 输入:优化后的 AST

    • 过程:

      • 将 AST 转换为可执行的 JS 代码
      • 生成 render 函数字符串
    • 输出示例:

      function render() {
        return _c('div', [_v(_s(message))])
      }
      

编译后,生成的 render 函数会在以下场景执行:

  1. 首次渲染:生成虚拟 DOM → 映射为真实 DOM
  2. 数据变更:重新执行 render 生成新虚拟 DOM → Diff 算法比对差异 → 更新真实 DOM

生命周期图示

下面就来到了面试官爱问的问题,Vue 的生命周期是怎么样的

下图展示了实例的生命周期

Vue 实例生命周期

英文的看着有点累,再上个中文的

img

END

本文主要介绍 Vue 实例,包括如何创建一个 Vue 实例、实例中的数据和方法、实例生命周期钩子以及生命周期的图示,实例的数据和方法主要涉及数据 data 对象,在实例生命周期钩子中简单讲解了模板编译

posted @   goicandoit  阅读(7)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示