pin_drop当前位置:知识文库 ❯ 图文

框架集成:08 HTML与Vue集成基础 - 详细教程与实战指南

一、教程简介

Vue是由尤雨溪创建的渐进式JavaScript框架,其设计理念是"渐进式框架"——你可以根据项目需求逐步引入Vue的功能。Vue与HTML的集成方式非常直观,通过模板语法直接在HTML中声明式地绑定数据和事件。

本教程将介绍Vue的简介、CDN引入方式、创建Vue应用、Vue与DOM的关系、响应式原理基础以及模板编译过程,帮助你理解Vue如何增强HTML的能力。


二、Vue简介与CDN引入

Vue的核心特点是渐进式、易上手、模板语法直观

  • 渐进式:按需引入,从库到框架

  • 模板语法:HTML增强,直观易学

  • 响应式:数据变化自动更新视图

  • 组件化:可复用的UI构建块

CDN引入方式

代码示例

<!-- Vue 3 开发版本 -->
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>

<!-- Vue 3 生产版本 -->
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>

<!-- 使用ES Module -->
<script type="module">
  import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js';
</script>

第一个Vue应用

代码示例

<div id="app">
  <p>当前时间:{{ currentTime }}</p>
  <p>计数器:{{ count }}</p>
  <button @click="increment">+ 增加</button>
  <button @click="decrement">- 减少</button>
  <p v-if="count > 5">计数器已超过5!</p>
  <p v-else>计数器未超过5</p>
</div>

<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
  const { createApp, ref, onMounted, onUnmounted } = Vue;

  createApp({
    setup() {
      const count = ref(0);
      const currentTime = ref(new Date().toLocaleTimeString());
      let timer = null;

      function increment() { count.value++; }
      function decrement() { count.value--; }

      onMounted(() => {
        timer = setInterval(() => {
          currentTime.value = new Date().toLocaleTimeString();
        }, 1000);
      });

      onUnmounted(() => {
        clearInterval(timer);
      });

      return { count, currentTime, increment, decrement };
    }
  }).mount('#app');
</script>

三、创建Vue应用

Vue 3使用createApp API创建应用实例:

代码示例

const { createApp, ref, computed, reactive } = Vue;

const app = createApp({
  setup() {
    // 响应式状态
    const newUser = ref('');
    const users = reactive([
      { id: 1, name: '张三', role: 'admin' },
      { id: 2, name: '李四', role: 'user' },
      { id: 3, name: '王五', role: 'user' }
    ]);
    let nextId = 4;

    // 计算属性
    const adminCount = computed(() => 
      users.filter(u => u.role === 'admin').length
    );
    const userCount = computed(() => 
      users.filter(u => u.role === 'user').length
    );

    // 方法
    function addUser() {
      const name = newUser.value.trim();
      if (!name) return;
      users.push({
        id: nextId++,
        name: name,
        role: 'user'
      });
      newUser.value = '';
    }

    function removeUser(id) {
      const index = users.findIndex(u => u.id === id);
      if (index > -1) users.splice(index, 1);
    }

    return { newUser, users, adminCount, userCount, addUser, removeUser };
  },
  template: `
    <div>
      <h3>用户管理系统</h3>
      <div>
        管理员: <strong>{{ adminCount }}</strong>
        普通用户: <strong>{{ userCount }}</strong>
      </div>
      <input v-model="newUser" @keyup.enter="addUser" />
      <button @click="addUser">添加用户</button>
      <ul>
        <li v-for="user in users" :key="user.id">
          {{ user.name }} - {{ user.role }}
          <button @click="removeUser(user.id)">删除</button>
        </li>
      </ul>
    </div>
  `
});

app.mount('#app');

四、Vue与DOM的关系

Vue通过响应式系统追踪数据变化,自动更新DOM:

Vue的更新流程

1. 数据变更 → 2. 侦听器触发 → 3. 虚拟DOM Diff → 4. 最小化DOM更新

代码示例

const { createApp, ref, computed } = Vue;

createApp({
  setup() {
    const keyword = ref('');
    const items = [
      'HTML5 语义化标签', 'CSS3 动画与过渡', 'JavaScript ES6+',
      'Vue 3 Composition API', 'React Hooks', 'Angular 依赖注入'
    ];

    const filteredItems = computed(() => {
      if (!keyword.value.trim()) return items;
      const kw = keyword.value.toLowerCase();
      return items.filter(item => item.toLowerCase().includes(kw));
    });

    function highlightText(text) {
      if (!keyword.value.trim()) return text;
      const regex = new RegExp(`(${keyword.value})`, 'gi');
      return text.replace(regex, '<span class="highlight">$1</span>');
    }

    return { keyword, items, filteredItems, highlightText };
  }
}).mount('#app');

五、响应式原理基础

Vue 3使用Proxy实现响应式系统:

代码示例

const { createApp, ref, reactive, watchEffect, computed, watch } = Vue;

createApp({
  setup() {
    // ref: 基本类型的响应式
    const count = ref(0);
    const message = ref('Hello Vue');

    // reactive: 对象的响应式
    const user = reactive({
      name: '张三',
      age: 25,
      skills: ['HTML', 'CSS', 'JavaScript']
    });

    // computed: 计算属性
    const skillCount = computed(() => user.skills.length);
    const userInfo = computed(() => 
      `${user.name}, ${user.age}岁, ${skillCount.value}项技能`
    );

    // watchEffect: 自动追踪依赖
    watchEffect(() => {
      console.log(`count变化: ${count.value}`);
    });

    // watch: 明确指定监听
    watch(() => user.age, (newVal, oldVal) => {
      console.log(`user.age: ${oldVal} → ${newVal}`);
    });

    return { count, message, user, skillCount, userInfo };
  }
}).mount('#app');

Vue 3响应式原理(Proxy)

代码示例

// Vue 3 使用 Proxy 实现响应式
const state = new Proxy(target, {
  get(target, key) {
    track(target, key);  // 追踪依赖
    return target[key];
  },
  set(target, key, value) {
    target[key] = value;
    trigger(target, key);  // 触发更新
    return true;
  }
});

// ref 的实现原理
function ref(value) {
  return new Proxy({ value }, {
    get(target, key) {
      track(target, 'value');
      return target[key];
    },
    set(target, key, newVal) {
      target[key] = newVal;
      trigger(target, 'value');
      return true;
    }
  });
}

六、模板编译

Vue模板在运行时或构建时被编译为渲染函数

编译流程

模板字符串 → AST抽象语法树 → 渲染函数 → 虚拟DOM → 真实DOM

模板到渲染函数的转换

代码示例

<!-- 模板写法 -->
<div class="app">
  <h1>{{ title }}</h1>
  <p v-if="show">{{ message }}</p>
  <ul>
    <li v-for="item in items" :key="item.id">
      {{ item.name }}
    </li>
  </ul>
  <button @click="handleClick">点击</button>
</div>

代码示例

// 编译后的渲染函数
function render(_ctx) {
  return h('div', { class: 'app' }, [
    h('h1', _ctx.title),
    _ctx.show ? h('p', _ctx.message) : null,
    h('ul', _ctx.items.map(item =>
      h('li', { key: item.id }, item.name)
    )),
    h('button', { onClick: _ctx.handleClick }, '点击')
  ])
}
特性 运行时编译 预编译(构建工具)
编译时机 浏览器中运行时 构建时
包体积 需要包含编译器(+30KB) 只需运行时(~10KB)
性能 首次渲染较慢 首次渲染快
适用场景 CDN引入、原型开发 生产项目

七、浏览器兼容性

特性 Chrome Firefox Safari Edge 说明
Vue 3 60+ 60+ 12+ 79+ 需ES2015+和Proxy
Proxy 49+ 18+ 10+ 12+ 响应式系统基础
Composition API 60+ 60+ 12+ 79+ Vue 3核心API
模板编译 60+ 60+ 12+ 79+ 运行时编译器
ES Modules 61+ 60+ 11+ 16+ ESM版本依赖

八、注意事项与最佳实践

  • 生产环境使用预编译:使用Vite或Vue CLI构建项目,避免运行时编译的开销

  • 理解ref和reactive的区别:ref用于基本类型,reactive用于对象;ref需要.value访问

  • 避免直接解构reactive对象:解构会丢失响应性,使用toRefs转换

  • 计算属性有缓存:computed只在依赖变化时重新计算,方法每次都执行

  • Vue 3不再支持IE11:因为Proxy无法polyfill

  • 使用template选项或SFC:CDN方式可用template选项,项目开发推荐SFC


九、代码规范示例

代码示例

// 不推荐:解构reactive丢失响应性
const user = reactive({ name: '张三', age: 25 });
const { name, age } = user; // 丢失响应性!

// 推荐:使用toRefs
import { toRefs } from 'vue';
const { name, age } = toRefs(user); // 保持响应性

// 不推荐:在模板中使用复杂表达式
// <p>{{ items.filter(i => i.active).map(i => i.name).join(', ') }}</p>

// 推荐:使用计算属性
const activeNames = computed(() =>
  items.filter(i => i.active).map(i => i.name).join(', ')
);
// <p>{{ activeNames }}</p>

// 不推荐:直接修改props
props.count++; // 不要修改!

// 推荐:通过emit通知父组件
emit('update:count', props.count + 1);

十、常见问题与解决方案

常见问题

Vue 2和Vue 3有什么主要区别?

Vue 3引入了Composition API(setup函数)、使用Proxy替代Object.defineProperty实现响应式、支持Fragment(多根节点)、Teleport、Suspense等新特性。性能也有显著提升。

ref的.value什么时候需要写?

在JavaScript中访问ref值时需要.value,在模板中自动解包不需要.value。例如:setup中count.value++,模板中{{ count }}。

Vue的模板和React的JSX哪个更好?

没有绝对的好坏。Vue模板更接近HTML,学习成本低,有编译时优化;JSX更灵活,是完整的JavaScript表达能力。选择取决于团队偏好和项目需求。

为什么Vue 3不支持IE11?

Vue 3的响应式系统基于Proxy实现,而Proxy无法在IE11中polyfill。如果需要支持IE11,应使用Vue 2。

CDN引入Vue时如何组织代码?

小型项目可以在单个HTML文件中使用template选项;中大型项目建议使用ES Module方式按需引入,或使用Vite构建。


十一、总结

本教程介绍了Vue与HTML集成的基础知识。Vue通过CDN可以快速引入,使用createApp创建应用实例。Vue 3的Composition API提供了更灵活的代码组织方式,refreactive是响应式数据的基础。Vue的响应式系统基于Proxy实现,当数据变化时自动触发DOM更新。模板编译将HTML模板转换为渲染函数,生产环境应使用预编译以获得更好的性能。Vue的渐进式设计让你可以根据项目需求逐步引入功能,从简单的CDN引入到完整的单文件组件开发。

标签: Vue入门 HTML集成 响应式 Composition API 模板编译 Proxy

本文涉及AI创作

内容由AI创作,请仔细甄别

list快速访问

上一篇: 框架集成:07 React样式与HTML - 详细教程与实战指南 下一篇: 框架集成:09 Vue模板语法与HTML - 详细教程与实战指南

poll相关推荐