【AI Generated】从零学习Vue.js

  • 【AI Generated】从零学习Vue.js已关闭评论
  • 45 次浏览
  • A+
所属分类:Web前端
摘要

Vue.js 是一个用于构建用户界面的渐进式 JavaScript 框架。它的设计理念是尽量简单,同时提供足够的灵活性和性能来应对复杂的应用需求。本书将带你从零开始学习 Vue.js,逐步掌握其核心概念和高级特性。


从零学习Vue.js

目录

  1. 引言
  2. 准备工作
  3. Vue.js 基础
    • 3.1 Vue 实例
    • 3.2 模板语法
    • 3.3 数据绑定
    • 3.4 计算属性和侦听器
    • 3.5 Class 与 Style 绑定
    • 3.6 条件渲染
    • 3.7 列表渲染
    • 3.8 事件处理
    • 3.9 表单输入绑定
  4. Vue.js 组件
    • 4.1 组件基础
    • 4.2 组件注册
    • 4.3 父子组件通信
    • 4.4 插槽
    • 4.5 动态组件
    • 4.6 异步组件
  5. Vue Router
    • 5.1 路由基础
    • 5.2 动态路由匹配
    • 5.3 嵌套路由
    • 5.4 路由守卫
    • 5.5 路由元信息
    • 5.6 导航守卫
    • 5.7 路由懒加载
  6. Vuex 状态管理
    • 6.1 Vuex 基础
    • 6.2 核心概念
    • 6.3 模块化
    • 6.4 中间件
    • 6.5 辅助函数
  7. 项目实战
    • 7.1 项目初始化
    • 7.2 组件设计
    • 7.3 路由配置
    • 7.4 状态管理
    • 7.5 API 集成
    • 7.6 部署与优化
  8. 进阶概念
    • 8.1 自定义指令
    • 8.2 混入
    • 8.3 插件
    • 8.4 服务端渲染 (SSR)
    • 8.5 Vue 3 新特性
  9. 总结与展望

1. 引言

Vue.js 是一个用于构建用户界面的渐进式 JavaScript 框架。它的设计理念是尽量简单,同时提供足够的灵活性和性能来应对复杂的应用需求。本书将带你从零开始学习 Vue.js,逐步掌握其核心概念和高级特性。

2. 准备工作

在开始学习 Vue.js 之前,你需要具备以下基础知识:

  • HTML/CSS 基础
  • JavaScript 基础

此外,你需要准备以下开发工具:

  • 一个现代浏览器(如 Chrome 或 Firefox)
  • 一个代码编辑器(如 VS Code 或 Sublime Text)
  • Node.js 和 npm(用于管理项目依赖)

安装 Node.js 和 npm:

  1. 访问 Node.js 官网 下载并安装适用于你操作系统的版本。
  2. 安装完成后,打开终端(或命令提示符)并运行以下命令,确认安装成功:
    node -v npm -v 

3. Vue.js 基础

3.1 Vue 实例

Vue.js 应用的核心是 Vue 实例。你可以通过创建一个新的 Vue 实例来启动一个 Vue 应用。

<!DOCTYPE html> <html> <head>   <title>Vue.js 学习</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> 

3.2 模板语法

Vue.js 使用一种基于 HTML 的模板语法,允许你声明式地绑定数据到 DOM。

<div id="app">   <p>{{ message }}</p>   <p v-bind:title="message">鼠标悬停查看消息</p> </div> <script>   var app = new Vue({     el: '#app',     data: {       message: 'Hello Vue!'     }   }); </script> 

3.3 数据绑定

Vue.js 提供了两种主要的数据绑定方式:插值和指令。

<div id="app">   <p>{{ message }}</p>   <input v-model="message"> </div> <script>   var app = new Vue({     el: '#app',     data: {       message: 'Hello Vue!'     }   }); </script> 

3.4 计算属性和侦听器

计算属性用于对数据进行计算和处理,而侦听器用于监听数据的变化。

<div id="app">   <p>原始消息: {{ message }}</p>   <p>反转消息: {{ reversedMessage }}</p> </div> <script>   var app = new Vue({     el: '#app',     data: {       message: 'Hello Vue!'     },     computed: {       reversedMessage: function () {         return this.message.split('').reverse().join('');       }     }   }); </script> 

3.5 Class 与 Style 绑定

你可以动态地绑定 HTML 元素的 class 和 style。

<div id="app">   <div v-bind:class="{ active: isActive }">Class 绑定</div>   <div v-bind:style="styleObject">Style 绑定</div> </div> <script>   var app = new Vue({     el: '#app',     data: {       isActive: true,       styleObject: {         color: 'red',         fontSize: '20px'       }     }   }); </script> 

3.6 条件渲染

使用 v-if 指令可以根据条件渲染元素。

<div id="app">   <p v-if="seen">现在你看到我了</p> </div> <script>   var app = new Vue({     el: '#app',     data: {       seen: true     }   }); </script> 

3.7 列表渲染

使用 v-for 指令可以渲染一个列表。

<div id="app">   <ul>     <li v-for="item in items" v-bind:key="item.id">       {{ item.text }}     </li>   </ul> </div> <script>   var app = new Vue({     el: '#app',     data: {       items: [         { id: 1, text: '苹果' },         { id: 2, text: '香蕉' },         { id: 3, text: '橙子' }       ]     }   }); </script> 

3.8 事件处理

使用 v-on 指令可以监听 DOM 事件。

<div id="app">   <button v-on:click="greet">点击我</button> </div> <script>   var app = new Vue({     el: '#app',     data: {       message: 'Hello Vue!'     },     methods: {       greet: function () {         alert(this.message);       }     }   }); </script> 

3.9 表单输入绑定

使用 v-model 指令可以实现表单输入与应用状态的双向绑定。

<div id="app">   <input v-model="message">   <p>{{ message }}</p> </div> <script>   var app = new Vue({     el: '#app',     data: {       message: 'Hello Vue!'     }   }); </script> 

4. Vue.js 组件

4.1 组件基础

组件是 Vue.js 的核心概念,用于构建可复用的 UI 片段。

<div id="app">   <my-component></my-component> </div> <script>   Vue.component('my-component', {     template: '<p>这是一个组件</p>'   });   var app = new Vue({     el: '#app'   }); </script> 

4.2 组件注册

组件可以全局注册或局部注册。

<!-- 全局注册 --> <script>   Vue.component('my-component', {     template: '<p>这是一个全局注册的组件</p>'   }); </script>  <!-- 局部注册 --> <script>   var Child = {     template: '<p>这是一个局部注册的组件</p>'   };   var app = new Vue({     el: '#app',     components: {       'my-component': Child     }   }); </script> 

4.3 父子组件通信

父组件可以通过 props 向子组件传递数据,子组件可以通过事件向父组件发送消息。

<div id="app">   <child-component v-bind:message="parentMessage"></child-component> </div> <script>   Vue.component('child-component', {     props: ['message'],     template: '<p>{{ message }}</p>'   });   var app = new Vue({     el: '#app',     data: {       parentMessage: '来自父组件的消息'     }   }); </script> 

4.4 插槽

插槽允许你在组件中插入内容。

<div id="app">   <alert-box>     <strong>注意!</strong> 这是一个重要的消息。   </alert-box> </div> <script>   Vue.component('alert-box', {     template: `       <div class="alert-box">         <slot></slot>       </div>     `   });   var app = new Vue({     el: '#app'   }); </script> 

4.5 动态组件

动态组件允许你在同一个挂载点动态切换多个组件。

<div id="app">   <component v-bind:is="currentComponent"></component>   <button v-on:click="currentComponent = 'component-a'">显示 A</button>   <button v-on:click="currentComponent = 'component-b'">显示 B</button> </div> <script>   Vue.component('component-a', {     template: '<p>组件 A</p>'   });   Vue.component('component-b', {     template: '<p>组件 B</p>'   });   var app = new Vue({     el: '#app',     data: {       currentComponent: 'component-a'     }   }); </script> 

4.6 异步组件

异步组件可以按需加载,减少初始加载时间。

Vue.component('async-example', function (resolve, reject) {   setTimeout(function () {     // 向 `resolve` 回调传递组件定义     resolve({       template: '<div>异步组件加载成功!</div>'     })   }, 1000) }) 

5. Vue Router

5.1 路由基础

Vue Router 是 Vue.js 的官方路由管理器,用于构建单页应用。

<!DOCTYPE html> <html> <head>   <title>Vue Router 学习</title>   <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>   <script src="https://cdn.jsdelivr.net/npm/vue-router@3"></script> </head> <body>   <div id="app">     <router-link to="/home">首页</router-link>     <router-link to="/about">关于</router-link>     <router-view></router-view>   </div>   <script>     const Home = { template: '<p>首页</p>' }     const About = { template: '<p>关于</p>' }      const routes = [       { path: '/home', component: Home },       { path: '/about', component: About }     ]      const router = new VueRouter({       routes     })      var app = new Vue({       el: '#app',       router     });   </script> </body> </html> 

5.2 动态路由匹配

动态路由匹配允许你在路由路径中使用参数。

<div id="app">   <router-link to="/user/1">用户 1</router-link>   <router-link to="/user/2">用户 2</router-link>   <router-view></router-view> </div> <script>   const User = {     template: '<p>用户 ID: {{ $route.params.id }}</p>'   }    const routes = [     { path: '/user/:id', component: User }   ]    const router = new VueRouter({     routes   })    var app = new Vue({     el: '#app',     router   }); </script> 

5.3 嵌套路由

嵌套路由允许你在路由视图中嵌套其他路由视图。

<div id="app">   <router-link to="/user/1">用户 1</router-link>   <router-link to="/user/2">用户 2</router-link>   <router-view></router-view> </div> <script>   const User = {     template: `       <div>         <h2>用户 ID: {{ $route.params.id }}</h2>         <router-link to="profile">个人资料</router-link>         <router-link to="posts">帖子</router-link>         <router-view></router-view>       </div>     `   }   const UserProfile = { template: '<p>个人资料</p>' }   const UserPosts = { template: '<p>帖子</p>' }    const routes = [     { path: '/user/:id', component: User,       children: [         { path: 'profile', component: UserProfile },         { path: 'posts', component: UserPosts }       ]     }   ]    const router = new VueRouter({     routes   })    var app = new Vue({     el: '#app',     router   }); </script> 

5.4 路由守卫

路由守卫允许你在导航到某个路由之前执行一些逻辑。

<div id="app">   <router-link to="/home">首页</router-link>   <router-link to="/about">关于</router-link>   <router-view></router-view> </div> <script>   const Home = { template: '<p>首页</p>' }   const About = { template: '<p>关于</p>' }    const routes = [     { path: '/home', component: Home },     { path: '/about', component: About, beforeEnter: (to, from, next) => {       if (confirm('你确定要进入关于页面吗?')) {         next()       } else {         next(false)       }     }}   ]    const router = new VueRouter({     routes   })    var app = new Vue({     el: '#app',     router   }); </script> 

5.5 路由元信息

路由元信息允许你在路由配置中添加自定义数据。

<div id="app">   <router-link to="/home">首页</router-link>   <router-link to="/about">关于</router-link>   <router-view></router-view> </div> <script>   const Home = { template: '<p>首页</p>' }   const About = { template: '<p>关于</p>' }    const routes = [     { path: '/home', component: Home },     { path: '/about', component: About, meta: { requiresAuth: true } }   ]    const router = new VueRouter({     routes   })    router.beforeEach((to, from, next) => {     if (to.matched.some(record => record.meta.requiresAuth)) {       // 这里可以添加你的认证逻辑       if (!auth.isAuthenticated()) {         next({ path: '/login' })       } else {         next()       }     } else {       next()     }   })    var app = new Vue({     el: '#app',     router   }); </script> 

5.6 导航守卫

导航守卫可以在路由切换前后执行逻辑。

<div id="app">   <router-link to="/home">首页</router-link>   <router-link to="/about">关于</router-link>   <router-view></router-view> </div> <script>   const Home = { template: '<p>首页</p>' }   const About = { template: '<p>关于</p>' }    const routes = [     { path: '/home', component: Home },     { path: '/about', component: About }   ]    const router = new VueRouter({     routes   })    router.beforeEach((to, from, next) => {     console.log('全局前置守卫')     next()   })    router.afterEach((to, from) => {     console.log('全局后置守卫')   })    var app = new Vue({     el: '#app',     router   }); </script> 

5.7 路由懒加载

路由懒加载可以按需加载路由组件,减少初始加载时间。

const routes = [   {     path: '/home',     component: () => import('./components/Home.vue')   },   {     path: '/about',     component: () => import('./components/About.vue')   } ]  const router = new VueRouter({   routes }) 

6. Vuex 状态管理

6.1 Vuex 基础

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

<!DOCTYPE html> <html> <head>   <title>Vuex 学习</title>   <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>   <script src="https://cdn.jsdelivr.net/npm/vuex@3"></script> </head> <body>   <div id="app">     <p>{{ count }}</p>     <button @click="increment">增加</button>   </div>   <script>     const store = new Vuex.Store({       state: {         count: 0       },       mutations: {         increment (state) {           state.count++         }       }     })      var app = new Vue({       el: '#app',       store,       computed: {         count () {           return this.$store.state.count         }       },       methods: {         increment () {           this.$store.commit('increment')         }       }     });   </script> </body> </html> 

6.2 核心概念

Vuex 的核心概念包括状态(state)、变更(mutations)、动作(actions)和 getters。

const store = new Vuex.Store({   state: {     count: 0   },   mutations: {     increment (state) {       state.count++     }   },   actions: {     incrementAsync ({ commit }) {       setTimeout(() => {         commit('increment')       }, 1000)     }   },   getters: {     doubleCount: state => state.count * 2   } }) 

6.3 模块化

Vuex 允许你将状态管理逻辑拆分成模块,每个模块拥有自己的 state、mutations、actions 和 getters。

const moduleA = {   state: { count: 0 },   mutations: { increment (state) { state.count++ } },   actions: { incrementAsync ({ commit }) { commit('increment') } },   getters: { doubleCount: state => state.count * 2 } }  const moduleB = {   state: { count: 0 },   mutations: { increment (state) { state.count++ } },   actions: { incrementAsync ({ commit }) { commit('increment') } },   getters: { doubleCount: state => state.count * 2 } }  const store = new Vuex.Store({   modules: {     a: moduleA,     b: moduleB   } }) 

6.4 中间件

Vuex 支持插件机制,可以在状态变更时执行一些逻辑。

const myPlugin = store => {   store.subscribe((mutation, state) => {     console.log(mutation.type)     console.log(mutation.payload)   }) }  const store = new Vuex.Store({   state: { count: 0 },   mutations: { increment (state) { state.count++ } },   plugins: [myPlugin] }) 

6.5 辅助函数

Vuex 提供了一些辅助函数,帮助你简化代码。

<div id="app">   <p>{{ count }}</p>   <button @click="increment">增加</button> </div> <script>   const store = new Vuex.Store({     state: { count: 0 },     mutations: { increment (state) { state.count++ } },     actions: { incrementAsync ({ commit }) { commit('increment') } },     getters: { doubleCount: state => state.count * 2 }   })    var app = new Vue({     el: '#app',     store,     computed: Vuex.mapState(['count']),     methods: Vuex.mapMutations(['increment'])   }); </script> 

7. 项目实战

7.1 项目初始化

使用 Vue CLI 初始化一个新的 Vue 项目。

npm install -g @vue/cli vue create my-project cd my-project npm run serve 

7.2 组件设计

根据项目需求设计和实现各个组件。假设我们要构建一个简单的待办事项应用。

vue create todo-app cd todo-app npm run serve 

创建 components/TodoItem.vue

<template>   <li>     <input type="checkbox" v-model="todo.done">     <span>{{ todo.text }}</span>   </li> </template>  <script> export default {   props: ['todo'] } </script> 

创建 components/TodoList.vue

<template>   <ul>     <todo-item v-for="todo in todos" :key="todo.id" :todo="todo"></todo-item>   </ul> </template>  <script> import TodoItem from './TodoItem.vue'  export default {   components: {     TodoItem   },   data () {     return {       todos: [         { id: 1, text: '学习 Vue', done: true },         { id: 2, text: '学习 Vuex', done: false },         { id: 3, text: '学习 Vue Router', done: false }       ]     }   } } </script> 

App.vue 中使用 TodoList 组件:

<template>   <div id="app">     <h1>待办事项</h1>     <todo-list></todo-list>   </div> </template>  <script> import TodoList from './components/TodoList.vue'  export default {   components: {     TodoList   } } </script> 

7.3 路由配置

使用 Vue Router 配置项目的路由。

安装 Vue Router:

npm install vue-router 

创建 router/index.js

import Vue from 'vue' import Router from 'vue-router' import Home from '@/components/Home.vue' import About from '@/components/About.vue'  Vue.use(Router)  export default new Router({   routes: [     { path: '/', component: Home },     { path: '/about', component: About }   ] }) 

main.js 中引入路由:

import Vue from 'vue' import App from './App.vue' import router from './router'  Vue.config.productionTip = false  new Vue({   router,   render: h => h(App) }).$mount('#app') 

创建 components/Home.vuecomponents/About.vue

Home.vue

<template>   <div>     <h1>首页</h1>     <todo-list></todo-list>   </div> </template>  <script> import TodoList from './TodoList.vue'  export default {   components: {     TodoList   } } </script> 

About.vue

<template>   <div>     <h1>关于</h1>     <p>这是关于页面。</p>   </div> </template> 

7.4 状态管理

使用 Vuex 管理项目的全局状态。

安装 Vuex:

npm install vuex 

创建 store/index.js

import Vue from 'vue' import Vuex from 'vuex'  Vue.use(Vuex)  export default new Vuex.Store({   state: {     todos: [       { id: 1, text: '学习 Vue', done: true },       { id: 2, text: '学习 Vuex', done: false },       { id: 3, text: '学习 Vue Router', done: false }     ]   },   mutations: {     addTodo (state, todo) {       state.todos.push(todo)     }   },   actions: {     addTodo ({ commit }, todo) {       commit('addTodo', todo)     }   },   getters: {     doneTodos: state => {       return state.todos.filter(todo => todo.done)     }   } }) 

main.js 中引入 Vuex:

import Vue from 'vue' import App from './App.vue' import router from './router' import store from './store'  Vue.config.productionTip = false  new Vue({   router,   store,   render: h => h(App) }).$mount('#app') 

TodoList.vue 中使用 Vuex 状态:

<template>   <ul>     <todo-item v-for="todo in todos" :key="todo.id" :todo="todo"></todo-item>   </ul> </template>  <script> import TodoItem from './TodoItem.vue' import { mapState } from 'vuex'  export default {   components: {     TodoItem   },   computed: {     ...mapState(['todos'])   } } </script> 

7.5 API 集成

假设我们有一个简单的 API 来获取和添加待办事项。

创建 api/todos.js

import axios from 'axios'  const API_URL = 'http://example.com/api/todos'  export default {   getTodos () {     return axios.get(API_URL)   },   addTodo (todo) {     return axios.post(API_URL, todo)   } } 

在 Vuex 中使用 API:

import Vue from 'vue' import Vuex from 'vuex' import api from '@/api/todos'  Vue.use(Vuex)  export default new Vuex.Store({   state: {     todos: []   },   mutations: {     setTodos (state, todos) {       state.todos = todos     },     addTodo (state, todo) {       state.todos.push(todo)     }   },   actions: {     fetchTodos ({ commit }) {       api.getTodos().then(response => {         commit('setTodos', response.data)       })     },     addTodo ({ commit }, todo) {       api.addTodo(todo).then(response => {         commit('addTodo', response.data)       })     }   },   getters: {     doneTodos: state => {       return state.todos.filter(todo => todo.done)     }   } }) 

在组件中触发 API 请求:

<template>   <div>     <ul>       <todo-item v-for="todo in todos" :key="todo.id" :todo="todo"></todo-item>     </ul>     <input v-model="newTodoText" placeholder="添加新任务">     <button @click="addTodo">添加</button>   </div> </template>  <script> import TodoItem from './TodoItem.vue' import { mapState, mapActions } from 'vuex'  export default {   components: {     TodoItem   },   data() {     return {       newTodoText: ''     }   },   computed: {     ...mapState(['todos'])   },   methods: {     ...mapActions(['fetchTodos', 'addTodo']),     addTodo() {       const newTodo = {         text: this.newTodoText,         done: false       }       this.addTodo(newTodo)       this.newTodoText = ''     }   },   created() {     this.fetchTodos()   } } </script> 

7.6 部署与优化

将项目部署到生产环境,并进行性能优化。

  1. 构建项目
npm run build 
  1. 部署到服务器

dist 目录中的内容上传到你的服务器。

  1. 性能优化
  • 使用 Vue Router 的懒加载功能按需加载组件。
  • 使用 Vuex 的模块化功能减少状态管理的复杂性。
  • 使用 Webpack 的代码分割功能减少初始加载时间。
  • 使用 gzip 压缩减少传输数据量。

8. 进阶概念

8.1 自定义指令

自定义指令允许你在 DOM 元素上应用自定义行为。

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

在组件中使用自定义指令:

<template>   <input v-focus> </template> 

8.2 混入

混入提供了一种分发 Vue 组件可复用功能的非常灵活的方式。

const myMixin = {   created: function () {     this.hello()   },   methods: {     hello: function () {       console.log('Hello from mixin!')     }   } }  const Component = Vue.extend({   mixins: [myMixin] }) 

8.3 插件

插件是 Vue.js 的一个核心概念,用于为 Vue 添加全局功能。

const MyPlugin = {   install (Vue, options) {     Vue.mixin({       created: function () {         console.log('Hello from plugin!')       }     })   } }  Vue.use(MyPlugin) 

8.4 服务端渲染 (SSR)

Vue.js 也支持服务端渲染(SSR),用于提升首屏加载速度和 SEO。

安装 Vue SSR 工具:

npm install vue-server-renderer express 

创建 server.js

const express = require('express') const renderer = require('vue-server-renderer').createRenderer() const createApp = require('./path/to/your/app')  const server = express()  server.get('*', (req, res) => {   const app = createApp()    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) 

8.5 Vue 3 新特性

Vue 3 引入了一些新的特性和改进,包括组合式 API、性能优化、TypeScript 支持等。

组合式 API

组合式 API 提供了一种更灵活的方式来组织组件逻辑。

<template>   <div>     <p>{{ count }}</p>     <button @click="increment">增加</button>   </div> </template>  <script> import { ref } from 'vue'  export default {   setup() {     const count = ref(0)     const increment = () => {       count.value++     }      return {       count,       increment     }   } } </script> 

9. 总结与展望

通过本书的学习,你应该已经掌握了 Vue.js 的基础知识和一些高级特性。希望你能将这些知识应用到实际项目中,不断实践和探索,成为一名优秀的 Vue.js 开发者。未来,Vue.js 生态系统还会不断发展,期待你能持续关注和学习。