Nuxt.js (Vue.js 服务端渲染框架) 教程

1. 简介

1.1 Vue.js 简介

Vue.js 是一个渐进式的 JavaScript 框架,用于构建用户界面。它易于上手,同时提供了强大的功能,如组件化开发、响应式数据绑定和虚拟 DOM。

1.2 Nuxt.js 简介

Nuxt.js 是一个基于 Vue.js 的更高层次的框架,旨在简化开发过程,特别是服务端渲染 (SSR) 和静态站点生成 (SSG)。它提供了开箱即用的配置,帮助开发者快速构建高性能的 Vue.js 应用。

2. 开发环境搭建

2.1 安装 Node.js 和 npm

首先,确保你的系统上安装了 Node.js 和 npm。你可以通过以下命令检查是否已安装:

node -v
npm -v

如果没有安装,可以从 Node.js 官网 下载并安装。

2.2 安装 Vue CLI

Vue CLI 是一个官方提供的脚手架工具,用于快速搭建 Vue.js 项目。你可以通过以下命令安装:

npm install -g @vue/cli

2.3 安装 Vite

Vite 是一个现代的前端构建工具,提供了极快的开发服务器和构建速度。你可以通过以下命令安装:

npm install -g create-vite-app

3. 创建第一个 Vue 应用

3.1 使用 Vue CLI 创建项目

vue create my-first-vue-app

3.2 使用 Vite 创建项目

npm init vite@latest my-first-vue-app --template vue

4. Vue 实例和生命周期

4.1 Vue 实例

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

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

4.2 生命周期钩子

Vue 实例在创建、更新和销毁过程中会触发一系列生命周期钩子。

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

5. 模板语法和数据绑定

5.1 插值

使用双大括号 {{ }} 进行文本插值。

<div id="app">
  {{ message }}
</div>

5.2 指令

Vue.js 提供了多种指令,如 v-bind、v-model 等。

<div id="app">
  <input v-model="message" placeholder="Enter a message">
  <p>{{ message }}</p>
</div>

6. 组件化开发

6.1 定义组件

组件是 Vue.js 中的基本构建块。你可以通过 Vue.component 定义一个全局组件。

Vue.component('my-component', {
  template: '<div>A custom component!</div>'
});

6.2 使用组件

在模板中使用自定义组件。

<div id="app">
  <my-component></my-component>
</div>

7. 组件通信

7.1 Props

父组件通过 props 向子组件传递数据。

Vue.component('child-component', {
  props: ['message'],
  template: '<div>{{ message }}</div>'
});

7.2 Events

子组件通过 $emit 向父组件发送事件。

Vue.component('child-component', {
  template: '<button @click="$emit('my-event')">Click me</button>'
});

7.3 Provide/Inject

在高层次组件中提供数据,在低层次组件中注入数据。

Vue.component('parent-component', {
  provide: {
    message: 'Hello from parent'
  },
  template: '<child-component></child-component>'
});

Vue.component('child-component', {
  inject: ['message'],
  template: '<div>{{ message }}</div>'
});

8. 计算属性和侦听器

8.1 计算属性

计算属性是基于依赖缓存的属性,只有在依赖发生变化时才会重新计算。

new Vue({
  el: '#app',
  data: {
    firstName: 'John',
    lastName: 'Doe'
  },
  computed: {
    fullName() {
      return this.firstName + ' ' + this.lastName;
    }
  }
});

8.2 侦听器

侦听器用于观察数据变化并执行相应的操作。

new Vue({
  el: '#app',
  data: {
    message: 'Hello, Vue!'
  },
  watch: {
    message(newVal, oldVal) {
      console.log(`Message changed from ${oldVal} to ${newVal}`);
    }
  }
});

9. 条件渲染和列表渲染

9.1 条件渲染

使用 v-if、v-else-if 和 v-else 进行条件渲染。

<div id="app">
  <p v-if="showMessage">This is a message.</p>
  <p v-else>No message to show.</p>
</div>

9.2 列表渲染

使用 v-for 进行列表渲染。

<div id="app">
  <ul>
    <li v-for="item in items" :key="item.id">{{ item.name }}</li>
  </ul>
</div>

10. 表单输入绑定

10.1 单向绑定

使用 v-bind 进行单向绑定。

<div id="app">
  <input :value="message" @input="message = $event.target.value">
  <p>{{ message }}</p>
</div>

10.2 双向绑定

使用 v-model 进行双向绑定。

<div id="app">
  <input v-model="message">
  <p>{{ message }}</p>
</div>

11. 单文件组件 (.vue 文件)

11.1 结构

单文件组件将模板、脚本和样式封装在一个文件中。

<template>
  <div>
    <p>{{ message }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: 'Hello from a .vue file!'
    };
  }
};
</script>

<style scoped>
p {
  color: blue;
}
</style>

12. 组件注册 (全局和局部)

12.1 全局注册

使用 Vue.component 进行全局注册。

Vue.component('my-component', {
  template: '<div>A custom component!</div>'
});

12.2 局部注册

在组件内部进行局部注册。

export default {
  components: {
    'my-component': {
      template: '<div>A custom component!</div>'
    }
  }
};

13. Scoped CSS

13.1 作用域样式

使用 scoped 属性将样式限制在当前组件内。

<style scoped>
p {
  color: blue;
}
</style>

14. CSS 预处理器 (Sass, Less)

14.1 安装预处理器

安装 Sass 或 Less 预处理器。

npm install sass-loader sass --save-dev

14.2 使用预处理器

在单文件组件中使用预处理器。

<style lang="scss">
$primary-color: blue;

p {
  color: $primary-color;
}
</style>

15. 动态样式和类绑定

15.1 动态类绑定

使用 v-bind:class 动态绑定类。

<div id="app">
  <div :class="{ active: isActive }">This is a dynamic class.</div>
</div>

15.2 动态样式绑定

使用 v-bind:style 动态绑定样式。

<div id="app">
  <div :style="{ color: textColor }">This is a dynamic style.</div>
</div>

16. Vue Router

16.1 安装 Vue Router

安装 Vue Router 并配置路由。

npm install vue-router

16.2 配置路由

在主文件中配置路由。

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({
  el: '#app',
  router
});

17. Vuex 状态管理

17.1 安装 Vuex

安装 Vuex 并配置状态管理。

npm install vuex

17.2 配置 Vuex

在主文件中配置 Vuex。

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment(state) {
      state.count++;
    }
  }
});

new Vue({
  el: '#app',
  store
});

18. 混入 (Mixins)

18.1 定义混入

定义一个混入对象。

const myMixin = {
  created() {
    console.log('Mixin created');
  }
};

18.2 使用混入

在组件中使用混入。

export default {
  mixins: [myMixin],
  created() {
    console.log('Component created');
  }
};

19. 自定义指令

19.1 定义指令

定义一个自定义指令。

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

19.2 使用指令

在模板中使用自定义指令。

<input v-focus>

20. 插件系统

20.1 定义插件

定义一个插件。

const myPlugin = {
  install(Vue) {
    Vue.mixin({
      created() {
        console.log('Plugin installed');
      }
    });
  }
};

20.2 使用插件

在主文件中使用插件。

Vue.use(myPlugin);

21. 虚拟 DOM 和 diff 算法

21.1 虚拟 DOM

虚拟 DOM 是 Vue.js 中用于提高性能的一种技术,它通过在内存中维护一个虚拟的 DOM 树来减少对实际 DOM 的操作。

21.2 diff 算法

diff 算法用于比较新旧虚拟 DOM 树的差异,并只更新实际 DOM 中发生变化的部分。

22. 异步组件

22.1 定义异步组件

定义一个异步组件。

const AsyncComponent = () => ({
  component: import('./AsyncComponent.vue'),
  loading: LoadingComponent,
  error: ErrorComponent,
  delay: 200,
  timeout: 3000
});

22.2 使用异步组件

在路由中使用异步组件。

const routes = [
  { path: '/async', component: AsyncComponent }
];

23. keep-alive 组件缓存

23.1 使用 keep-alive

使用 keep-alive 组件缓存动态组件。

<keep-alive>
  <component :is="currentComponent"></component>
</keep-alive>

24. 懒加载和代码分割

24.1 懒加载

使用 import() 进行懒加载。

const AsyncComponent = () => import('./AsyncComponent.vue');

24.2 代码分割

代码分割可以将应用拆分为多个小块,按需加载。

25. Vue DevTools

25.1 安装 Vue DevTools

安装 Vue DevTools 浏览器扩展。

25.2 使用 Vue DevTools

在开发过程中使用 Vue DevTools 调试应用。

26. Vue Test Utils

26.1 安装 Vue Test Utils

安装 Vue Test Utils 进行单元测试。

npm install @vue/test-utils

26.2 编写测试

编写单元测试用例。

import { mount } from '@vue/test-utils';
import MyComponent from './MyComponent.vue';

test('renders correctly', () => {
  const wrapper = mount(MyComponent);
  expect(wrapper.html()).toMatchSnapshot();
});

27. Vue CLI

27.1 创建项目

使用 Vue CLI 创建项目。

vue create my-project

27.2 配置项目

在 vue.config.js 中配置项目。

module.exports = {
  devServer: {
    port: 8080
  }
};

28. Nuxt.js (Vue.js 服务端渲染框架)

28.1 安装 Nuxt.js

安装 Nuxt.js 并创建项目。

npx create-nuxt-app my-nuxt-app

28.2 项目结构

Nuxt.js 项目的基本结构。

my-nuxt-app/
├── assets/
├── components/
├── layouts/
├── middleware/
├── pages/
├── plugins/
├── static/
├── store/
├── nuxt.config.js
└── package.json

28.3 配置 Nuxt.js

在 nuxt.config.js 中配置 Nuxt.js。

export default {
  head: {
    title: 'My Nuxt App',
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' }
    ]
  },
  modules: [
    '@nuxtjs/axios'
  ]
};

29. 项目结构组织

29.1 目录结构

合理的目录结构有助于项目的维护和扩展。

my-project/
├── src/
│   ├── assets/
│   ├── components/
│   ├── layouts/
│   ├── middleware/
│   ├── pages/
│   ├── plugins/
│   ├── static/
│   ├── store/
│   └── nuxt.config.js
└── package.json

29.2 模块化开发

将功能模块化,便于团队协作和代码复用。

30. 代码风格和规范

30.1 ESLint

使用 ESLint 进行代码风格检查。

npm install eslint --save-dev

30.2 Prettier

使用 Prettier 进行代码格式化。

npm install prettier --save-dev