Javascript

Vue3学习:从入门到初级实战教程

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

本文详细介绍了Vue3学习的全流程,从环境搭建、基础语法到组件通信和实战项目案例,帮助你快速掌握Vue3的核心特性和开发技巧。通过本文,你将学会如何使用Vue3进行高效开发,并构建出实用的前端应用。Vue3学习不仅包括了基础知识,还涵盖了路由配置和状态管理等高级内容。

Vue3学习:从入门到初级实战教程
Vue3简介与环境搭建

Vue3的核心特性介绍

Vue.js 是一个用于构建用户界面的渐进式框架。Vue3 是 Vue.js 的最新版本,具有以下核心特性:

  1. 更好的性能:Vue3 对性能进行了显著的改进,包括更快的响应时间和更小的包体积。
  2. Composition API:引入了 Composition API,这是一种新的 API 用于更好地管理复杂组件的状态和逻辑。
  3. 更好的工具支持:Vue3 改进了开发工具的集成,提供了更好的开发者体验。
  4. Tree-shaking:Vue3 的代码结构更加模块化,有助于在构建时进行 Tree-shaking,减少打包文件的大小。
  5. TypeScript 支持:Vue3 与 TypeScript 更好地集成,提供了更好的类型支持。
  6. Teleport:提供了一个新的 <teleport> 组件,可以将内容渲染到 DOM 的任意位置。
  7. Fragments:支持在单个组件中返回多个根节点。
  8. 更好的兼容性:Vue3 对旧浏览器的支持进行了优化。
  9. 更好的错误信息:提供了更详细的错误信息和警告,有助于调试和维护。

开发环境搭建(Node.js、Vue CLI等)

在开始学习 Vue3 之前,你需要搭建开发环境。以下是搭建环境的基本步骤:

  1. 安装 Node.js 和 npm:Vue3 的开发需要 Node.js 和 npm。你可以从 Node.js 官方网站下载安装包:https://nodejs.org
  2. 安装 Vue CLI:Vue CLI 是一个工具,允许你快速搭建 Vue 项目。安装 Vue CLI 可以通过 npm:
    npm install -g @vue/cli
  3. 创建 Vue3 项目:使用 Vue CLI 创建一个新的 Vue3 项目:
    vue create my-vue3-project

    在项目创建过程中,选择 Vue3 作为项目的基础。

  4. 启动开发服务器:进入项目目录并启动开发服务器:
    cd my-vue3-project
    npm run serve

    这将启动一个开发服务器,你可以通过浏览器访问 http://localhost:8080 查看项目。

Vue3基础语法

组件化开发

Vue 是一个组件驱动的框架。组件是可复用的 Vue 实例,具有独立的作用域。

创建一个简单的组件

<!-- HelloWorld.vue -->
<template>
  <div>
    <h1>我的第一个 Vue3 组件</h1>
    <p>{{ message }}</p>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data() {
    return {
      message: 'Hello, Vue3!'
    };
  }
};
</script>

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

注册与使用组件

在其他 Vue 文件中注册并使用这个组件:

<!-- App.vue -->
<template>
  <div id="app">
    <HelloWorld />
  </div>
</template>

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

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

模板语法与HTML模板

Vue 使用模板语法将 DOM 结构与应用程序的数据绑定在一起。模板语法允许你使用 Vue 特定的语法来定义数据如何呈现。

绑定属性与事件

属性绑定:

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

<script>
export default {
  data() {
    return {
      message: ''
    };
  }
};
</script>

事件绑定:

<template>
  <div>
    <button v-on:click="increment">点击我</button>
    <p>{{ count }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      count: 0
    };
  },
  methods: {
    increment() {
      this.count++;
    }
  }
};
</script>

绑定处理(v-bind、v-model等)

v-bind 用于动态绑定属性:

<template>
  <div>
    <img v-bind:class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="imageUrl" />
  </div>
</template>

<script>
export default {
  data() {
    return {
      imageUrl: 'https://example.com/image.jpg'
    };
  }
};
</script>

v-model 用于双向数据绑定:

<template>
  <div>
    <input v-model="username" />
    <p>用户名: {{ username }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      username: ''
    };
  }
};
</script>
数据处理与响应式系统

响应式原理简述

Vue 的响应式系统基于 ES6 的 Proxy 对象。当数据发生变化时,Vue 会自动更新视图,实现视图与数据的同步。

计算属性与侦听器

计算属性

计算属性用于依赖于其他数据的属性,并在依赖的数据发生变化时自动更新计算属性。

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

<script>
export default {
  data() {
    return {
      firstName: 'John',
      lastName: 'Doe'
    };
  },
  computed: {
    fullName() {
      return `${this.firstName} ${this.lastName}`;
    }
  }
};
</script>

侦听器

侦听器用于侦听特定数据的变化,并执行自定义的回调函数。

<template>
  <div>
    <input v-model="message" />
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: ''
    };
  },
  watch: {
    message(newVal, oldVal) {
      console.log(`新值: ${newVal}, 旧值: ${oldVal}`);
    }
  }
};
</script>

生命周期钩子

Vue 组件有几个生命周期钩子,用于在生命周期的不同阶段执行自定义代码。

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

<script>
export default {
  data() {
    return {
      message: '生命周期钩子演示'
    };
  },
  created() {
    console.log('created');
  },
  mounted() {
    console.log('mounted');
  }
};
</script>
路由与状态管理

Vue Router基础配置

Vue Router 是 Vue.js 的官方路由库。

安装 Vue Router

npm install vue-router@next

基本配置

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

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

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

export default router;

路由组件示例

<!-- App.vue -->
<template>
  <div>
    <router-link to="/">首页</router-link>
    <router-link to="/about">关于</router-link>
    <router-link to="/cart">购物车</router-link>
    <router-view />
  </ идеальноСontainer>
</template>

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

Vuex简介与使用方法

Vuex 是 Vue.js 的状态管理库,适用于复杂的前端应用。

基本配置

npm install vuex@next
// store/index.js
import { createStore } from 'vuex';

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

在组件中使用 Vuex

<template>
  <div>
    <button @click="increment">点击我</button>
    <p>{{ count }}</p>
  </div>
</template>

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

export default {
  computed: {
    ...mapState(['count'])
  },
  methods: {
    ...mapActions(['increment'])
  }
};
</script>

路由与状态管理结合的简单项目实践

结合 Vue Router 和 Vuex 的项目示例:

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

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

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

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

export default createStore({
  state: {
    count: 0,
    cart: []
  },
  mutations: {
    increment(state) {
      state.count++;
    },
    addToCart(state, product) {
      state.cart.push(product);
    }
  },
  actions: {
    increment({ commit }) {
      commit('increment');
    },
    addToCart({ commit }, product) {
      commit('addToCart', product);
    }
  },
  getters: {
    count: (state) => state.count,
    cart: (state) => state.cart
  }
});
<!-- App.vue -->
<template>
  <div>
    <router-link to="/">首页</router-link>
    <router-link to="/about">关于</router-link>
    <router-link to="/cart">购物车</router-link>
    <router-view />
  </div>
</template>

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

export default {
  computed: {
    ...mapState(['count', 'cart'])
  },
  methods: {
    ...mapActions(['increment', 'addToCart'])
  }
};
</script>
<!-- Home.vue -->
<template>
  <div>
    <h1>首页</h1>
    <button @click="increment">点击我</button>
    <p>当前计数: {{ count }}</p>
  </div>
</template>

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

export default {
  computed: {
    ...mapState(['count'])
  },
  methods: {
    ...mapActions(['increment'])
  }
};
</script>
<!-- About.vue -->
<template>
  <div>
    <h1>关于</h1>
    <p>当前计数: {{ count }}</p>
  </div>
</template>

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

export default {
  computed: {
    ...mapState(['count'])
  }
};
</script>
<!-- ShoppingCart.vue -->
<template>
  <div>
    <h1>购物车</h1>
    <ul>
      <li v-for="product in cart" :key="product.id">
        {{ product.name }} - {{ product.price }}
      </li>
    </ul>
  </div>
</template>

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

export default {
  computed: {
    ...mapState(['cart'])
  }
};
</script>
组件通信

父子组件通信

父组件向子组件传递数据:

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

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

export default {
  components: {
    Child
  },
  data() {
    return {
      parentMessage: '从父组件传递过来的消息'
    };
  }
};
</script>
<!-- Child.vue -->
<template>
  <div>
    <p>{{ message }}</p>
  </div>
</template>

<script>
export default {
  props: {
    message: {
      type: String,
      default: ''
    }
  }
};
</script>

子组件向父组件传递数据:

<!-- Parent.vue -->
<template>
  <div>
    <Child @child-event="handleChildEvent" />
  </div>
</template>

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

export default {
  components: {
    Child
  },
  methods: {
    handleChildEvent(message) {
      console.log('子组件传递的消息:', message);
    }
  }
};
</script>
<!-- Child.vue -->
<template>
  <div>
    <button @click="sendMessage">点击我</button>
  </div>
</template>

<script>
export default {
  methods: {
    sendMessage() {
      this.$emit('child-event', '从子组件传递的消息');
    }
  }
};
</script>

兄弟组件通信

使用事件总线(Event Bus)进行兄弟组件的通信:

<!-- EventBus.js -->
import Vue from 'vue';
import VueRouter from 'vue-router';

export const eventBus = new Vue({
  router: new VueRouter()
});
<!-- Child1.vue -->
<template>
  <div>
    <button @click="sendMessageToChild2">发送消息到 Child2</button>
  </div>
</template>

<script>
import { eventBus } from '../EventBus';

export default {
  methods: {
    sendMessageToChild2() {
      eventBus.$emit('messageFromChild1', '来自 Child1 的消息');
    }
  }
};
</script>
<!-- Child2.vue -->
<template>
  <div>
    <p>{{ receivedMessage }}</p>
  </div>
</template>

<script>
import { eventBus } from '../EventBus';

export default {
  data() {
    return {
      receivedMessage: ''
    };
  },
  created() {
    eventBus.$on('messageFromChild1', (message) => {
      this.receivedMessage = message;
    });
  }
};
</script>

组件间的全局状态共享

使用 Vuex 进行全局状态管理:

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

export default createStore({
  state: {
    sharedState: '全局状态'
  },
  mutations: {
    updateSharedState(state, newState) {
      state.sharedState = newState;
    }
  },
  actions: {
    updateSharedState({ commit }, newState) {
      commit('updateSharedState', newState);
    }
  },
  getters: {
    sharedState: (state) => state.sharedState
  }
});
<!-- Child1.vue -->
<template>
  <div>
    <button @click="updateGlobalState">更新全局状态</button>
  </div>
</template>

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

export default {
  computed: {
    ...mapGetters(['sharedState'])
  },
  methods: {
    ...mapActions(['updateSharedState'])
  }
};
</script>
<!-- Child2.vue -->
<template>
  <div>
    <p>{{ sharedState }}</p>
  </div>
</template>

<script>
import { mapGetters } from 'vuex';

export default {
  computed: {
    ...mapGetters(['sharedState'])
  }
};
</script>
实战项目案例

从零开始构建一个简单的Vue3项目

  1. 项目初始化
vue create my-vue3-project
cd my-vue3-project
  1. 项目结构规划
.
├── public
│   └── index.html
├── src
│   ├── assets
│   ├── components
│   ├── App.vue
│   └── main.js
├── package.json
└── README.md
  1. 组件划分
<!-- src/components/Header.vue -->
<template>
  <header>
    <nav>
      <router-link to="/">首页</router-link>
      <router-link to="/about">关于</router-link>
    </nav>
  </header>
</template>
<!-- src/components/Footer.vue -->
<template>
  <footer>
    <p>&copy; 2023 我的Vue3项目</p>
  </footer>
</template>
<!-- src/components/Home.vue -->
<template>
  <div>
    <h1>首页</h1>
    <p>欢迎来到首页</p>
  </div>
</template>
<!-- src/components/About.vue -->
<template>
  <div>
    <h1>关于</h1>
    <p>关于页面的内容</p>
  </div>
</template>
  1. 路由配置
// src/router/index.js
import { createRouter, createWebHistory } from 'vue-router';
import Home from '../components/Home.vue';
import About from '../components/About.vue';

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

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

export default router;
  1. 路由注册
<!-- src/App.vue -->
<template>
  <div>
    <Header />
    <router-view />
    <Footer />
  </div>
</template>

<script>
import Header from './components/Header.vue';
import Footer from './components/Footer.vue';

export default {
  components: {
    Header,
    Footer
  }
};
</script>
  1. 项目调试与部署
npm run serve

项目结构规划与组件划分

继续细化组件划分,将不同功能分开:

<!-- src/components/ProductCard.vue -->
<template>
  <div class="product-card">
    <img :class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="product.image" alt="Product" />
    <h3>{{ product.name }}</h3>
    <p>{{ product.price }}</p>
    <button @click="addToCart">添加到购物车</button>
  </div>
</template>

<script>
export default {
  props: {
    product: {
      type: Object,
      required: true
    }
  },
  methods: {
    addToCart() {
      this.$emit('add-to-cart', this.product);
    }
  }
};
</script>

<style scoped>
.product-card {
  border: 1px solid #ccc;
  padding: 10px;
  margin: 10px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
}

.product-card img {
  width: 100px;
}
</style>
<!-- src/components/ProductList.vue -->
<template>
  <div class="product-list">
    <ProductCard v-for="product in products" :product="product" @add-to-cart="addProductToCart" />
  </div>
</template>

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

export default {
  components: {
    ProductCard
  },
  data() {
    return {
      products: [
        {
          id: 1,
          name: '产品1',
          price: '100元',
          image: 'https://example.com/image1.jpg'
        },
        {
          id: 2,
          name: '产品2',
          price: '200元',
          image: 'https://example.com/image2.jpg'
        }
      ]
    };
  },
  methods: {
    addProductToCart(product) {
      console.log('添加到购物车:', product);
    }
  }
};
</script>

<style scoped>
.product-list {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
</style>

项目调试与部署

调试:

npm run serve

部署:

npm run build

部署到服务器:

# 将生成的dist文件夹复制到服务器
scp -r dist user@server:/path/to/server

在服务器上运行Nginx或Apache等Web服务器,使项目可访问。

总结

通过以上教程,你已经掌握了 Vue3 的基础语法、组件化开发、路由与状态管理、组件通信等关键技术。你可以继续深入学习 Vue3 的高级特性和最佳实践,构建更加复杂的前端应用。推荐你在慕课网 (https://www.imooc.com/) 上学习更多 Vue3 课程,提升你的开发技能。

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