Vue.js 介绍
Vue.js 是一个用于构建用户界面的渐进式框架。它的核心库专注于视图层,易于学习,与其他库或已有项目结合非常灵活。Vue 采用了 MVVM(Model-View-ViewModel)模式,使得开发者能够通过声明式渲染和数据双向绑定来简化开发工作。
环境搭建
使用 CDN 快速体验
你可以在 HTML 文件中直接通过 CDN 引入 Vue.js,这样可以快速开始体验 Vue.js 的基本功能。
确保你在 <head>
部分引入了 Vue.js。如果你使用的是 CDN,确保 URL 正确,并且在 Vue.js 加载完成后再创建 Vue 实例。正确的引用应该像这样:
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
示例 HTML 源码:
<!DOCTYPE html>
<html>
<head>
<title>Vue.js 入门示例</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script> <!-- 引入 Vue.js -->
</head>
<body>
<div id="app"> <!-- Vue 实例挂载的 DOM 元素 -->
<h1>{{ message }}</h1> <!-- 数据绑定显示 -->
</div>
<script>
new Vue({
el: '#app', // 将 Vue 实例挂载到 id 为 app 的 DOM 元素上
data: {
message: 'Hello Vue!' // Vue 实例的数据对象
}
});
</script>
</body>
</html>
使用 Vue CLI 创建项目
Vue CLI 是一个官方提供的工具,可以帮助你快速生成 Vue 项目结构。
确保你已经在电脑上安装了Node.js。Node.js 的安装包中会包含 npm(Node 包管理器),你可以使用 npm 来安装 Vue CLI。输入以下命令检查 Node.js 和 npm 是否安装成功:
node -v
npm -v
安装 Vue CLI:
npm install -g @vue/cli
创建新项目:
使用命令为你的应用创建新的项目(假设项目名为 my-project
):
vue create my-project
进入项目目录并启动开发服务器:
cd my-project
npm run serve
可以在 VSCode 中点击左边的“文件”菜单,选择“打开文件夹”,找到并选择刚刚创建的项目文件夹 my-project
来进行 Vue 开发
了解 Vue.js 核心概念
一. 组件(Components)
组件是 Vue.js 的核心概念之一,Vue 应用由组件构建而成。组件可以是小的功能单元,也可以是大型的应用结构。每个组件都有自己的 HTML 模板、样式和逻辑。
示例:
Vue.component('my-component', {
template: '<p>这是一个组件!</p>'
});
二. 模板语法(Template Syntax)
Vue 使用一个简洁的模板语法,它允许你在 HTML 的标记中嵌入 JavaScript 表达式。Vue 的模板在内部被编译成虚拟 DOM 渲染。
<div id="app">
<h1>{{ greeting }}</h1> <!-- 使用大括号绑定数据 -->
</div>
<script>
new Vue({
el: '#app',
data: {
greeting: '欢迎使用 Vue.js!' // 绑定数据
}
});
</script>
三. 数据绑定(Data Binding)
数据绑定(Data Binding)是 Vue.js 的一个核心概念,它允许你将 Vue 实例中的数据与 DOM 元素进行同步,构建动态的用户界面。通过数据绑定,Vue.js 实现了单向和双向数据绑定,使得开发变得更加简单和高效。以下是关于数据绑定的详细知识点:
1. 单向数据绑定
单向数据绑定是指数据流向 DOM,在 Vue 实例中定义的数据会被渲染到视图中。当视图中的数据改变时,它不会影响 Vue 实例内的数据。
示例:
<div id="app">
<p>{{ message }}</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
<script>
new Vue({
el: '#app',
data: {
message: '欢迎使用 Vue.js!'
}
});
</script>
在这个例子中,message
的值渲染到 <p>
标签中,内容会显示为 "欢迎使用 Vue.js!"。
2. 双向数据绑定
双向数据绑定允许你将 DOM 元素的值与 Vue 实例中的数据同步变化。这在表单控件(输入框、复选框、选择框等)中尤其常用。
双向数据绑定可以通过 v-model
指令来实现,方便与表单输入元素的交互。
主要用途:v-model
是用于实现表单输入元素的双向数据绑定。例如,您可以将输入框中的值与 Vue 实例中的数据同步。
典型用法:常用于 input、textarea 和 select 元素。
示例:
<div id="app">
<input v-model="inputValue" placeholder="输入内容"> <!-- 双向绑定 -->
<p>你输入的内容是: {{ inputValue }}</p> <!-- 显示绑定内容 -->
</div>
<script>
new Vue({
el: '#app',
data: {
inputValue: '' // 定义输入值
}
});
</script>
3. 计算属性
计算属性是基于依赖的数据进行计算和缓存的属性,通常用于需要进行数据处理的场景。计算属性不是实时更新的,但会在依赖的数据变化时重新计算。
示例:
<div id="app">
<p>原文字串:{{ originalText }}</p>
<p>反转后的字符串:{{ reversedText }}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
originalText: 'Hello Vue!'
},
computed: {
reversedText() {
return this.originalText.split('').reverse().join('');
}
}
});
</script>
4. 侦听器
侦听器可以监控 Vue 实例中的数据变化,并在数据变化时执行额外的代码。通常用于处理复杂或者开销较大的操作。
<div id="app">
<input v-model="number" placeholder="输入一个数字">
<p>平方:{{ square }}</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
<script>
new Vue({
el: '#app',
data: {
number: 0
},
computed: {
square() {
return this.number * this.number; // 计算平方
}
},
watch: {
number(newValue) {
console.log(`数字已变为:${newValue}`);
}
}
});
</script>

用于动态绑定的指令
- v-bind:用于动态绑定 HTML 属性
- v-if、v-else-if、v-else:用于条件渲染
- v-for:用于循环渲染列表
- v-show:用于控制元素的显隐
v-bind:用于动态绑定 HTML 属性
典型用法:常用于设置非表单元素的属性,也可以用于样式与类的动态绑定。
1. 绑定 HTML 属性
使用 v-bind
指令可以将 Vue 数据属性的值绑定到 HTML 元素的属性上。例如,你可以用它来动态设置 href
、src
、class
和 style
等 HTML 属性。
示例:
<div id="app">
<a v-bind:href="url">点击这里</a>
<img v-bind:src="imageSrc" alt="动态图片">
</div>
<script>
new Vue({
el: '#app',
data: {
url: 'https://www.example.com',
imageSrc: 'https://www.example.com/image.jpg'
}
});
</script>
在上面的示例中,href
属性和 src
属性的值都绑定到 Vue 实例中的数据属性。
简写方式
在 Vue 中,可以使用 :
作为 v-bind
的简写。上面的代码可以简化为:
<div id="app">
<a :href="url">点击这里</a>
<img :src="imageSrc" alt="动态图片">
</div>
2. 绑定 CSS 类
v-bind
也可以用于动态绑定 CSS 类。这在需要根据某些条件来更改样式时非常有用。
示例:
<div id="app">
<button :class="{ active: isActive }">点击我</button>
<button @click="toggleActive">切换状态</button>
</div>
<script>
new Vue({
el: '#app',
data: {
isActive: false // 初始情况下按钮不活跃
},
methods: {
toggleActive() {
this.isActive = !this.isActive; // 切换按钮活跃状态
}
}
});
</script>
<style>
.active {
background-color: green; /* 设置活跃状态下的背景颜色 */
color: white;
}
</style>
在这个例子中,按钮的类名会根据 isActive
的值来变化。点击按钮会切换 isActive
的值,从而修改按钮的样式。

3. 绑定行内样式
v-bind
还可以用于绑定行内样式,允许你动态设置样式对象。
<div id="app">
<div :style="{ color: textColor, fontSize: fontSize }">这是有动态样式的文本</div>
<button @click="changeStyle">改变样式</button>
</div>
<script>
new Vue({
el: '#app',
data: {
textColor: 'blue',
fontSize: '20px'
},
methods: {
changeStyle() {
this.textColor = this.textColor === 'blue' ? 'red' : 'blue'; // 切换文本颜色
this.fontSize = this.fontSize === '20px' ? '30px' : '20px'; // 切换文本大小
}
}
});
</script>
在这个示例中,文本的颜色和大小是动态的,并可以通过按钮点击进行切换。
v-if、v-else-if、v-else:用于条件渲染
1. v-if 的基本使用
v-if
指令用于根据某个条件来决定是否渲染一个元素或组件。如果条件为真,该元素将被渲染;如果条件为假,元素则不会出现在 DOM 中。
基本语法:
<v-if="condition">{{ content }}</v-if>
这里的 condition
是一个表达式,当它的值为真时,内容 content
将被渲染。
2. 示例代码
下面是一个简单的示例,展示了如何使用 v-if
来控制一个段落的显示与隐藏:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue.js v-if 示例</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
</head>
<body>
<div id="app">
<p v-if="isVisible">这个段落会根据 isVisible 的值显示或隐藏。</p>
<button @click="toggleVisibility">切换可见性</button>
</div>
<script>
new Vue({
el: '#app',
data: {
isVisible: true // 控制段落的显示与隐藏
},
methods: {
toggleVisibility() {
this.isVisible = !this.isVisible; // 切换 isVisible 的值
}
}
});
</script>
</body>
</html>
在这个示例中:
- 当
isVisible
为true
时,段落会被渲染。 - 当用户点击按钮时,
toggleVisibility
方法会切换isVisible
的值,从而控制段落的显示和隐藏。
3. 多重 v-if
条件
你还可以在同一个元素中使用 v-else
和 v-else-if
来处理多个条件。
<p v-if="value === 1">Value is 1</p>
<p v-else-if="value === 2">Value is 2</p>
<p v-else>Value is neither 1 nor 2</p>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue.js v-if Demo</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script> <!-- 引入 Vue.js -->
</head>
<body>
<div id="app">
<h1>条件渲染示例</h1>
<input type="number" v-model.number="value" placeholder="输入一个数字"> <!-- 使用 .number 修饰符 -->
<p v-if="value === 1">Value is 1</p>
<p v-else-if="value === 2">Value is 2</p>
<p v-else-if="value !== null">Value is neither 1 nor 2</p> <!-- 确保只有当 value 不是 null 时才显示这个 -->
<p v-else>Please enter a value</p> <!-- 当没有输入值时 -->
</div>
<script>
new Vue({
el: '#app',
data: {
value: null // 初始化值为空
}
});
</script>
</body>
</html>
在输入框中输入数字:
- 输入
1
,页面会显示 "Value is 1"。 - 输入
2
,页面会显示 "Value is 2"。 - 输入其他数字,如
3
,页面会显示 "Value is neither 1 nor 2"。 - 如果不输入任何值,页面会显示 "Please enter a value"。
v-for:用于循环渲染列表
v-for
是 Vue.js 中用于循环渲染列表的指令。它用于将数组或对象中的数据动态渲染为多个 DOM 元素。
1. v-for
的基本用法
v-for="(item, index) in items"
item
:代表当前循环的项(数组中的元素)。index
:可选参数,当前项的索引。items
:要进行循环的数据,可以是数组或对象。
2. 示例
下面是一个简单的使用 v-for
的示例,展示如何循环遍历一个数组并渲染列表项。
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>v-for 示例</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
</head>
<body>
<div id="app">
<h1>水果列表</h1>
<ul>
<li v-for="(fruit, index) in fruits" :key="index">
{{ index + 1 }}. {{ fruit }}
</li>
</ul>
<button @click="addFruit">添加水果</button>
</div>
<script>
new Vue({
el: '#app',
data: {
fruits: ['苹果', '香蕉', '橙子'] // 初始化水果数组
},
methods: {
addFruit() {
this.fruits.push('新水果'); // 添加新水果
}
}
});
</script>
</body>
</html>
在这个示例中:
- 创建了一个水果列表,使用
v-for
指令循环遍历fruits
数组。 - 在
<li>
内部,我们显示水果的索引和名称。 - 使用
:key
属性进行列表项的唯一标识,建议始终提供这个属性以提高性能和避免异常。
3. 使用对象进行 v-for
循环
你也可以遍历对象的属性,使用以下语法:
v-for="(value, key) in object"
示例:
<div id="app">
<h1>信息列表</h1>
<ul>
<li v-for="(value, key) in info" :key="key">
{{ key }}: {{ value }}
</li>
</ul>
</div>
<script>
new Vue({
el: '#app',
data: {
info: {
姓名: '张三',
年龄: 28,
职业: '程序员'
}
}
});
</script>

4. 嵌套 v-for
v-for
可以嵌套在其他 v-for
中,用于处理多维数组。
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>v-for 示例</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script> <!-- 引入 Vue.js -->
</head>
<body>
<div id="app">
<h1>分类列表</h1>
<ul>
<li v-for="(category, index) in categories" :key="index">
<strong>{{ category.name }}</strong>
<ul>
<li v-for="(item, itemIndex) in category.items" :key="itemIndex">
{{ item }}
</li>
</ul>
</li>
</ul>
</div>
<script>
new Vue({
el: '#app',
data: {
categories: [
{ name: '水果', items: ['苹果', '香蕉', '橙子'] },
{ name: '蔬菜', items: ['胡萝卜', '西兰花'] }
]
}
});
</script>
</body>
</html>

注意事项
- 使用
key
属性:当使用v-for
渲染列表时,建议为每个列表项提供一个唯一的key
。这样可以优化性能,确保 Vue.js 能有效地跟踪元素,减少不必要的渲染。 - 列表项的顺序:如果数据是可变的(如添加或删除项目),使用唯一的
key
属性可以让 Vue.js 正确识别每个元素,避免出现错误的顺序或状态。 - 循环嵌套:
v-for
可以嵌套使用来处理复杂的数据结构,比如二维数组或对象,但要小心避免过多嵌套,使逻辑变得复杂。
Methods
基本概念
methods
是 Vue 实例的一个属性,用于定义要在组件中调用的函数。这些方法可以用于处理用户交互、事件,以及其他逻辑。
在 Vue 实例中,你可以通过 methods
属性定义多个方法,语法如下:
new Vue({
el: '#app',
data: {
// 数据属性
},
methods: {
methodName() {
// 方法逻辑
}
}
});
1. 定义方法
methods: {
increment() {
this.count++; // 每次调用时增加 count 的值
}
}
2. 绑定事件
使用 @
或 v-on
指令将方法与 DOM 元素的事件绑定在一起。例如,你可以将点击事件与方法关联:
<button @click="increment">增加</button>
3. 访问数据
在 methods
中,可以通过 this
关键字访问 Vue 实例的数据属性:
methods: {
greet() {
alert(`你好,${this.name}!`); // 访问和使用 data 属性
}
}
4. 方法参数
方法可以接收参数,你可以在模板中通过事件传递参数。例如:
methods: {
showMessage(message) {
alert(message); // 使用参数
}
}
在模板中调用时:
<button @click="showMessage('欢迎使用 Vue!')">显示消息</button>
完整示例,展示 methods
的使用:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue.js methods 示例</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
</head>
<body>
<div id="app">
<h1>{{ title }}</h1>
<button @click="increment">增加</button>
<p>当前计数:{{ count }}</p>
<input v-model="message" placeholder="输入消息">
<button @click="showMessage(message)">显示消息</button>
</div>
<script>
new Vue({
el: '#app',
data: {
title: '计数器',
count: 0,
message: ''
},
methods: {
increment() {
this.count++; // 增加计数
},
showMessage(msg) {
alert(`你输入的消息是: ${msg}`); // 显示输入的消息
}
}
});
</script>
</body>
</html>

Demo 练习:
在这个练习中,我们将创建一个简单的待办事项清单(To-Do List),并使用 Vue 来管理待办项的添加和删除。
<!DOCTYPE html>
<html>
<head>
<title>待办事项清单</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script> <!-- 引入 Vue.js -->
</head>
<body>
<div id="app">
<h1>我的待办事项清单</h1>
<input v-model="newTask" placeholder="添加新任务"> <!-- 输入框 -->
<button @click="addTask">添加</button> <!-- 添加按钮 -->
<ul>
<li v-for="(task, index) in tasks" :key="index">
{{ task }} <button @click="removeTask(index)">删除</button> <!-- 删除按钮 -->
</li>
</ul>
</div>
<script>
new Vue({
el: '#app', // 将 Vue 实例挂载到 id 为 app 的元素上
data: {
newTask: '', // 新任务的输入值
tasks: [] // 存储任务的数组
},
methods: {
addTask: function() {
// 添加新任务的方法
if (this.newTask.trim() !== '') { // 检查输入不为空
this.tasks.push(this.newTask.trim()); // 将新任务添加到任务数组中
this.newTask = ''; // 清空输入框
}
},
removeTask: function(index) {
// 删除任务的方法
this.tasks.splice(index, 1); // 从任务数组中移除指定索引的任务
}
}
});
</script>
</body>
</html>

思考:Vue 相比于原生 JS 代码到底有什么优势?
分别写出一个功能完整的 TodoList(待办事项)
1. 原生 JavaScript 版本(Vanilla JS)
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<title>原生JS TodoList</title>
</head>
<body>
<h2>我的待办事项(原生JS)</h2>
<input type="text" id="input-task" placeholder="输入任务" />
<button onclick="addTask()">添加</button>
<ul id="task-list">
<!-- 任务会动态插入到这里 -->
</ul>
<script>
// 获取 DOM 元素
const input = document.getElementById('input-task');
const list = document.getElementById('task-list');
// 初始任务列表
let tasks = ['学习JavaScript', '写个Demo'];
// 页面加载时渲染初始任务
function renderTasks() {
list.innerHTML = ''; // 清空
tasks.forEach((task, index) => {
const li = document.createElement('li');
li.textContent = task;
const btn = document.createElement('button');
btn.textContent = '删除';
btn.onclick = () => removeTask(index); // 删除对应任务
li.appendChild(btn);
list.appendChild(li);
});
}
// 添加任务
function addTask() {
const value = input.value.trim();
if (value) {
tasks.push(value);
input.value = '';
renderTasks(); // 手动重新渲染
}
}
// 删除任务
function removeTask(index) {
tasks.splice(index, 1);
renderTasks(); // 手动重新渲染
}
// 初始化页面
renderTasks();
</script>
</body>
</html>
2. Vue3 版本(使用 CDN 快速体验)
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<title>Vue TodoList</title>
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="app">
<h2>我的待办事项(Vue3)</h2>
<input
v-model="newTask"
@keyup.enter="addTask"
placeholder="输入任务"
/>
<button @click="addTask">添加</button>
<ul>
<li v-for="(task, index) in tasks" :key="index">
{{ task }}
<button @click="removeTask(index)">删除</button>
</li>
</ul>
</div>
<script>
Vue.createApp({
data() {
return {
newTask: '',
tasks: ['学习Vue', '写个Demo']
};
},
methods: {
addTask() {
if (this.newTask.trim()) {
this.tasks.push(this.newTask);
this.newTask = '';
}
},
removeTask(index) {
this.tasks.splice(index, 1);
}
}
}).mount('#app');
</script>
</body>
</html>
对比分析:JS vs Vue
对比项 | 原生 JavaScript | Vue |
---|---|---|
代码量 | 多(需手动操作 DOM) | 少(声明式模板) |
数据管理 | tasks 数组 + 手动同步 | 数据驱动,自动更新视图 |
添加/删除逻辑 | 要 createElement 、appendChild 、remove() | 只改数据,视图自动变 |
事件绑定 | btn.onclick = ... | 模板中直接写 @click="..." |
双向绑定 | 手动取 input.value | v-model 自动同步 |
维护性 | 难扩展,容易出错 | 结构清晰,易复用 |
举个例子说明“数据驱动”
在 Vue 中:
this.tasks.push('新任务'); // 只改数据
// → 页面自动出现新任务,无需你操作 DOM!
而在原生 JS 中:
tasks.push('新任务');
renderTasks(); // 必须手动调用渲染函数
Vue 生命周期
Vue.js 的生命周期是指从创建一个 Vue 实例到销毁的整个过程。在这个生命周期的不同阶段,Vue 会调用一些特定的生命周期钩子函数,这些钩子函数允许开发者在特定时刻执行代码。生命周期钩子使得我们可以在 Vue 实例的不同状态下执行自定义操作,比如初始化数据、设置事件监听、清理资源等。
以下是 Vue 实例生命周期的主要阶段:
- 创建阶段
- beforeCreate:实例初始化之后,数据观测和事件配置之前调用。
- created:实例已创建完成,数据观测和事件配 置已完成,但尚未挂载到 DOM。
- 挂载阶段
- beforeMount:在挂载开始之前被调用,相关的 render 函数首次调用。
- mounted:实例被挂载后被调用,el 被替换为实例的 $el。此时可以访问 DOM。
- 更新阶段
- beforeUpdate:数据更改,DOM 重新渲染之前调用。
- updated:由于数据更改导致的重新渲染完成后调用。
- 销毁阶段
- beforeDestroy:组件实例被销毁之前调用,此时可以进行清理操作。
- destroyed:组件实例已被销毁后调用,完全可清理及销毁对象。

以下是一个简单的 Vue 组件示例,展示了如何在生命周期钩子中执行代码。
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue 生命周期示例</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script> <!-- 确保引用了Vue.js -->
<style>
body {
font-family: Arial, sans-serif;
background-color: #f9f9f9;
padding: 20px;
}
h1 {
color: #333;
}
</style>
</head>
<body>
<div id="app">
<h1>{{ message }}</h1>
</div>
<script>
new Vue({
el: '#app',
data: {
message: 'Hello, Vue!'
},
beforeCreate() {
console.log('beforeCreate: 实例刚初始化');
},
created() {
console.log('created: 实例已创建');
},
beforeMount() {
console.log('beforeMount: 即将挂载');
},
mounted() {
console.log('mounted: 实例已挂载在 DOM 上');
},
beforeUpdate() {
console.log('beforeUpdate: 数据即将更新');
},
updated() {
console.log('updated: 数据更新完毕');
},
beforeDestroy() {
console.log('beforeDestroy: 实例即将销毁');
},
destroyed() {
console.log('destroyed: 实例已销毁');
}
});
</script>
</body>
</html>

通过生命周期钩子,开发者可以在 Vue 实例的不同阶段插入自定义逻辑。这对于初始化数据、绑定事件、处理异步请求、清除资源等操作都非常有用。掌握生命周期的各个阶段能够帮助你更好地控制组件的行为和状态,从而提高应用的性能和用户体验。
ES6 语法新特性
ES6(ECMAScript 2015)引入了一系列新的语法特性和改进,使得 JavaScript 在书写风格上更加简洁和现代化。以下是一些主要的 ES6 语法风格及其特点:
1. 块级作用域
let
和 const
:引入了对变量声明的新语法,let
用于声明可变的变量,const
用于声明不可变的常量。
ES5 示例
在 ES5 中,变量声明总是使用 var
,它的作用域是函数级的。
function example() {
if (true) {
var x = 10; // x 在函数作用域内有效
}
console.log(x); // 输出: 10
}
example();
对比 ES6
使用 let
或 const
,以实现块级作用域。
function example() {
if (true) {
let y = 20; // y 在块级作用域内有效
const z = 30; // z 在块级作用域内有效
console.log(y); // 输出: 20
console.log(z); // 输出: 30
}
// console.log(y); // 报错:y is not defined
}
example();
2. 箭头函数
更简洁的函数表示法,且不绑定自己的 this
值,使得在回调函数中使用 this
更加直观。
const add = (a, b) => a + b;
ES5 示例
使用传统的函数表达式。
var add = function(a, b) {
return a + b;
};
var result = add(5, 10);
console.log(result); // 输出: 15
对比 ES6
使用箭头函数语法。
const add = (a, b) => a + b; // 更简洁的写法
const result = add(5, 10);
console.log(result); // 输出: 15
3. 模板字符串
使用反引号 `
来包围字符串,可以轻松插入变量和进行多行字符串。
let name = '世界';
let greeting = `你好,${name}`; // 支持插值
ES5 示例
使用字符串连接来插入变量。
var name = '世界';
var greeting = '你好,' + name + '!'; // 字符串拼接
console.log(greeting); // 输出: 你好,世界!
对比 ES6
使用模板字符串进行插值。
let name = '世界';
let greeting = `你好,${name}!`; // 支持变量插值和多行
console.log(greeting); // 输出: 你好,世界!
4. 解构赋值
允许从数组或对象中提取值,语法更加简洁。
const arr = [1, 2, 3];
const [a, b] = arr; // 数组解构
const obj = { x: 1, y: 2 };
const { x, y } = obj; // 对象解构
ES5 示例
使用索引或属性赋值来获取数组或对象的值。
var arr = [1, 2, 3];
var a = arr[0];
var b = arr[1]; // 使用索引访问
var obj = { x: 1, y: 2 };
var x = obj.x;
var y = obj.y; // 使用属性访问
对比 ES6
使用解构赋值,减少代码量。
const arr = [1, 2, 3];
const [a, b] = arr; // 数组解构
const obj = { x: 1, y: 2 };
const { x, y } = obj; // 对象解构
5. 默认参数
函数参数可以设置默认值,有助于减少需要判断参数是否为空的代码。
function multiply(a, b = 1) {
return a * b;
}
ES5 示例
需要提前检查参数是否为 undefined
。
function multiply(a, b) {
b = typeof b !== 'undefined' ? b : 1; // 手动检查
return a * b;
}
console.log(multiply(5)); // 输出: 5
对比 ES6
可以为参数设置默认值。
function multiply(a, b = 1) {
return a * b;
}
console.log(multiply(5)); // 输出: 5
6. 扩展运算符
用于数组和对象的展开,能够简洁地合并多个数组或复制对象。
const arr1 = [1, 2];
const arr2 = [3, 4];
const combined = [...arr1, ...arr2]; // 数组合并
const obj1 = { a: 1 };
const obj2 = { b: 2 };
const combinedObj = { ...obj1, ...obj2 }; // 对象合并
ES5 示例
使用 concat()
方法合并数组,或者循环通过 for
手动添加对象属性。
var arr1 = [1, 2];
var arr2 = [3, 4];
var combined = arr1.concat(arr2); // 数组合并
// 对象合并
var obj1 = { a: 1 };
var obj2 = { b: 2 };
var combinedObj = {};
for (var key in obj1) combinedObj[key] = obj1[key];
for (var key in obj2) combinedObj[key] = obj2[key];
对比 ES6
使用展开运算符(...
)来简化这些操作。
const arr1 = [1, 2];
const arr2 = [3, 4];
const combined = [...arr1, ...arr2]; // 数组合并
const obj1 = { a: 1 };
const obj2 = { b: 2 };
const combinedObj = { ...obj1, ...obj2 }; // 对象合并
7. 类与模块
- 使用
class
语法定义类,使得面向对象编程的风格更加接近其他编程语言。 - 引入模块化语法,使用
import
和export
来管理代码的组织和依赖。
class Person {
constructor(name) {
this.name = name;
}
greet() {
return `你好,${this.name}`;
}
}
export default Person; // 导出
ES5 示例
使用构造函数和原型来实现面向对象编程。
function Person(name) {
this.name = name;
}
Person.prototype.greet = function() {
return '你好,' + this.name;
};
var person = new Person('张三');
console.log(person.greet()); // 输出: 你好,张三
对比 ES6
引入 class
语法。
class Person {
constructor(name) {
this.name = name;
}
greet() {
return `你好,${this.name}`; // 使用模板字符串
}
}
const person = new Person('张三');
console.log(person.greet()); // 输出: 你好,张三
8. Promise
引入 Promise
对象,使得处理异步操作更加直观,避免了回调地狱(callback hell)。
const myPromise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('成功!');
}, 1000);
});
ES5 示例
使用回调函数处理异步操作。
function asyncOperation(callback) {
setTimeout(function() {
callback('成功!'); // 调用回调
}, 1000);
}
asyncOperation(function(result) {
console.log(result); // 输出: 成功!
});
对比 ES6
使用 Promise
使得异步操作更加直观。
const myPromise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('成功!'); // 直接调用 resolve
}, 1000);
});
myPromise.then(result => {
console.log(result); // 输出: 成功!
});
ES6 在语法上提供了更多方便的特性,使得代码更加简洁、可读性更强。它让开发者可以更方便地处理变量、函数、异步操作和对象。
Axios
基本概念
Vue 应用需要与后端进行 HTTP 请求来获取或发送数据,只能通过Axios
为什么学习 Axios
- HTTP 请求:
- Axios 是一个基于 Promise 的 HTTP 客户端,能够简化与服务器的交互,支持发送 GET、POST、PUT、DELETE 等请求。
- 现代应用通常需要获取远程数据或发送数据到服务器,掌握 Axios 将使你能够高效地进行这些操作。
- 处理请求和响应:
- Axios 提供了易于使用的 API,可以配置请求头、参数、超时等,方便开发者根据需要调整请求。
- 支持响应的拦截器,可以在数据到达应用之前进行处理,如错误处理、加载状态更新等。
- 简化异步操作:
- Axios 使用 Promise,使得处理异步操作变得更加直观,不再需要嵌套的回调函数(回调地狱)。
- 配合
async/await
使用时,能够让代码更加清晰可读。
- 跨浏览器支持:
- Axios 兼容现代浏览器,并处理了一些常见的浏览器差异性问题(如 JSON 请求的序列化/反序列化)。
安装 Axios
在 Vue 项目中,你可以通过 npm 或 yarn 安装 Axios:
npm install axios
# 或者
yarn add axios
基本使用
Axios 提供了简单的 API 来发送 HTTP 请求。以下是一些常见的用法。
发送 GET 请求
axios.get('https://api.example.com/items')
.then(response => {
console.log(response.data); // 处理返回的数据
})
.catch(error => {
console.error('请求错误:', error);
});
发送 POST 请求
axios.post('https://api.example.com/items', {
name: '新任务',
completed: false
})
.then(response => {
console.log('任务添加成功:', response.data);
})
.catch(error => {
console.error('添加任务失败:', error);
});
Django 和 Vue.js前后端项目不分离
利用 Django 和 Vue.js 通过引用 CDN 方式,构建一个简单的待办事项清单 (To-Do List) ,包括如何使用 GET 和 POST 请求与 Django 后端进行数据库交互。
创建 Django 项目和应用
创建一个新的 Django 项目和应用。在这个示例中,项目名称为 DjangoProject
,应用名称为 myapp
。
确保将 myapp
添加到 settings.py
中的 INSTALLED_APPS
:
# DjangoProject/settings.py
INSTALLED_APPS = [
...
'myapp',
'rest_framework', # 确保 Django REST Framework 已安装
]
安装 Django REST Framework
Django REST Framework 是一个强大的网页 API 构建工具,具有序列化、视图集等功能。
pip install djangorestframework
创建待办事项模型
在 models.py
中定义 TodoItem
模型,存储任务和其完成状态。模型是 Django ORM 和数据库之间的连接。
在 myapp/models.py
文件中定义待办事项模型:
# myapp/models.py
from django.db import models
class TodoItem(models.Model):
task = models.CharField(max_length=200)
completed = models.BooleanField(default=False)
def __str__(self):
return self.task
可选择关联到 mysql 数据库(PyMySQL方式)
确保您在您的 Python 环境中安装了 PyMySQL
。可以通过 pip
安装它:
pip install PyMySQL
配置 Django 设置
在您的 Django 项目的 settings.py
文件中,找到 DATABASES
设置,并进行如下配置(假设您已经创建了名为 mydatabase
的数据库):
# DjangoProject/settings.py
import os
import pymysql
# 使用 PyMySQL 作为 MySQL 的 DB API 适配器
pymysql.install_as_MySQLdb()
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'myapp', # 数据库名称
'USER': 'root', # 数据库用户名
'PASSWORD': 'xxxxxxxx', # 数据库用户密码
'HOST': 'localhost', # 数据库主机
'PORT': '3306', # 数据库端口,通常为 3306
}
}
确保您已经在 MySQL 中创建了数据库
CREATE DATABASE myapp;
创建序列化器和视图
创建一个序列化器,用于将模型转换为 JSON 格式,并实现相应的 API 接口。序列化器负责将 Django 模型转换为 JSON 格式。处理 HTTP 请求并返回序列化数据。
myapp/serializers.py
# myapp/serializers.py
from rest_framework import serializers
from .models import TodoItem
class TodoItemSerializer(serializers.ModelSerializer):
class Meta:
model = TodoItem
fields = '__all__'
myapp/views.py
# myapp/views.py
from rest_framework import viewsets
from .models import TodoItem
from .serializers import TodoItemSerializer
class TodoItemViewSet(viewsets.ModelViewSet):
queryset = TodoItem.objects.all()
serializer_class = TodoItemSerializer
配置 URL 路由
在 urls.py
中配置 API 路由和主页视图:
# DjangoProject/urls.py
from django.contrib import admin
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from myapp.views import TodoItemViewSet
from django.views.generic import TemplateView
# 创建路由
router = DefaultRouter()
router.register(r'todos', TodoItemViewSet)
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include(router.urls)), # API 路由
path('', TemplateView.as_view(template_name='index.html')), # 主页视图
]
创建模板
在项目根目录下的 templates
目录创建一个 index.html
文件。
<!-- templates/index.html -->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>待办事项</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<style>
body { font-family: Arial, sans-serif; padding:16px; }
ul { padding-left:0; list-style:none; }
li { margin:8px 0; display:flex; align-items:center; gap:8px; }
.completed { text-decoration:line-through; color:#999; }
</style>
</head>
<body>
<div id="app">
<h1>待办事项</h1>
<input v-model="newTask" @keyup.enter="addTodo" placeholder="添加新任务" />
<button @click="addTodo">添加</button>
<ul>
<li v-for="todo in todos" :key="todo.id">
<input type="checkbox" :checked="todo.completed" @change="toggleCompleted(todo)" />
<span :class="{ completed: todo.completed }" v-text="todo.task"></span>
<button @click="deleteTodo(todo.id)">删除</button>
</li>
</ul>
</div>
<script>
new Vue({
el: '#app',
data() {
return { newTask: '', todos: [] };
},
mounted() { this.fetchTodos(); },
methods: {
fetchTodos() {
axios.get('/api/todos/')
.then(res => { this.todos = res.data || []; })
.catch(err => { console.error('GET 失败', err); });
},
addTodo() {
const text = (this.newTask || '').trim();
if (!text) return;
axios.post('/api/todos/', { task: text })
.then(res => { this.todos.push(res.data); this.newTask = ''; })
.catch(err => { console.error('POST 失败', err); });
},
deleteTodo(id) {
axios.delete(`/api/todos/${id}/`)
.then(() => { this.todos = this.todos.filter(t => t.id !== id); })
.catch(err => { console.error('DELETE 失败', err); });
},
toggleCompleted(todo) {
const newVal = !todo.completed;
// 乐观更新
todo.completed = newVal;
axios.patch(`/api/todos/${todo.id}/`, { completed: newVal })
.catch(err => {
// 回退
todo.completed = !newVal;
console.error('PATCH 失败', err);
});
}
}
});
</script>
</body>
</html>
在这个 index.html
文件中:
- 我们引入了 Vue.js 和 Axios 的 CDN。
- 实现了一个可以添加新待办事项,删除已存在待办事项的简单接口。
- 在
mounted
生命周期钩子中,调用fetchTodos
方法以获取待办事项。 fetchTodos
使用GET
请求从后端获取待办事项列表,并将结果存储在todos
的数组中。addTodo
方法通过POST
请求将新任务添加到数据库,并更新本地数组。deleteTodo
方法通过DELETE
请求删除任务。
启动 Django 服务器
确保你已经进行了数据库迁移:
python manage.py makemigrations
python manage.py migrate
启动 Django 开发服务器:
python manage.py runserver
访问应用
在浏览器中访问 http://127.0.0.1:8000/
,你就会看到待办事项清单应用。你可以添加新的待办事项,勾选完成状态,或删除已经添加的任务。

http://127.0.0.1:8000/api/todos/

数据库

发布者:LJH,转发请注明出处:https://www.ljh.cool/43809.html