第1章:Vue核心概念——模板语法、响应式原理、组件系统、双向绑定

大家好,我是你们的前端老司机。

今天咱们来聊聊Vue最核心的四个概念。说实话,这四个东西搞明白了,Vue你就掌握了七成。我当年刚接触Vue时,就是被这四板斧给征服的。

1.1 模板语法:把HTML变成动态的

模板语法,说白了就是让你在HTML里写JavaScript表达式。Vue的模板是基于HTML的,但它加了一些“魔法调料”。

我最常用的就是插值表达式——双大括号 {{ }}。比如:

<div>{{ message }}</div>

这里的 message 会动态替换成数据里的值。嗯,这里要注意:插值里只能写单个表达式,不能写语句。比如 {{ if (ok) { return msg } }} 这种就不行。

除了插值,还有指令。指令是 v- 开头的特殊属性。我列几个最常用的:

  • v-bind:动态绑定属性。比如 v-bind:src="imageSrc",简写是 :src
  • v-if / v-else:条件渲染。符合条件才渲染DOM
  • v-for:列表渲染。循环生成DOM
  • v-on:事件绑定。比如 v-on:click="handleClick",简写是 @click
我的小习惯:能用简写就用简写。 :@ 写起来快,读起来也清晰。团队里统一风格就好。

1.2 响应式原理:Vue怎么知道数据变了?

这是Vue最神奇的地方。你改了数据,页面自动更新。怎么做到的?

Vue 2用的是Object.defineProperty,Vue 3换成了Proxy。原理其实不复杂:

  1. Vue会遍历数据对象的所有属性
  2. getter/setter 把它们变成“响应式的”
  3. 当数据被读取时,收集依赖(谁在用这个数据)
  4. 当数据被修改时,通知所有依赖去更新

举个例子:

// Vue 2 的响应式简化版
let data = { count: 0 }
let activeEffect = null

function defineReactive(obj, key) {
  let value = obj[key]
  const deps = new Set()
  
  Object.defineProperty(obj, key, {
    get() {
      if (activeEffect) deps.add(activeEffect)
      return value
    },
    set(newValue) {
      value = newValue
      deps.forEach(fn => fn())
    }
  })
}

defineReactive(data, 'count')
我曾经踩过的坑:Vue 2里,直接通过下标修改数组元素(比如 arr[0] = 'new')是不会触发更新的。因为Object.defineProperty无法监听数组索引的变化。后来Vue 3用Proxy解决了这个问题。

为什么会这样?因为Object.defineProperty只能拦截对象的属性读写,而Proxy可以拦截更多操作——包括数组的索引赋值、属性的新增删除等。

1.3 组件系统:搭积木的艺术

组件,就是把UI拆成独立可复用的模块。每个组件都有自己的模板、数据和逻辑。

我习惯把组件分成三类:

类型 特点 例子
页面级组件 对应路由,包含完整页面 HomePage, UserProfile
通用组件 可复用,与业务无关 Button, Modal, Table
业务组件 特定业务场景复用 UserCard, OrderList

组件之间怎么通信?最基础的是props(父传子)和emit(子传父)。

<!-- 父组件 -->
<ChildComponent 
  :title="pageTitle" 
  @update="handleUpdate" 
/>

<!-- 子组件 -->
<script>
export default {
  props: ['title'],
  emits: ['update'],
  methods: {
    doUpdate() {
      this.$emit('update', newData)
    }
  }
}
</script>
记住这个原则:数据流是单向的。父组件通过props往下传,子组件通过emit往上通知。别搞乱了,不然项目大了你会后悔的。

1.4 双向绑定:v-model的魔力

双向绑定,就是数据变了视图更新,视图变了数据也更新。Vue里用 v-model 实现。

你想想看,一个输入框:

<input v-model="username" />

这行代码等价于:

<input 
  :value="username" 
  @input="username = $event.target.value" 
/>

说白了,v-model 就是个语法糖。它帮你做了两件事:

  • 把数据绑定到 value 属性
  • 监听 input 事件,把新值写回数据

不同的表单元素,v-model 绑定的属性和事件不一样:

元素 属性 事件
input[type=text] value input
input[type=checkbox] checked change
select value change
textarea value input
自定义组件也能用v-model:Vue 3里,你可以在组件里通过 modelValue prop 和 update:modelValue emit 来实现。Vue 2则是 valueinput

我在项目中遇到过一个问题:多个表单字段需要双向绑定,但每个字段都要写 v-model 很烦。后来我用 computed 的 get/set 做了个统一处理,代码清爽多了。

<script>
export default {
  props: ['formData'],
  emits: ['update:formData'],
  computed: {
    localFormData: {
      get() {
        return this.formData
      },
      set(value) {
        this.$emit('update:formData', value)
      }
    }
  }
}
</script>

嗯,这四个概念是Vue的基石。模板语法让你写动态HTML,响应式原理让数据驱动视图,组件系统帮你组织代码,双向绑定简化了表单处理。搞懂它们,你就能写出像样的Vue应用了。

下一章,咱们聊聊Vue 3的新特性——Composition API。说实话,我第一次用的时候也觉得别扭,但用顺手后真香了。