Javascript

Vue3全家桶学习:从入门到实践的简单教程

本文主要是介绍Vue3全家桶学习:从入门到实践的简单教程,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
概述

Vue3全家桶学习涵盖了Vue3的基础知识、组件化开发、响应式原理、Vue Router与Vuex的使用,以及与TypeScript的结合,帮助开发者全面掌握Vue3的开发技巧。文章详细介绍了从安装配置到实战演练的全过程,旨在帮助读者快速上手并构建实际项目。此外,还提供了部署上线和常见问题的解决方法,确保项目顺利运行。

Vue3基础知识入门
Vue3简介

Vue.js 是一个渐进式 JavaScript 框架,它让构建优秀的用户界面变得非常轻松。Vue3 是 Vue.js 的最新版本,它带来了许多新特性、优化及增强,包括更好的性能、TypeScript 支持、Composition API 等。Vue3 提供了一个灵活的架构,支持自定义渲染器,这使得 Vue 可以应用于广泛的环境和运行时环境,如服务端渲染、静态站点生成、Web Components 等。

Vue3安装与配置
  1. 安装 Node.js
    首先,你需要确保已经安装了 Node.js。你可以从 Node.js 官方网站下载并安装最新版本的 Node.js。Node.js 的安装将自动安装 npm(Node Package Manager),这是 Node.js 的包管理器。

  2. 安装 Vue CLI
    Vue CLI 是一个用于快速创建 Vue.js 项目的命令行工具。安装 Vue CLI 可以使用以下命令:

    npm install -g @vue/cli
  3. 创建 Vue3 项目
    使用 Vue CLI 创建一个新的 Vue3 项目:

    vue create my-vue3-project

    在创建过程中,选择 Vue3 版本,或者在默认配置中手动选择 Vue3。

  4. 项目初始化
    创建项目后,可以使用以下命令进入项目目录并启动开发服务器:

    cd my-vue3-project
    npm run serve

    这将启动开发服务器,你可以在浏览器中打开 http://localhost:8080 查看项目。

Vue3项目结构解析

一个典型的 Vue3 项目结构如下:

my-vue3-project/
├── node_modules/
├── public/
│   ├── index.html
│   └── favicon.ico
├── src/
│   ├── assets/
│   ├── components/
│   ├── App.vue
│   ├── main.js
│   └── router/
│       └── index.js
├── .browserslistrc
├── .editorconfig
├── .eslintrc.js
├── .gitignore
├── babel.config.js
├── package.json
├── README.md
└── yarn.lock
  • public:存放静态文件,如 index.htmlfavicon.ico
  • src:存放源代码,包括组件、资源文件、路由配置等。
  • App.vue:项目的根组件。
  • main.js:项目的入口文件。
  • router:存放路由配置文件。

示例代码:根组件 App.vue

<template>
  <div id="app">
    <h1>Hello Vue3</h1>
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: 'App',
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>
Vue3组件化开发
组件的基本使用

Vue3 使用组件构建用户界面。组件可以看作是可重用的自包含的 Vue 实例。每个组件都有自己的模板、样式和逻辑。

创建组件

组件是通过 Vue 的 defineComponent 函数定义的:

import { defineComponent } from 'vue';

export default defineComponent({
  name: 'HelloWorld',
  props: {
    msg: String
  },
  template: `
    <div class="hello">
      <h1>{{ msg }}</h1>
    </div>
  `,
});

使用组件

在其他组件中使用上面定义的组件:

<template>
  <h1>{{ title }}</h1>
  <HelloWorld msg="Hello Vue3" />
</template>

<script>
import HelloWorld from './components/HelloWorld.vue';

export default {
  name: 'App',
  components: {
    HelloWorld
  },
  data() {
    return {
      title: 'App Title'
    };
  }
}
</script>
组件间的数据传递

父组件向子组件传递数据

父组件可以通过 props 向子组件传递数据:

<!-- Parent.vue -->
<template>
  <ChildComponent :message="parentMessage" />
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent
  },
  data() {
    return {
      parentMessage: 'Hello from parent'
    };
  }
}
</script>
<!-- ChildComponent.vue -->
<template>
  <div>{{ message }}</div>
</template>

<script>
export default {
  name: 'ChildComponent',
  props: {
    message: String
  }
}
</script>

子组件向父组件传递数据

子组件可以通过 $emit 触发事件,向父组件传递数据。

<!-- ChildComponent.vue -->
<template>
  <button @click="sendMessage">Send Message</button>
</template>

<script>
export default {
  name: 'ChildComponent',
  methods: {
    sendMessage() {
      this.$emit('messageSent', 'Hello from child');
    }
  }
}
</script>
<!-- Parent.vue -->
<template>
  <ChildComponent @messageSent="handleMessage" />
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  name: 'Parent',
  components: {
    ChildComponent
  },
  methods: {
    handleMessage(message) {
      console.log(message);
    }
  }
}
</script>
插槽(Slot)的使用

插槽用于向子组件传递内容。插槽可以分为默认插槽、具名插槽和作用域插槽。

默认插槽

<!-- Parent.vue -->
<template>
  <ChildComponent>
    <h2>This is default slot content</h2>
  </ChildComponent>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent
  }
}
</script>
<!-- ChildComponent.vue -->
<template>
  <div>
    <slot></slot>
  </div>
</template>

具名插槽

<!-- Parent.vue -->
<template>
  <ChildComponent>
    <template v-slot:header>
      <h1>This is header slot content</h1>
    </template>
    <template v-slot:footer>
      <p>This is footer slot content</p>
    </template>
  </ChildComponent>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent
  }
}
</script>
<!-- ChildComponent.vue -->
<template>
  <div>
    <slot name="header"></slot>
    <slot name="footer"></slot>
  </div>
</template>

作用域插槽

作用域插槽允许子组件传递数据给父组件。

<!-- ChildComponent.vue -->
<template>
  <slot v-bind:item="item"></slot>
</template>

<script>
export default {
  name: 'ChildComponent',
  data() {
    return {
      item: { id: 1, name: 'John' }
    };
  }
}
</script>
<!-- Parent.vue -->
<template>
  <ChildComponent>
    <template v-slot:default="{ item }">
      <p>ID: {{ item.id }}</p>
      <p>Name: {{ item.name }}</p>
    </template>
  </ChildComponent>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent
  }
}
</script>
Vue3响应式原理与应用
响应式数据绑定

Vue3 使用 Proxy 来实现响应式系统,这比 Vue2 中的 Object.defineProperty 更加强大。响应式数据绑定是通过 refreactive 实现的。

使用 ref

ref 用于基本数据类型:

import { ref } from 'vue';

export default {
  setup() {
    const count = ref(0);
    return { count };
  }
}

在模板中使用:

<template>
  <div>
    <p>{{ count }}</p>
    <button @click="count++">Increment</button>
  </div>
</template>

<script>
import { ref } from 'vue';

export default {
  setup() {
    const count = ref(0);
    return { count };
  }
}
</script>

使用 reactive

reactive 用于复杂的数据对象:

import { reactive } from 'vue';

export default {
  setup() {
    const state = reactive({
      count: 0,
      name: 'John'
    });
    return { state };
  }
}

在模板中使用:

<template>
  <div>
    <p>{{ state.count }}</p>
    <p>{{ state.name }}</p>
  </div>
</template>

<script>
import { reactive } from 'vue';

export default {
  setup() {
    const state = reactive({
      count: 0,
      name: 'John'
    });
    return { state };
  }
}
</script>

computed 计算属性

计算属性是基于组件内部的状态计算出的结果。

import { ref, computed } from 'vue';

export default {
  setup() {
    const a = ref(1);
    const b = ref(2);
    const sum = computed(() => a.value + b.value);
    return { a, b, sum };
  }
}

在模板中使用:

<template>
  <div>
    <p>{{ a }}</p>
    <p>{{ b }}</p>
    <p>{{ sum }}</p>
  </div>
</template>

<script>
import { ref, computed } from 'vue';

export default {
  setup() {
    const a = ref(1);
    const b = ref(2);
    const sum = computed(() => a.value + b.value);
    return { a, b, sum };
  }
}
</script>

watch 侦听器

侦听器用于监听数据的变化,并在数据变化时执行回调。

import { ref, watch } from 'vue';

export default {
  setup() {
    const count = ref(0);
    watch(count, (newValue, oldValue) => {
      console.log(`count changed from ${oldValue} to ${newValue}`);
    });
    return { count };
  }
}
计算属性与侦听器

计算属性 vs 侦听器

计算属性和侦听器都可以用于数据处理,但它们的工作方式不同。

  • 计算属性:计算属性基于依赖关系进行缓存,仅在依赖变化时重新计算。
  • 侦听器:侦听器直接监听数据的变化,并在变化时执行回调。

示例代码

import { ref, computed, watch } from 'vue';

export default {
  setup() {
    const a = ref(1);
    const b = ref(2);
    const sum = computed(() => a.value + b.value);

    watch([a, b], (newValues, oldValues) => {
      console.log(`Values changed from ${JSON.stringify(oldValues)} to ${JSON.stringify(newValues)}`);
    });

    return { a, b, sum };
  }
}

在模板中使用:

<template>
  <div>
    <p>{{ a }}</p>
    <p>{{ b }}</p>
    <p>{{ sum }}</p>
  </div>
</template>

<script>
import { ref, computed, watch } from 'vue';

export default {
  setup() {
    const a = ref(1);
    const b = ref(2);
    const sum = computed(() => a.value + b.value);

    watch([a, b], (newValues, oldValues) => {
      console.log(`Values changed from ${JSON.stringify(oldValues)} to ${JSON.stringify(newValues)}`);
    });

    return { a, b, sum };
  }
}
</script>
深浅响应式对比

示例代码:浅响应式

import { ref } from 'vue';

export default {
  setup() {
    const state = ref({
      a: 1,
      b: { text: 'hello' }
    });
    return { state };
  }
}

示例代码:深响应式

import { reactive } from 'vue';

export default {
  setup() {
    const state = reactive({
      a: 1,
      b: { text: 'hello' }
    });
    return { state };
  }
}
Vue3全家桶中的Router与Vuex
Vue Router基本使用

Vue Router 是 Vue.js 官方的路由插件,用于管理前端路由。它支持路由参数、重定向、命名路由、嵌套路由等。

安装 Vue Router

npm install vue-router

基本配置

import { createRouter, createWebHistory } from 'vue-router';

const routes = [
  { path: '/', component: Home },
  { path: '/about', component: About }
];

const router = createRouter({
  history: createWebHistory(),
  routes
});

export default router;

导入并使用路由

import { createApp } from 'vue';
import App from './App.vue';
import router from './router';

createApp(App).use(router).mount('#app');

示例代码:定义路由和组件

// router/index.js
import { createRouter, createWebHistory } from 'vue-router';
import Home from '../views/Home.vue';
import About from '../views/About.vue';

const routes = [
  { path: '/', component: Home },
  { path: '/about', component: About }
];

const router = createRouter({
  history: createWebHistory(),
  routes
});

export default router;
<!-- views/Home.vue -->
<template>
  <div>
    <h1>Home Page</h1>
  </div>
</template>
<!-- views/About.vue -->
<template>
  <div>
    <h1>About Page</h1>
  </div>
</template>
Vuex状态管理

Vuex 是一个集中式的状态管理库,用于 Vue.js 应用。它可以帮助你管理应用中的状态,使状态管理更加一致且可预测。

安装 Vuex

npm install vuex

基本配置

import { createStore } from 'vuex';

export default createStore({
  state: {
    count: 0
  },
  mutations: {
    increment(state) {
      state.count++;
    }
  },
  actions: {
    increment(context) {
      context.commit('increment');
    }
  }
});

导入并使用 Vuex

import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';

createApp(App).use(router).use(store).mount('#app');

示例代码:定义 Vuex 状态和操作

// store/index.js
import { createStore } from 'vuex';

export default createStore({
  state: {
    count: 0
  },
  mutations: {
    increment(state) {
      state.count++;
    }
  },
  actions: {
    increment(context) {
      context.commit('increment');
    }
  }
});
实战案例:使用Router与Vuex构建应用

项目结构

my-vue3-project/
├── node_modules/
├── public/
│   ├── index.html
│   └── favicon.ico
├── src/
│   ├── assets/
│   ├── components/
│   ├── App.vue
│   ├── main.js
│   └── router/
│       └── index.js
│   └── store/
│       └── index.js
├── .browserslistrc
├── .editorconfig
├── .eslintrc.js
├── .gitignore
├── babel.config.js
├── package.json
├── README.md
└── yarn.lock

示例代码:定义路由和组件

// router/index.js
import { createRouter, createWebHistory } from 'vue-router';
import Home from '../views/Home.vue';
import About from '../views/About.vue';

const routes = [
  { path: '/', component: Home },
  { path: '/about', component: About }
];

const router = createRouter({
  history: createWebHistory(),
  routes
});

export default router;
<!-- views/Home.vue -->
<template>
  <div>
    <h1>Home Page</h1>
    <p>Count: {{ count }}</p>
    <button @click="increment">Increment</button>
  </div>
</template>

<script>
import { mapState, mapActions } from 'vuex';

export default {
  computed: {
    ...mapState(['count'])
  },
  methods: {
    ...mapActions(['increment'])
  }
}
</script>
<!-- views/About.vue -->
<template>
  <div>
    <h1>About Page</h1>
  </div>
</template>

示例代码:定义 Vuex 状态和操作

// store/index.js
import { createStore } from 'vuex';

export default createStore({
  state: {
    count: 0
  },
  mutations: {
    increment(state) {
      state.count++;
    }
  },
  actions: {
    increment(context) {
      context.commit('increment');
    }
  }
});
Vue3与TypeScript结合
TypeScript基础入门

TypeScript 是 JavaScript 的超集,提供了静态类型检查,使得代码更加健壮和易于维护。TypeScript 的主要特性包括类型注解、接口、泛型等。

安装 TypeScript

npm install typescript

基本语法

// TypeScript 基本类型
let a: number = 1;
let b: string = 'hello';
let c: boolean = true;
let d: null = null;
let e: undefined = undefined;

// 数组
let arr: number[] = [1, 2, 3];
let arr2: Array<number> = [1, 2, 3];

// 对象
let obj: { name: string, age: number } = { name: 'John', age: 30 };

// 接口
interface Person {
  name: string;
  age: number;
}

let person: Person = { name: 'John', age: 30 };

// 泛型
function identity<T>(arg: T): T {
  return arg;
}

let result = identity<string>('hello');
Vue3项目中引入TypeScript

安装 Vue CLI TypeScript 插件

npm install -g @vue/cli-plugin-typescript

创建 Vue3 项目并配置 TypeScript

vue create my-vue3-project

选择 Vue3 项目模板并启用 TypeScript 插件。

示例代码:使用 TypeScript 编写 Vue 组件

<script setup lang="ts">
import { ref } from 'vue';

const count = ref(0);

function increment() {
  count.value++;
}
</script>

<template>
  <div>
    <p>{{ count }}</p>
    <button @click="increment">Increment</button>
  </div>
</template>

<style scoped>
p {
  font-size: 20px;
}
</style>
Type安全的组件开发

使用 TypeScript 定义 Props

<script setup lang="ts">
import { defineComponent, ref, defineProps } from 'vue';

interface Props {
  message: string;
}

const props = defineProps<Props>();

const count = ref(0);

function increment() {
  count.value++;
}
</script>

<template>
  <div>
    <p>{{ props.message }}</p>
    <p>{{ count }}</p>
    <button @click="increment">Increment</button>
  </div>
</template>

使用 TypeScript 定义 Emits

<script setup lang="ts">
import { defineComponent, ref, defineEmits } from 'vue';

interface Props {
  message: string;
}

const props = defineProps<Props>();

const count = ref(0);

const emit = defineEmits<{
  (e: 'incremented', value: number): void;
}>();

function increment() {
  count.value++;
  emit('incremented', count.value);
}
</script>

<template>
  <div>
    <p>{{ props.message }}</p>
    <p>{{ count }}</p>
    <button @click="increment">Increment</button>
  </div>
</template>
Vue3项目实战演练
小项目实战:从零开始搭建Vue3项目

项目需求

假设我们需要创建一个简单的待办事项(To-Do List)应用。该应用需要有以下功能:

  1. 添加新的待办事项。
  2. 显示所有待办事项。
  3. 删除已添加的待办事项。

项目结构

to-do-list/
├── node_modules/
├── public/
│   ├── index.html
│   └── favicon.ico
├── src/
│   ├── assets/
│   ├── components/
│   │   └── TodoItem.vue
│   ├── App.vue
│   ├── main.ts
│   └── router/
│       └── index.ts
├── .browserslistrc
├── .editorconfig
├── .eslintrc.js
├── .gitignore
├── babel.config.js
├── package.json
├── README.md
└── yarn.lock

示例代码:定义根组件 App.vue

<script setup lang="ts">
import { ref } from 'vue';
import TodoItem from './components/TodoItem.vue';
import { useRouter } from 'vue-router';

const router = useRouter();

const todoList = ref<string[]>([]);
const newTodo = ref('');

function addTodo() {
  if (newTodo.value) {
    todoList.value.push(newTodo.value);
    newTodo.value = '';
  }
}

function deleteTodo(index: number) {
  todoList.value.splice(index, 1);
}
</script>

<template>
  <div id="app">
    <h1>To-Do List</h1>
    <input v-model="newTodo" @keyup.enter="addTodo" placeholder="Type a new todo">
    <button @click="addTodo">Add</button>
    <ul>
      <TodoItem
        v-for="(todo, index) in todoList"
        :key="index"
        :todo="todo"
        @delete="deleteTodo(index)"
      />
    </ul>
  </div>
</template>

<style>
#app {
  width: 50%;
  margin: 0 auto;
}

input {
  width: 50%;
  padding: 5px;
}

button {
  padding: 5px 10px;
}

ul {
  list-style-type: none;
  padding: 0;
}

li {
  margin: 5px 0;
}
</style>

示例代码:定义 TodoItem 组件

<script setup lang="ts">
import { defineProps, defineEmits } from 'vue';

interface Props {
  todo: string;
}

const props = defineProps<Props>();
const emit = defineEmits<{
  (e: 'delete', index: number): void;
}>();

function deleteTodo(index: number) {
  emit('delete', index);
}
</script>

<template>
  <li>
    {{ props.todo }}
    <button @click="deleteTodo">Delete</button>
  </li>
</template>
项目部署与上线
  1. 构建项目
    使用 Vue CLI 构建项目:

    npm run build

    这将在 dist 目录下生成静态文件。

  2. 部署到服务器
    将生成的静态文件部署到服务器。常见的部署方式包括使用服务器托管、云服务托管等。

  3. 域名和 DNS 设置
    如果你有自己的域名,可以在 DNS 服务提供商处设置域名解析到服务器 IP 地址。
常见问题与解决方法

问题:开发环境运行不正常

  • 检查依赖是否安装正确
    npm install
  • 检查环境配置
    确保项目的 .env 文件和 package.json 中的配置正确。

问题:生产环境构建失败

  • 确保所有依赖已安装
    npm ci
  • 检查构建脚本
    确保 package.json 中的 scripts 配置正确。

问题:Vue3项目性能问题

  • 优化代码
    使用 v-ifv-show 代替频繁的 DOM 操作。
  • 减少 DOM 操作
    尽量减少对 DOM 的频繁操作,使用虚拟 DOM 优化。
  • 预渲染
    使用 vue-server-renderer 进行服务端渲染。

问题:TypeScript 报错

  • 检查类型定义
    确保所有模块和组件都有对应的类型定义文件。
  • 更新依赖版本
    更新 Vue CLI 和 TypeScript 版本,确保兼容性。

通过以上步骤和示例代码,你可以从零开始搭建一个完整的 Vue3 项目,并将其部署到生产环境。希望这篇教程对你有所帮助!

这篇关于Vue3全家桶学习:从入门到实践的简单教程的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!