Vue.js 核心知识点完整解析第一章
·
Vue.js 核心知识点完整解析第一章
1. Vue模板语法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue模板语法</title>
<script src="../static/js/vue.js"></script>
</head>
<body>
<div id="root">
<!-- 插值语法:用于解析标签体内容 -->
<h1>插值语法示例</h1>
<p>{{ message }}</p>
<p>{{ number + 1 }}</p>
<p>{{ ok ? 'YES' : 'NO' }}</p>
<p>{{ message.split('').reverse().join('') }}</p>
<!-- 指令语法:用于解析标签属性、内容、事件等 -->
<h1>指令语法示例</h1>
<!-- v-bind 指令 -->
<a v-bind:href="url">普通绑定</a>
<a :href="url">简写绑定</a>
<div :class="className">类名绑定</div>
<div :style="styleObject">样式绑定</div>
<!-- v-on 指令 -->
<button v-on:click="handleClick">普通事件</button>
<button @click="handleClick">简写事件</button>
<!-- v-if 指令 -->
<p v-if="show">条件渲染</p>
<!-- v-for 指令 -->
<ul>
<li v-for="item in items" :key="item.id">{{ item.name }}</li>
</ul>
</div>
<script>
new Vue({
el: '#root',
data: {
message: 'Hello Vue!',
number: 10,
ok: true,
url: 'https://vuejs.org',
className: 'active',
styleObject: {
color: 'red',
fontSize: '20px'
},
show: true,
items: [
{ id: 1, name: 'Vue' },
{ id: 2, name: 'React' },
{ id: 3, name: 'Angular' }
]
},
methods: {
handleClick() {
alert('按钮被点击了!');
}
}
});
</script>
</body>
</html>
知识点总结:
- 插值语法:
{{ }}用于标签体内容,支持JS表达式 - 指令语法:
v-前缀的特殊属性,用于各种DOM操作 - 常用指令:
v-bind,v-on,v-if,v-for等 - 简写形式:
:代替v-bind,@代替v-on
2. 数据绑定与el/data的两种写法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>数据绑定与写法</title>
<script src="../static/js/vue.js"></script>
</head>
<body>
<div id="root">
<h1>数据绑定示例</h1>
<!-- 单向数据绑定:v-bind -->
<input type="text" v-bind:value="name">
<span>单向绑定:{{name}}</span>
<!-- 双向数据绑定:v-model -->
<input type="text" v-model="name">
<span>双向绑定:{{name}}</span>
<!-- v-model修饰符 -->
<input v-model.lazy="lazyText" placeholder="懒更新">
<input v-model.number="numberText" placeholder转为数字>
<input v-model.trim="trimText" placeholder="去除空格">
</div>
<script>
// el的两种写法
const vm = new Vue({
// 写法一:直接配置el属性
// el: '#root',
data: {
name: 'Vue.js',
lazyText: '',
numberText: '',
trimText: ''
},
// 写法二:使用$mount()
// mounted() {
// this.$mount('#root');
// }
});
// 第二种el写法
vm.$mount('#root');
// data的两种写法
const vm2 = new Vue({
el: '#app',
// 写法一:对象式
// data: {
// name: '对象式data'
// }
// 写法二:函数式(推荐)
data() {
return {
name: '函数式data'
};
}
});
</script>
</body>
</html>
知识点总结:
- 单向绑定:
v-bind数据从Vue流向页面 - 双向绑定:
v-model数据双向流动 - el的两种写法:配置对象中直接写 / 使用
$mount() - data的两种写法:对象式 / 函数式(组件必须用函数式)
3. MVVM模型与数据代理
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MVVM与数据代理</title>
<script src="../static/js/vue.js"></script>
</head>
<body>
<div id="root">
<h1>MVVM模型演示</h1>
<p>Model: {{message}}</p>
<input v-model="message" placeholder="修改Model">
<h2>数据代理验证</h2>
<p>原始数据: {{originalData}}</p>
<p>代理后数据: {{proxyData}}</p>
</div>
<script>
// MVVM模型理解
const vm = new Vue({
el: '#root',
data: {
message: 'Hello MVVM',
originalData: '原始值'
},
computed: {
// 数据代理示例
proxyData: {
get() {
return this.originalData + ' (代理后)';
},
set(value) {
this.originalData = value.replace(' (代理后)', '');
}
}
}
});
// 验证数据代理
console.log(vm); // 查看Vue实例
console.log(vm._data === vm.$data); // true
console.log(vm.message === vm._data.message); // true,证明数据代理
</script>
</body>
</html>
知识点总结:
- MVVM模型:Model-View-ViewModel的缩写
- M:模型,对应data中的数据
- V:视图,模板DOM
- VM:视图模型,Vue实例对象
- 数据代理:通过Object.defineProperty()实现,vm代理data中属性的操作
4. 事件处理
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>事件处理</title>
<script src="../static/js/vue.js"></script>
<style>
.demo { width: 100px; height: 100px; background: skyblue; margin: 10px; }
</style>
</head>
<body>
<div id="root">
<h1>事件处理大全</h1>
<!-- 基本事件处理 -->
<button @click="showAlert">点击事件</button>
<button @click="showMessage('参数传递')">带参数事件</button>
<!-- 事件修饰符 -->
<div @click="outerClick" class="demo">
<div @click.stop="innerClick" class="demo">.stop阻止冒泡</div>
</div>
<a @click.prevent="linkClick" href="https://vuejs.org">.prevent阻止默认行为</a>
<!-- 键盘事件 -->
<input @keyup.enter="enterPressed" placeholder="按回车触发">
<input @keyup.13="enterPressed" placeholder="按键码13也是回车">
<!-- 鼠标事件 -->
<div @mouseenter="mouseEnter" @mouseleave="mouseLeave" class="demo">
鼠标事件
</div>
<!-- 事件对象 -->
<button @click="eventHandler">事件对象$event</button>
<button @click="eventHandler2($event, '自定义参数')">混合参数</button>
</div>
<script>
new Vue({
el: '#root',
methods: {
showAlert() {
alert('按钮被点击了!');
},
showMessage(msg) {
alert('收到消息:' + msg);
},
outerClick() {
console.log('外部div被点击');
},
innerClick() {
console.log('内部div被点击,不会冒泡到外部');
},
linkClick() {
alert('链接被点击,但不会跳转');
},
enterPressed() {
console.log('回车键被按下');
},
mouseEnter() {
console.log('鼠标进入');
},
mouseLeave() {
console.log('鼠标离开');
},
eventHandler(event) {
console.log('事件对象:', event);
console.log('目标元素:', event.target);
},
eventHandler2(event, param) {
console.log('事件对象:', event);
console.log('自定义参数:', param);
}
}
});
</script>
</body>
</html>
知识点总结:
- 事件绑定:
v-on或@简写 - 事件修饰符:
.stop,.prevent,.capture,.self,.once,.passive - 按键修饰符:
.enter,.tab,.delete,.esc,.space,.up,.down,.left,.right - 系统修饰键:
.ctrl,.alt,.shift,.meta
5. 计算属性与监视属性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>计算属性与监视属性</title>
<script src="../static/js/vue.js"></script>
</head>
<body>
<div id="root">
<h1>计算属性 vs 方法 vs 监视属性</h1>
<input v-model="firstName" placeholder="姓">
<input v-model="lastName" placeholder="名">
<h3>方法调用:{{getFullName()}}</h3>
<h3>计算属性:{{fullName}}</h3>
<h3>监视结果:{{watchedFullName}}</h3>
<h2>购物车示例</h2>
<div v-for="item in cart" :key="item.id">
{{item.name}} - ¥{{item.price}} × {{item.quantity}}
</div>
<h3>总价(计算属性):¥{{totalPrice}}</h3>
<h3>总价(监视属性):¥{{watchedTotalPrice}}</h3>
</div>
<script>
new Vue({
el: '#root',
data: {
firstName: '张',
lastName: '三',
watchedFullName: '',
watchedTotalPrice: 0,
cart: [
{ id: 1, name: '商品A', price: 100, quantity: 2 },
{ id: 2, name: '商品B', price: 200, quantity: 1 }
]
},
methods: {
getFullName() {
console.log('方法被调用');
return this.firstName + this.lastName;
}
},
computed: {
// 计算属性:有缓存,依赖变化才重新计算
fullName: {
get() {
console.log('计算属性被调用');
return this.firstName + this.lastName;
},
set(value) {
const names = value.split('');
this.firstName = names[0];
this.lastName = names[1] || '';
}
},
totalPrice() {
return this.cart.reduce((total, item) => {
return total + item.price * item.quantity;
}, 0);
}
},
watch: {
// 监视属性:数据变化时执行异步或复杂操作
firstName: {
handler(newVal, oldVal) {
console.log('firstName从', oldVal, '变为', newVal);
this.watchedFullName = newVal + this.lastName;
},
immediate: true // 立即执行一次
},
lastName: {
handler(newVal) {
this.watchedFullName = this.firstName + newVal;
}
},
cart: {
handler() {
this.watchedTotalPrice = this.cart.reduce((total, item) => {
return total + item.price * item.quantity;
}, 0);
},
deep: true // 深度监视
}
}
});
</script>
</body>
</html>
知识点总结:
- 计算属性:基于依赖缓存,只有相关依赖发生改变时才会重新求值
- 监视属性:观察和响应Vue实例上的数据变动,适合执行异步操作
- 区别:计算属性适合同步计算,监视属性适合异步或复杂逻辑
6. 绑定样式与条件渲染
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>样式绑定与条件渲染</title>
<script src="../static/js/vue.js"></script>
<style>
.basic { padding: 10px; margin: 5px; }
.active { background-color: #4CAF50; color: white; }
.text-danger { color: red; }
.large { font-size: 24px; }
.rounded { border-radius: 10px; }
.static-class { border: 1px solid #ccc; }
.v-enter-active, .v-leave-active {
transition: opacity 0.5s;
}
.v-enter, .v-leave-to {
opacity: 0;
}
</style>
</head>
<body>
<div id="root">
<h1>样式绑定</h1>
<!-- 绑定class - 对象语法 -->
<div class="basic" :class="{ active: isActive, 'text-danger': hasError }">
对象语法:{{isActive ? '激活' : '未激活'}}
</div>
<!-- 绑定class - 数组语法 -->
<div class="basic" :class="[activeClass, errorClass]">
数组语法:同时绑定多个class
</div>
<!-- 绑定style - 对象语法 -->
<div :style="{ color: activeColor, fontSize: fontSize + 'px' }">
内联样式对象语法
</div>
<!-- 绑定style - 数组语法 -->
<div :style="[baseStyles, overridingStyles]">
内联样式数组语法
</div>
<h1>条件渲染</h1>
<!-- v-if vs v-show -->
<button @click="show = !show">切换显示</button>
<div v-if="show" class="basic">v-if条件渲染(元素移除)</div>
<div v-show="show" class="basic">v-show条件渲染(display切换)</div>
<!-- v-if、v-else-if、v-else -->
<div>
<input type="number" v-model="score" placeholder="输入分数">
<div v-if="score >= 90">优秀</div>
<div v-else-if="score >= 80">良好</div>
<div v-else-if="score >= 60">及格</div>
<div v-else>不及格</div>
</div>
<!-- template标签使用 -->
<template v-if="showTemplate">
<h3>Template标签</h3>
<p>这组元素会一起显示或隐藏</p>
</template>
<!-- 用key管理可复用的元素 -->
<template v-if="loginType === 'username'">
<label>用户名:</label>
<input placeholder="输入用户名" key="username-input">
</template>
<template v-else>
<label>邮箱:</label>
<input placeholder="输入邮箱" key="email-input">
</template>
<button @click="toggleLoginType">切换登录方式</button>
</div>
<script>
new Vue({
el: '#root',
data: {
// 样式数据
isActive: true,
hasError: false,
activeClass: 'active',
errorClass: 'text-danger',
activeColor: 'blue',
fontSize: 20,
baseStyles: {
padding: '10px',
margin: '5px'
},
overridingStyles: {
backgroundColor: '#f0f0f0',
borderRadius: '5px'
},
// 条件渲染数据
show: true,
score: 85,
showTemplate: true,
loginType: 'username'
},
methods: {
toggleLoginType() {
this.loginType = this.loginType === 'username' ? 'email' : 'username';
}
}
});
</script>
</body>
</html>
知识点总结:
- class绑定:对象语法、数组语法
- style绑定:对象语法、数组语法
- v-if:真正的条件渲染,确保事件监听器和子组件适当被销毁和重建
- v-show:只是简单地切换元素的CSS display属性
- 选择建议:频繁切换用v-show,运行时条件很少改变用v-if
7. 列表渲染与表单数据收集
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>列表渲染与表单数据</title>
<script src="../static/js/vue.js"></script>
<style>
.list-item { padding: 10px; border: 1px solid #ddd; margin: 5px; }
.completed { text-decoration: line-through; color: #999; }
.form-group { margin: 10px 0; }
label { display: inline-block; width: 100px; }
</style>
</head>
<body>
<div id="root">
<h1>列表渲染 v-for</h1>
<!-- 数组渲染 -->
<h3>用户列表</h3>
<ul>
<li v-for="(user, index) in users" :key="user.id">
{{index + 1}}. {{user.name}} - {{user.age}}岁
<button @click="removeUser(index)">删除</button>
</li>
</ul>
<!-- 对象渲染 -->
<h3>用户信息对象</h3>
<div v-for="(value, key, index) in userInfo" :key="key">
{{index}}. {{key}} : {{value}}
</div>
<!-- 范围渲染 -->
<h3>数字范围</h3>
<span v-for="n in 5" :key="n">{{n}} </span>
<!-- 过滤/排序列表 -->
<h3>成年用户(计算属性过滤)</h3>
<ul>
<li v-for="user in adultUsers" :key="user.id">
{{user.name}} - {{user.age}}岁
</li>
</ul>
<h1>表单数据收集</h1>
<form @submit.prevent="handleSubmit">
<!-- 文本输入 -->
<div class="form-group">
<label>用户名:</label>
<input type="text" v-model.trim="formData.username">
</div>
<!-- 密码输入 -->
<div class="form-group">
<label>密码:</label>
<input type="password" v-model="formData.password">
</div>
<!-- 单选按钮 -->
<div class="form-group">
<label>性别:</label>
<input type="radio" id="male" value="male" v-model="formData.gender">
<label for="male">男</label>
<input type="radio" id="female" value="female" v-model="formData.gender">
<label for="female">女</label>
</div>
<!-- 复选框 -->
<div class="form-group">
<label>爱好:</label>
<input type="checkbox" id="basketball" value="basketball" v-model="formData.hobbies">
<label for="basketball">篮球</label>
<input type="checkbox" id="football" value="football" v-model="formData.hobbies">
<label for="football">足球</label>
<input type="checkbox" id="swimming" value="swimming" v-model="formData.hobbies">
<label for="swimming">游泳</label>
</div>
<!-- 选择框 -->
<div class="form-group">
<label>城市:</label>
<select v-model="formData.city">
<option value="">请选择</option>
<option value="beijing">北京</option>
<option value="shanghai">上海</option>
<option value="guangzhou">广州</option>
</select>
</div>
<!-- 多行文本 -->
<div class="form-group">
<label>个人介绍:</label>
<textarea v-model.lazy="formData.introduction"></textarea>
</div>
<button type="submit">提交</button>
</form>
<h3>表单数据预览:</h3>
<pre>{{ JSON.stringify(formData, null, 2) }}</pre>
</div>
<script>
new Vue({
el: '#root',
data: {
// 列表数据
users: [
{ id: 1, name: '张三', age: 25 },
{ id: 2, name: '李四', age: 17 },
{ id: 3, name: '王五', age: 30 },
{ id: 4, name: '赵六', age: 16 }
],
userInfo: {
name: '张三',
age: 25,
gender: 'male',
city: 'beijing'
},
// 表单数据
formData: {
username: '',
password: '',
gender: 'male',
hobbies: [],
city: '',
introduction: ''
}
},
computed: {
adultUsers() {
return this.users.filter(user => user.age >= 18);
}
},
methods: {
removeUser(index) {
this.users.splice(index, 1);
},
handleSubmit() {
// 表单验证
if (!this.formData.username.trim()) {
alert('请输入用户名');
return;
}
if (this.formData.hobbies.length === 0) {
alert('请至少选择一个爱好');
return;
}
// 提交逻辑
console.log('表单数据:', this.formData);
alert('表单提交成功!');
// 重置表单
this.formData = {
username: '',
password: '',
gender: 'male',
hobbies: [],
city: '',
introduction: ''
};
}
}
});
</script>
</body>
</html>
知识点总结:
- 列表渲染:
v-for指令遍历数组、对象、数字范围 - key的重要性:为每个节点提供唯一标识,优化虚拟DOM的diff算法
- 数组更新检测:Vue包装了数组的变异方法,能触发视图更新
- 表单绑定:
v-model在各种表单元素上的应用 - 修饰符:
.lazy,.number,.trim的使用场景
核心知识点回顾
Vue实例与配置
- el:指定挂载目标,两种写法
- data:数据对象,两种写法(对象式/函数式)
- methods:定义方法,
this自动绑定为Vue实例
数据绑定与响应式
- 插值语法:
{{ }}用于文本内容 - 指令语法:
v-前缀的特殊属性 - 双向绑定:
v-model实现表单输入与应用状态同步
计算属性与监视
- computed:基于依赖缓存,适合计算逻辑
- watch:观察数据变化,适合异步操作
条件与列表渲染
- v-if/v-show:条件渲染,注意区别
- v-for:列表渲染,必须使用key
样式与类绑定
- :class:动态绑定CSS类
- :style:动态绑定内联样式
事件处理
- v-on:事件监听,支持修饰符
- 事件对象:
$event的使用
这些知识点构成了Vue.js的基础核心,掌握好这些内容为进一步学习Vue组件化开发打下坚实基础。
生活感悟
这周学习Vue基础时,发现理解概念和实际编码是两回事。看视频觉得都懂了,一写代码就遇到各种问题。最大的体会是:不能光看,一定要动手敲代码。每个小知识点都要亲自验证,犯错越多,收获越大。
**
学习计划
**
一:过滤器
学习过滤器的定义和使用
实践:日期格式化、价格显示等常用过滤器
目标:掌握{{ message | filterName }}语法
二:内置指令
重点指令:v-text、v-html、v-cloak、v-once、v-pre
理解每个指令的应用场景和注意事项
特别注意v-html的安全问题
三:自定义指令
学习指令的注册方式(全局/局部)
掌握5个钩子函数:bind、inserted、update等
实践:实现一个自动聚焦指令
四:生命周期
记忆8个关键生命周期钩子
理解每个阶段适合做什么操作
避免在created中操作DOM
五:非单文件组件
组件的基本定义和注册
组件间的数据传递(props/$emit)
理解组件化开发思想
六:单文件组件
学习.vue文件的结构(template、script、style)
搭建Vue CLI开发环境
体验现代前端开发流程
更多推荐



所有评论(0)