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 }, '点击')
])
}七、浏览器兼容性
八、注意事项与最佳实践
-
生产环境使用预编译:使用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提供了更灵活的代码组织方式,ref和reactive是响应式数据的基础。Vue的响应式系统基于Proxy实现,当数据变化时自动触发DOM更新。模板编译将HTML模板转换为渲染函数,生产环境应使用预编译以获得更好的性能。Vue的渐进式设计让你可以根据项目需求逐步引入功能,从简单的CDN引入到完整的单文件组件开发。
本文涉及AI创作
内容由AI创作,请仔细甄别