目录
一、起步
1. vue介绍
-
Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。
2. Vue基本语法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue.js 2 基础语法示例</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
</head>
<body>
<div id="app">
<!-- 插值和表达式 -->
<div>{{ message }}</div>
<!-- 条件渲染 -->
<div v-if="isVisible">可见内容</div>
<div v-else>隐藏内容</div>
<!-- 列表渲染 -->
<ul>
<li v-for="item in items" :key="item.id">{{ item.name }}</li>
</ul>
<!-- 动态绑定属性 -->
<img v-bind:src="imageSrc" alt="图片">
<!-- 事件处理 -->
<button v-on:click="handleClick">点击我</button>
</div>
<script>
new Vue({
el: '#app',
data: {
message: 'Hello Vue!',
isVisible: true,
items: [
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' },
{ id: 3, name: 'Item 3' }
],
imageSrc: 'https://placekitten.com/200/300' // 示例图片链接
},
methods: {
handleClick() {
alert('按钮被点击了!');
}
}
});
</script>
</body>
</html>
3. 计算属性computed
在 Vue.js 中,使用计算属性 computed
可以非常方便地处理复杂的逻辑和数据计算。以下是一个简单的购物车案例,演示如何使用计算属性来计算购物车中商品的总数量和总价格。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue.js 计算属性示例 - 购物车</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
</head>
<body>
<div id="app">
<h2>购物车</h2>
<ul>
<li v-for="(item, index) in cart" :key="index">
{{ item.name }} - 单价: {{ item.price }}元 - 数量: {{ item.quantity }}
</li>
</ul>
<p>总商品数量: {{ totalQuantity }}</p>
<p>总价格: {{ totalPrice }}元</p>
<button @click="addItem">添加商品</button>
</div>
<script>
new Vue({
el: '#app',
data: {
cart: [
{ id: 1, name: '商品A', price: 10, quantity: 2 },
{ id: 2, name: '商品B', price: 15, quantity: 1 },
{ id: 3, name: '商品C', price: 20, quantity: 3 }
]
},
computed: {
totalQuantity() {
// 计算购物车中所有商品的总数量
return this.cart.reduce((total, item) => total + item.quantity, 0);
},
totalPrice() {
// 计算购物车中所有商品的总价格
return this.cart.reduce((total, item) => total + item.price * item.quantity, 0);
}
},
methods: {
addItem() {
// 点击按钮添加商品
const newItem = {
id: this.cart.length + 1,
name: '新商品' + (this.cart.length + 1),
price: Math.floor(Math.random() * 20) + 1,
quantity: Math.floor(Math.random() * 5) + 1
};
this.cart.push(newItem);
}
}
});
</script>
</body>
</html>
在这个示例中:
cart
数组模拟了购物车中的商品列表,每个商品包括id
、name
、price
和quantity
。- 使用
v-for
指令循环渲染购物车中的每个商品。 computed
计算属性totalQuantity
和totalPrice
分别计算购物车中所有商品的总数量和总价格。addItem
方法用于在点击按钮时向购物车中添加一个新的随机商品,以便演示计算属性的动态更新。
通过计算属性,我们可以非常方便地实现对购物车中数据的实时计算和展示,而无需在模板中编写复杂的逻辑或手动更新计算结果。
4.自定义指令
当你需要在 Vue.js 中实现自定义行为或直接操作 DOM 元素时,可以使用自定义指令。以下是一个简单的示例,展示如何创建一个自定义指令来实现当鼠标悬停在元素上时,改变其背景颜色。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue.js 自定义指令示例</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
</head>
<body>
<div id="app">
<h2>Vue.js 自定义指令示例</h2>
<div v-custom-hover-color>鼠标悬停在这里</div>
</div>
<script>
// 注册一个全局自定义指令 `v-custom-hover-color`
Vue.directive('custom-hover-color', {
bind(el, binding) {
// 鼠标进入时的处理函数
el.addEventListener('mouseenter', function() {
el.style.backgroundColor = binding.value || 'lightblue';
});
// 鼠标离开时的处理函数
el.addEventListener('mouseleave', function() {
el.style.backgroundColor = null;
});
}
});
new Vue({
el: '#app'
});
</script>
</body>
</html>
在这个示例中:
- 自定义指令
v-custom-hover-color
注册为custom-hover-color
,并通过Vue.directive
方法进行全局注册。 bind
钩子函数用于在指令绑定到元素时执行初始化工作。在这里,我们绑定了mouseenter
和mouseleave
事件来实现鼠标悬停时改变背景颜色的效果。binding
参数包含指令的信息,可以通过binding.value
获取指令的绑定值。在本例中,我们将其用作背景颜色,如果未提供绑定值,则使用默认的lightblue
。
这个示例演示了如何创建一个简单的自定义指令,以及如何使用该指令在鼠标悬停时改变元素的背景颜色。
5.template属性及标签
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue.js template 属性和标签示例</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
</head>
<body>
<div id="app">
<h2>Vue.js template 属性和标签示例</h2>
<!-- 使用 template 标签定义模板 -->
<template id="custom-template">
<div>
<h3>{{ title }}</h3>
<p>{{ content }}</p>
</div>
</template>
<!-- 使用组件,引用 template 标签中定义的模板 -->
<div>
<custom-component></custom-component>
</div>
</div>
<script>
// 注册一个局部组件 CustomComponent
Vue.component('custom-component', {
template: '#custom-template', // 使用 template 属性引用模板
data() {
return {
title: '这是一个自定义组件',
content: '这是组件的内容部分。'
};
}
});
new Vue({
el: '#app'
});
</script>
</body>
</html>
在这个示例中:
- 使用
<template>
标签定义了一个 id 为custom-template
的模板,里面包含了一个简单的组件结构,包括标题和内容。 - 在 Vue 实例中,通过
Vue.component
方法注册了一个局部组件custom-component
,并在组件的template
属性中使用了#custom-template
来引用之前定义的模板。 - 在组件的
data
中定义了标题和内容的数据,这些数据在模板中通过插值表达式{{ title }}
和{{ content }}
进行动态渲染。
这个例子展示了如何使用 Vue 的 template
属性和 <template>
标签来定义和引用组件的模板,使得组件的结构和数据可以动态地展示在页面上。
6.动态样式处理
1. 对象语法
使用对象语法可以根据数据的状态动态绑定样式。
<template>
<div :class="{ active: isActive, 'text-danger': hasError }">
<!-- 组件内容 -->
</div>
</template>
<script>
export default {
data() {
return {
isActive: true,
hasError: false
};
}
};
</script>
<style>
.active {
font-weight: bold;
}
.text-danger {
color: red;
}
</style>
2. 数组语法
使用数组语法可以根据多个条件动态绑定样式类。
<template>
<div :class="[activeClass, errorClass]">
<!-- 组件内容 -->
</div>
</template>
<script>
export default {
data() {
return {
isActive: true,
hasError: false
};
},
computed: {
activeClass() {
return this.isActive ? 'active' : '';
},
errorClass() {
return this.hasError ? 'text-danger' : '';
}
}
};
</script>
<style>
.active {
font-weight: bold;
}
.text-danger {
color: red;
}
</style>
3. 绑定内联样式
使用对象语法绑定内联样式。
<template>
<div :style="{ color: activeColor, fontSize: fontSize + 'px' }">
<!-- 组件内容 -->
</div>
</template>
<script>
export default {
data() {
return {
activeColor: 'red',
fontSize: 14
};
}
};
</script>
4. 使用计算属性
使用计算属性根据复杂逻辑动态计算样式。
<template>
<div :style="computedStyles">
<!-- 组件内容 -->
</div>
</template>
<script>
export default {
data() {
return {
isActive: true,
fontSize: 14
};
},
computed: {
computedStyles() {
return {
color: this.isActive ? 'red' : 'blue',
fontSize: this.fontSize + 'px'
};
}
}
};
</script>
5. 动态绑定类名和内联样式
结合使用动态类名和内联样式。
<template>
<div :class="[activeClass, { 'text-danger': hasError }]" :style="{ fontSize: fontSize + 'px' }">
<!-- 组件内容 -->
</div>
</template>
<script>
export default {
data() {
return {
isActive: true,
hasError: false,
fontSize: 14
};
},
computed: {
activeClass() {
return this.isActive ? 'active' : '';
}
}
};
</script>
<style>
.active {
font-weight: bold;
}
.text-danger {
color: red;
}
</style>
在Vue.js中,处理动态样式可以通过:class和:style指令,以及计算属性等方式实现。根据你的具体需求和场景,选择合适的方法来动态设置组件的样式,这些方法可以灵活应对不同的样式变化需求。
7.$set及Vue.set
假设我们有一个 Vue 组件,显示用户的基本信息,包括姓名和年龄。用户信息保存在一个对象 user
中,初始时只有姓名。我们希望通过点击按钮来动态添加用户的年龄信息。
<template>
<div>
<p>Name: {{ user.name }}</p>
<p v-if="user.age">Age: {{ user.age }}</p>
<button @click="addAge">Add Age</button>
</div>
</template>
<script>
export default {
data() {
return {
user: {
name: 'John'
}
};
},
methods: {
addAge() {
// 添加用户的年龄信息
// 使用 Vue.set 或 $set 来添加响应式属性
this.$set(this.user, 'age', 30);
}
}
};
</script>
在上面的例子中:
user
对象初始时只有name
属性。- 点击 "Add Age" 按钮会调用
addAge
方法。 - 在
addAge
方法中,我们使用this.$set(this.user, 'age', 30)
来向user
对象添加age
属性,并赋值为30
。这里this.$set
可以直接用$set
替代,效果相同。
这样做的好处是,通过 $set
或 Vue.set
方法添加的属性会是响应式的,即使后来添加的属性也能触发视图的重新渲染。这在处理动态数据的时候非常有用,特别是在使用 Vue.js 的过程中,数据通常是响应式的,这样能够保证界面能及时更新以反映最新的数据状态。
二、进阶
1.事件修饰符
在 Vue.js 2 中,事件修饰符用于在处理 DOM 事件时进行额外的控制或增强。下面我会通过例子来介绍 Vue.js 2 中常见的事件修饰符及其用法。
假设我们有一个按钮,希望在点击时阻止默认行为、阻止事件冒泡,并只有在按下 Enter
键时触发事件。我们会用到以下事件修饰符:
在实际开发中,这些事件修饰符可以根据需要进行组合使用,以达到精确控制事件行为的目的,增强 Vue 组件的交互体验和功能。
2.watch监听器
.stop
: 阻止事件冒泡.prevent
: 阻止事件默认行为.capture
: 使用事件捕获模式.self
: 只当事件是从触发元素自身触发时才触发回调.once
: 事件将只会触发一次.passive
: 指示 Vue 应该使用{ passive: true }
选项添加事件监听器-
<template> <div> <!-- 使用事件修饰符 --> <button @click.enter="handleClick" @click.stop.prevent="handleClick">Click me</button> </div> </template> <script> export default { methods: { handleClick() { console.log('Button clicked'); } } }; </script>
解释每个事件修饰符的作用:
@click.enter
: 当按下Enter
键时触发点击事件。@click.stop.prevent
: 同时使用.stop
和.prevent
修饰符,.stop
阻止事件冒泡,.prevent
阻止默认行为。这样点击按钮时既阻止了事件冒泡,又阻止了默认行为。
在 Vue.js 中,watch
是一个用于监听 Vue 实例中数据变化的功能。它允许你监视一个数据,并在数据变化时执行自定义逻辑。以下是一个简单的案例,演示如何使用 watch
监听 Vue 实例中的数据变化:
假设我们有一个需求:当用户输入一个名字时,我们希望实时地将其转换为大写显示。我们可以使用 watch
来监听输入框中的名字变化,并在变化时进行大写转换并显示出来。
<template>
<div>
<input type="text" v-model="name" placeholder="Enter your name">
<p>Your name in uppercase: {{ nameInUpperCase }}</p>
</div>
</template>
<script>
export default {
data() {
return {
name: '',
nameInUpperCase: ''
};
},
watch: {
// 监听名字变化
name(newName, oldName) {
this.nameInUpperCase = newName.toUpperCase();
}
}
};
</script>
解释每个部分的作用:
-
<input type="text" v-model="name" placeholder="Enter your name">
: 这是一个输入框,使用了v-model
指令将输入框的值与 Vue 实例中的name
数据属性进行双向绑定。 -
{{ nameInUpperCase }}
: 这里展示了经过watch
监听后转换为大写的名字。 -
data() { ... }
: Vue 实例的数据选项,包含了name
和nameInUpperCase
两个属性,初始值为空字符串。 -
watch: { ... }
: Vue 实例的watch
选项,包含一个名为name
的监听器,当name
变化时,会触发其中的回调函数。回调函数接收两个参数newName
和oldName
,分别表示新值和旧值。 -
name(newName, oldName) { ... }
:name
的监听器回调函数,在这里我们简单地将newName
转换为大写形式,并将结果赋给nameInUpperCase
。
通过这个例子,你可以看到如何使用 watch
监听数据变化,并在变化时执行自定义的逻辑。这种方式非常适合需要在数据变化时进行异步操作或复杂计算的场景。
3.生命周期
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue.js Lifecycle Example</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
</head>
<body>
<div id="app">
<h2>Vue.js Lifecycle Example</h2>
<p>{{ message }}</p>
</div>
<script>
new Vue({
el: '#app',
data() {
return {
message: 'Vue.js Lifecycle Example'
};
},
beforeCreate() {
console.log('beforeCreate hook');
},
created() {
console.log('created hook');
},
beforeMount() {
console.log('beforeMount hook');
},
mounted() {
console.log('mounted hook');
},
beforeUpdate() {
console.log('beforeUpdate hook');
},
updated() {
console.log('updated hook');
},
beforeDestroy() {
console.log('beforeDestroy hook');
},
destroyed() {
console.log('destroyed hook');
}
});
</script>
</body>
</html>
-
HTML 结构:
- 使用了一个简单的
div
元素作为 Vue 实例的挂载点,并绑定了一个数据message
。
- 使用了一个简单的
-
Vue 实例:
- 在
new Vue()
中,我们定义了一个 Vue 实例。 el: '#app'
将 Vue 实例挂载到了 id 为app
的 DOM 元素上。data()
方法返回了一个包含message
初始值的对象。
- 在
-
生命周期钩子函数:
-
创建阶段:
beforeCreate()
:在实例初始化之后,数据观测和事件配置之前调用。created()
:实例已经完成数据观测,属性和方法的运算,但是挂载阶段尚未开始。
-
挂载阶段:
beforeMount()
:在开始挂载之前调用,相关的 render 函数首次被调用。mounted()
:el 被新创建的 vm.$el 替换,并挂载到实例上之后调用该钩子。
-
更新阶段:
beforeUpdate()
:数据更新时调用,但是虚拟 DOM 尚未重新渲染。updated()
:由于数据更改导致的虚拟 DOM 重新渲染和打补丁后调用。
-
销毁阶段:
beforeDestroy()
:实例销毁之前调用。在这一步,实例仍然完全可用。destroyed()
:Vue 实例销毁后调用,清理工作应该在这里完成。
-
-
控制台输出:
- 打开浏览器控制台,你会看到以上生命周期钩子函数输出的信息,以帮助理解它们的执行顺序和作用。
这个例子展示了 Vue.js 实例从创建到销毁的完整生命周期过程,每个阶段的钩子函数都有其特定的用途和时机,可用于执行相应的操作和逻辑。
4.filter过滤器
在 Vue.js 2.x 中,过滤器(filters)是用来处理文本格式化的功能,可以在数据显示之前进行一些常见的文本处理。以下是一个简单的案例代码,展示了如何定义和使用 Vue.js 2.x 的过滤器:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue.js Filter Example</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
</head>
<body>
<div id="app">
<h2>Vue.js Filter Example</h2>
<p>Original message: {{ message }}</p>
<p>Filtered message (uppercase): {{ message | uppercase }}</p>
<p>Filtered message (reversed): {{ message | reverse }}</p>
</div>
<script>
// 定义全局过滤器
Vue.filter('uppercase', function(value) {
if (!value) return '';
return value.toString().toUpperCase();
});
Vue.filter('reverse', function(value) {
if (!value) return '';
return value.split('').reverse().join('');
});
new Vue({
el: '#app',
data() {
return {
message: 'Hello, Vue.js Filters!'
};
}
});
</script>
</body>
</html>
-
HTML 结构:
- 使用了一个简单的
div
元素作为 Vue 实例的挂载点,并绑定了一个数据message
。 - 在三个
<p>
标签中,展示了不同过滤器处理后的message
。
- 使用了一个简单的
-
Vue 实例:
- 在
new Vue()
中,我们定义了一个 Vue 实例。 el: '#app'
将 Vue 实例挂载到了 id 为app
的 DOM 元素上。data()
方法返回了一个包含message
初始值的对象。
- 在
-
过滤器:
- 全局过滤器:
Vue.filter('uppercase', ...)
:定义了一个名为uppercase
的全局过滤器,用来将字符串转换为大写形式。Vue.filter('reverse', ...)
:定义了一个名为reverse
的全局过滤器,用来将字符串进行反转操作。
- 全局过滤器:
-
模板中的过滤器使用:
{{ message | uppercase }}
:应用uppercase
过滤器将message
的值转换为大写显示。{{ message | reverse }}
:应用reverse
过滤器将message
的值反转显示。
-
运行效果:
- 打开浏览器,加载该 HTML 文件,你会看到
message
的原始内容以及应用过滤器后的效果,分别显示为大写形式和反转形式。
- 打开浏览器,加载该 HTML 文件,你会看到
过滤器是 Vue.js 中用来格式化数据的便捷方式,可以用于处理文本、日期、数值等各种类型的数据显示需求,使得模板更加清晰和易于维护。