2025-04-10
编程
00

目录

1. 安装 Vue
使用 CDN
使用 npm 或 yarn 安装
2. Vue 实例
3. 模板语法
4. 计算属性与侦听器
计算属性
侦听器
5. Class 与 Style 绑定
6. 条件渲染与列表渲染
条件渲染
列表渲染
7. 表单输入绑定
8. 组件系统
9. 事件处理
基本用法
事件修饰符
10. 自定义指令
注册全局自定义指令
注册局部自定义指令
11. 插槽(Slots)
默认插槽
具名插槽
12. 动态 & 异步组件
动态组件
异步组件
13. Vuex 状态管理
安装 Vuex
创建 Store
14. Vue Router 路由管理
安装 Vue Router
基本配置
在模板中使用路由链接
15. Mixins
定义 Mixin
使用 Mixin
16. 自定义过滤器
示例:货币格式化
17. 生命周期钩子
18. 动画和过渡效果
基本用法
列表过渡
19. 表单输入组件
自定义输入组件
20. 错误处理
全局错误处理器
局部错误处理器
21. SSR(服务器端渲染)
创建一个简单的 SSR 应用
22. 测试 Vue 应用
使用 Jest 进行单元测试
23. 国际化(i18n)
安装 vue-i18n
基本配置

Vue.js 是一个用于构建用户界面的渐进式框架。Vue 2 是目前广泛使用的一个版本,它提供了简洁的 API 和强大的功能,使得开发者能够快速创建复杂的单页面应用(SPA)。以下是一个基础教程,帮助你开始使用 Vue 2。

1. 安装 Vue

使用 CDN

对于简单的项目或学习目的,你可以直接通过 CDN 引入 Vue:

html
<!DOCTYPE html> <html> <head> <title>Vue 2 Example</title> <script src="https://cdn.jsdelivr.net/npm/vue@2"></script> </head> <body> <div id="app"> {{ message }} </div> <script> var app = new Vue({ el: '#app', data: { message: 'Hello Vue!' } }); </script> </body> </html>

使用 npm 或 yarn 安装

对于更复杂的应用,推荐使用 npm 或 yarn 来安装 Vue:

bash
npm install vue@2 # 或者 yarn add vue@2

然后在你的 JavaScript 文件中引入 Vue:

javascript
import Vue from 'vue'; new Vue({ el: '#app', data: { message: 'Hello Vue!' } });

2. Vue 实例

每个 Vue 应用都是从一个 Vue 实例开始的。Vue 实例需要绑定到一个 DOM 元素,并且可以包含数据、方法、生命周期钩子等。

javascript
var vm = new Vue({ el: '#app', // 绑定元素的选择器 data: { // 数据对象 message: 'Hello Vue!' }, methods: { // 方法集合 reverseMessage: function () { this.message = this.message.split('').reverse().join(''); } } });

3. 模板语法

Vue 使用基于 HTML 的模板语法,允许你声明式地将 DOM 绑定至底层 Vue 实例的数据。

  • 文本插值:使用双大括号 {{ }} 进行文本插值。
  • 原始 HTML:使用 v-html 指令输出原始 HTML 内容。
  • 属性绑定:使用 v-bind 指令动态绑定属性。
html
<div id="app"> <p>{{ message }}</p> <p v-html="rawHtml"></p> <a v-bind:href="url">Link</a> </div> <script> new Vue({ el: '#app', data: { message: 'Hello Vue!', rawHtml: '<span style="color: red;">This should be red.</span>', url: 'https://vuejs.org' } }); </script>

4. 计算属性与侦听器

计算属性

计算属性是基于其他数据属性计算得出的属性。

html
<div id="app"> <p>Original message: "{{ message }}"</p> <p>Computed reversed message: "{{ reversedMessage }}"</p> </div> <script> var vm = new Vue({ el: '#app', data: { message: 'Hello' }, computed: { reversedMessage: function () { return this.message.split('').reverse().join(''); } } }); </script>

侦听器

当需要执行异步操作或开销较大的操作时,侦听器非常有用。

javascript
var vm = new Vue({ el: '#app', data: { question: '', answer: 'I cannot give you an answer until you ask a question!' }, watch: { question: function (newQuestion) { this.answer = 'Waiting for you to stop typing...'; this.getAnswer(); } }, methods: { getAnswer: function () { // Simulate an async operation setTimeout(() => { this.answer = 'Your question is "' + this.question + '"'; }, 1000); } } });

5. Class 与 Style 绑定

Vue 可以让你动态地添加或移除 CSS 类和内联样式。

  • 绑定 Class:
html
<div id="app"> <div v-bind:class="{ active: isActive, 'text-danger': hasError }">Class Binding</div> </div> <script> new Vue({ el: '#app', data: { isActive: true, hasError: false } }); </script>
  • 绑定 Style:
html
<div id="app"> <div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }">Style Binding</div> </div> <script> new Vue({ el: '#app', data: { activeColor: 'red', fontSize: 30 } }); </script>

6. 条件渲染与列表渲染

条件渲染

使用 v-if, v-else, v-show 等指令来实现条件渲染。

html
<div id="app"> <h1 v-if="awesome">Vue is awesome!</h1> <h1 v-else>Oh no 😢</h1> </div> <script> new Vue({ el: '#app', data: { awesome: true } }); </script>

列表渲染

使用 v-for 指令来遍历数组或对象。

html
<div id="app"> <ul> <li v-for="(item, index) in items" :key="index">{{ item.message }}</li> </ul> </div> <script> new Vue({ el: '#app', data: { items: [ { message: 'Foo' }, { message: 'Bar' } ] } }); </script>

7. 表单输入绑定

Vue 使用 v-model 指令来创建双向数据绑定。

html
<div id="app"> <input v-model="message" placeholder="edit me"> <p>Message is: {{ message }}</p> </div> <script> new Vue({ el: '#app', data: { message: '' } }); </script>

8. 组件系统

组件是 Vue 中最重要的概念之一。它们可以扩展 HTML 元素,封装可重用的代码。

javascript
Vue.component('todo-item', { props: ['todo'], template: '<li>{{ todo.text }}</li>' }); var app = new Vue({ el: '#app', data: { groceryList: [ { id: 0, text: 'Vegetables' }, { id: 1, text: 'Cheese' }, { id: 2, text: 'Whatever else humans are supposed to eat' } ] } });
html
<div id="app"> <ol> <todo-item v-for="item in groceryList" v-bind:todo="item" v-bind:key="item.id"></todo-item> </ol> </div>

9. 事件处理

Vue 提供了 v-on 指令来监听 DOM 事件,并在触发时执行 JavaScript 代码。

基本用法

html
<div id="app"> <button v-on:click="incrementCounter">Click me</button> <p>The button has been clicked {{ counter }} times.</p> </div> <script> new Vue({ el: '#app', data: { counter: 0 }, methods: { incrementCounter: function () { this.counter += 1; } } }); </script>

事件修饰符

Vue 提供了一些事件修饰符,例如 .stop, .prevent, .capture, .self 等,用于简化常见的事件行为。

  • 阻止事件冒泡:
html
<div id="app"> <div @click="doThis"> <button @click.stop="doThat">Click Me</button> </div> </div>
  • 防止默认行为:
html
<form v-on:submit.prevent="onSubmit"> <button type="submit">Submit</button> </form>

10. 自定义指令

除了内置指令(如 v-model, v-bind),Vue 还允许你注册自定义指令。

注册全局自定义指令

javascript
Vue.directive('focus', { inserted: function (el) { el.focus(); } });

使用:

html
<input v-focus>

注册局部自定义指令

javascript
new Vue({ el: '#app', directives: { focus: { inserted: function (el) { el.focus(); } } } });

11. 插槽(Slots)

插槽是 Vue 中用于分发内容的机制,允许你在组件中插入任意内容。

默认插槽

html
<!-- 子组件 --> <template> <div class="child-component"> <slot>Default content</slot> </div> </template> <!-- 父组件 --> <div id="app"> <child-component> <p>This is some content passed to the child component.</p> </child-component> </div>

具名插槽

html
<!-- 子组件 --> <template> <header> <slot name="header"></slot> </header> <main> <slot></slot> </main> <footer> <slot name="footer"></slot> </footer> </template> <!-- 父组件 --> <div id="app"> <child-component> <template v-slot:header> <h1>Here might be a page title</h1> </template> <p>A paragraph for the main content.</p> <template v-slot:footer> <p>Here's some contact info</p> </template> </child-component> </div>

12. 动态 & 异步组件

Vue 支持动态加载和异步加载组件,这对于大型应用尤其有用。

动态组件

使用 <component> 元素和 is 属性来动态切换组件。

html
<div id="app"> <button @click="currentComponent = 'ComponentA'">Load A</button> <button @click="currentComponent = 'ComponentB'">Load B</button> <component :is="currentComponent"></component> </div> <script> const ComponentA = { template: '<div>Component A</div>' }; const ComponentB = { template: '<div>Component B</div>' }; new Vue({ el: '#app', data: { currentComponent: 'ComponentA' }, components: { ComponentA, ComponentB } }); </script>

异步组件

javascript
Vue.component('async-example', function (resolve, reject) { setTimeout(function () { resolve({ template: '<div>I am async!</div>' }); }, 1000); });

13. Vuex 状态管理

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

安装 Vuex

bash
npm install vuex@3

创建 Store

javascript
import Vue from 'vue'; import Vuex from 'vuex'; Vue.use(Vuex); const store = new Vuex.Store({ state: { count: 0 }, mutations: { increment(state) { state.count++; } }, actions: { increment({ commit }) { commit('increment'); } } }); new Vue({ el: '#app', store, computed: { count() { return this.$store.state.count; } }, methods: { increment() { this.$store.dispatch('increment'); } } });

14. Vue Router 路由管理

Vue Router 是官方路由管理器,与 Vue.js 核心深度集成,让构建单页面应用变得轻而易举。

安装 Vue Router

bash
npm install vue-router@3

基本配置

javascript
import Vue from 'vue'; import VueRouter from 'vue-router'; import Home from './components/Home.vue'; import About from './components/About.vue'; Vue.use(VueRouter); const routes = [ { path: '/', component: Home }, { path: '/about', component: About } ]; const router = new VueRouter({ routes }); new Vue({ router, el: '#app' });

在模板中使用路由链接

html
<div id="app"> <router-link to="/">Home</router-link> <router-link to="/about">About</router-link> <router-view></router-view> </div>

15. Mixins

Mixins 是一种灵活的方式来复用 Vue 组件中的代码。

定义 Mixin

javascript
var myMixin = { created: function () { console.log('Mixin hook called'); }, methods: { sharedMethod: function () { console.log('This method is shared'); } } };

使用 Mixin

javascript
var vm = new Vue({ mixins: [myMixin], created: function () { console.log('Component hook called'); } });

16. 自定义过滤器

虽然 Vue 2.x 已经移除了内置的过滤器功能,但你可以通过计算属性或方法实现类似的功能。

示例:货币格式化

javascript
new Vue({ el: '#app', data: { price: 1234.56 }, filters: { currency: function (value) { if (!value) return ''; return '$' + value.toFixed(2); } } });

使用:

html
<div id="app"> <p>{{ price | currency }}</p> </div>

17. 生命周期钩子

每个 Vue 实例在创建过程中会经历一系列初始化步骤,例如设置数据观察、编译模板、挂载实例到 DOM 上等。同时,也提供了一系列生命周期钩子,让你可以在特定阶段添加自己的代码。

  • beforeCreate: 在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。
  • created: 在实例创建完成后被立即调用。
  • beforeMount: 在挂载开始之前被调用。
  • mounted: 在挂载完成后被调用。
  • beforeUpdate: 数据更新时调用,发生在虚拟 DOM 打补丁之前。
  • updated: 由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。
  • beforeDestroy: 实例销毁之前调用。
  • destroyed: 实例销毁后调用。

示例:

javascript
new Vue({ el: '#app', data: { message: 'Hello Vue!' }, beforeCreate: function () { console.log('beforeCreate'); }, created: function () { console.log('created'); }, mounted: function () { console.log('mounted'); } });

18. 动画和过渡效果

Vue 提供了一个内置的 <transition> 组件来实现元素进入或离开时的过渡效果。

基本用法

html
<div id="app"> <button @click="show = !show">Toggle</button> <transition name="fade"> <p v-if="show">Hello, Vue!</p> </transition> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2"></script> <script> new Vue({ el: '#app', data: { show: true } }); </script> <style> .fade-enter-active, .fade-leave-active { transition: opacity .5s; } .fade-enter, .fade-leave-to /* .fade-leave-active in <2.1.8 */ { opacity: 0; } </style>

列表过渡

使用 <transition-group> 来为列表项添加动画。

html
<div id="app"> <button @click="addItem">Add Item</button> <transition-group name="list" tag="ul"> <li v-for="item in items" :key="item">{{ item }}</li> </transition-group> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2"></script> <script> new Vue({ el: '#app', data: { items: [1, 2, 3], nextNum: 4 }, methods: { randomIndex: function () { return Math.floor(Math.random() * this.items.length) }, addItem: function () { this.items.splice(this.randomIndex(), 0, this.nextNum++) } } }); </script> <style> .list-enter-active, .list-leave-active { transition: all 1s; } .list-enter, .list-leave-to /* .list-leave-active for <2.1.8 */ { opacity: 0; transform: translateY(30px); } </style>

19. 表单输入组件

Vue 可以通过 v-model 实现对表单元素的双向绑定。除了基本的文本框、复选框等,还可以自定义输入组件。

自定义输入组件

javascript
Vue.component('custom-input', { props: ['value'], template: ` <input v-bind:value="value" v-on:input="$emit('input', $event.target.value)" > ` }); new Vue({ el: '#app', data: { searchText: '' } });

使用:

html
<div id="app"> <custom-input v-model="searchText"></custom-input> <p>{{ searchText }}</p> </div>

20. 错误处理

在开发过程中,正确处理错误对于维护应用的稳定性至关重要。Vue 提供了全局和局部两种方式来捕获错误。

全局错误处理器

javascript
Vue.config.errorHandler = function (err, vm, info) { console.error(`Error: ${err.toString()}\nInfo: ${info}`); };

局部错误处理器

可以在组件内部使用 errorCaptured 钩子来捕获错误。

javascript
new Vue({ // ... errorCaptured: function (err, vm, info) { console.error(`Error captured: ${err.toString()}\nInfo: ${info}`); return false; // 如果返回 false,则阻止错误向上传播 } });

21. SSR(服务器端渲染)

Vue 支持服务器端渲染(SSR),这对于提高首屏加载速度和 SEO 优化非常有用。

创建一个简单的 SSR 应用

首先安装必要的依赖:

bash
npm install vue vue-server-renderer express --save

然后创建一个简单的 Express 服务器来渲染 Vue 应用。

javascript
const Vue = require('vue'); const server = require('express')(); const renderer = require('vue-server-renderer').createRenderer(); server.get('*', (req, res) => { const app = new Vue({ data: { url: req.url }, template: `<div>访问的 URL 是: {{ url }}</div>` }); renderer.renderToString(app, (err, html) => { if (err) { res.status(500).end('Internal Server Error'); return; } res.end(` <!DOCTYPE html> <html lang="en"> <head><title>Hello</title></head> <body>${html}</body> </html> `); }); }); server.listen(8080);

22. 测试 Vue 应用

测试是软件开发的重要组成部分,Vue 生态系统中有许多工具可以帮助你测试你的 Vue 应用程序。

使用 Jest 进行单元测试

Jest 是一个流行的 JavaScript 测试框架,可以与 Vue.js 无缝集成。

首先安装相关依赖:

bash
npm install --save-dev jest @vue/test-utils vue-jest babel-jest

然后创建一个测试文件,例如 MyComponent.spec.js

javascript
import { shallowMount } from '@vue/test-utils'; import MyComponent from '@/components/MyComponent.vue'; describe('MyComponent.vue', () => { it('renders correctly', () => { const wrapper = shallowMount(MyComponent, { propsData: { msg: 'hello!' } }); expect(wrapper.text()).toContain('hello!'); }); });

最后,在 package.json 中添加一个脚本来运行测试:

json
"scripts": { "test": "jest" }

23. 国际化(i18n)

国际化是指使应用程序能够适应不同语言和地区的过程。Vue 提供了 vue-i18n 插件来简化这个过程。

安装 vue-i18n

bash
npm install vue-i18n

基本配置

javascript
import Vue from 'vue'; import VueI18n from 'vue-i18n'; Vue.use(VueI18n); const i18n = new VueI18n({ locale: 'en', // 设置默认语言 messages: { en: { message: { hello: 'hello world' } }, zh: { message: { hello: '你好,世界' } } } }); new Vue({ i18n, el: '#app', data: { locale: 'zh' }, watch: { locale(val) { this.$i18n.locale = val; } } });

使用:

html
<div id="app"> <p>{{ $t('message.hello') }}</p> </div>