Vue3 学习教程,从入门到精通,Vue CLI 语法知识点及使用方法详解(38)

发布于:2025-08-17 ⋅ 阅读:(12) ⋅ 点赞:(0)

Vue CLI 语法知识点及使用方法详解

本文将详细介绍 Vue CLI 的各个核心概念、语法知识点及其使用方法。每个知识点都配有具体的案例代码,并包含详细注释,帮助您更好地理解和应用 Vue CLI 进行项目开发。


1. Vue CLI 简介

Vue CLI 是一个用于快速搭建 Vue.js 项目的标准工具。它提供了一系列功能强大的工具和插件,帮助开发者高效地管理项目配置、依赖关系以及开发流程。

主要功能:

  • 项目脚手架:快速创建 Vue 项目结构。
  • 插件系统:集成各种开发工具和插件,如 Babel、ESLint、Vue Router、Vuex 等。
  • 图形化界面:提供 GUI 工具,方便不熟悉命令行的开发者使用。
  • 可配置性:支持自定义配置,适应不同项目的需求。

2. Vue CLI 的安装

2.1 全局安装 Vue CLI

首先,确保您的系统已安装 Node.js(建议版本 >= 14)和 npmYarn

使用以下命令全局安装 Vue CLI:

npm install -g @vue/cli

或使用 Yarn:

yarn global add @vue/cli

2.2 验证安装

安装完成后,可以通过以下命令验证 Vue CLI 是否安装成功:

vue --version

如果安装成功,会显示 Vue CLI 的版本号,例如:

@vue/cli 5.0.8

3. 创建项目

使用 Vue CLI 创建项目有两种主要方式:通过命令行工具 vue create 和通过图形化界面工具 vue ui

3.1 使用 vue create 命令

3.1.1 基本用法

在终端中运行以下命令来创建一个新的 Vue 项目:

vue create my-project
3.1.2 选择预设

执行上述命令后,Vue CLI 会提示您选择预设:

? Please pick a preset:
  Default ([Vue 3] babel, eslint)
  Default ([Vue 2] babel, eslint)
❯ Manually select features

选择 Manually select features 可以自定义项目配置。

3.1.3 自定义配置

选择 Manually select features 后,您可以选择需要的功能:

? Check the features needed for your project:
 ◉ Choose Vue version
 ◉ Babel
 ◉ TypeScript
 ◉ Router
 ◉ Vuex
 ◉ CSS Pre-processors
 ◉ Linter / Formatter
 ◉ Unit Testing
 ◉ E2E Testing

根据项目需求选择相应的功能。

3.1.4 配置示例

以下是一个典型的配置示例:

? Please pick a preset: Manually select features
? Check the features needed for your project: Choose Vue version, Babel, Router, Vuex, CSS Pre-processors, Linter
? Choose a version of Vue.js that you want to start the project with 3.x
? Use history mode for router? (Requires proper server setup for index fallback in production) Yes
? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): Sass/SCSS (with dart-sass)
? Pick a linter / formatter config: Prettier
? Pick additional lint features: Lint on save
? Where do you prefer placing config for Babel, ESLint, etc.? In dedicated config files

3.2 使用图形界面工具 vue ui

Vue CLI 还提供了图形化界面工具,可以通过以下命令启动:

vue ui

这将打开一个浏览器窗口,您可以在其中通过图形界面创建和管理 Vue 项目。


4. 项目结构

创建项目后,Vue CLI 会生成以下典型的项目结构:

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

4.1 主要文件说明

  • public/index.html:应用的入口 HTML 文件。
  • src/main.js:应用的入口 JavaScript 文件,负责创建 Vue 实例并挂载根组件。
  • src/App.vue:根组件,包含了应用的全局结构和样式。
  • src/components/:存放单文件组件的目录。
  • src/views/:存放页面级组件的目录,通常与 Vue Router 配合使用。
  • src/router/index.js:Vue Router 的配置文件,定义应用的路由。

5. 单文件组件 (Single File Components)

Vue 的单文件组件(.vue 文件)将模板、脚本和样式封装在一个文件中,提供了模块化和可维护性。

5.1 单文件组件结构

一个典型的 .vue 文件结构如下:

<template>
  <div>
    <!-- HTML 模板 -->
  </div>
</template>

<script>
export default {
  // 组件逻辑
  data() {
    return {
      // 数据属性
    };
  },
  methods: {
    // 方法
  }
};
</script>

<style scoped>
/* 样式 */
</style>

5.2 案例:编写一个简单的计数器组件

5.2.1 Counter.vue
<template>
  <div class="counter">
    <h2>计数器</h2>
    <p>当前计数:{{ count }}</p>
    <button @click="increment">增加</button>
    <button @click="decrement">减少</button>
  </div>
</template>

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

<style scoped>
.counter {
  border: 1px solid #ccc;
  padding: 20px;
  width: 200px;
  text-align: center;
}
button {
  margin: 5px;
}
</style>
5.2.2 使用计数器组件

App.vue 中引入并使用 Counter 组件:

<template>
  <div id="app">
    <h1>欢迎使用 Vue CLI</h1>
    <Counter />
  </div>
</template>

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

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

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  text-align: center;
  margin-top: 60px;
}
</style>

6. 实现选项卡切换图片效果

6.1 Tabs.vue

<template>
  <div class="tabs">
    <ul class="tab-header">
      <li
        v-for="(tab, index) in tabs"
        :key="index"
        :class="{ active: activeTab === index }"
        @click="activeTab = index"
      >
        {{ tab.title }}
      </li>
    </ul>
    <div class="tab-content">
      <img :src="currentImage" alt="Tab Image" />
    </div>
  </div>
</template>

<script>
export default {
  name: 'Tabs',
  data() {
    return {
      activeTab: 0,
      tabs: [
        { title: '图片1', image: 'https://via.placeholder.com/300x200?text=图片1' },
        { title: '图片2', image: 'https://via.placeholder.com/300x200?text=图片2' },
        { title: '图片3', image: 'https://via.placeholder.com/300x200?text=图片3' }
      ]
    };
  },
  computed: {
    currentImage() {
      return this.tabs[this.activeTab].image;
    }
  }
};
</script>

<style scoped>
.tabs {
  width: 300px;
  margin: 0 auto;
}
.tab-header {
  list-style: none;
  padding: 0;
  display: flex;
  border-bottom: 2px solid #ccc;
}
.tab-header li {
  margin: 0 10px;
  padding: 10px;
  cursor: pointer;
  border-bottom: 2px solid transparent;
}
.tab-header li.active {
  border-bottom: 2px solid #007bff;
  color: #007bff;
}
.tab-content {
  padding: 20px;
  text-align: center;
}
</style>

6.2 使用选项卡组件

App.vue 中引入并使用 Tabs 组件:

<template>
  <div id="app">
    <h1>选项卡切换图片效果</h1>
    <Tabs />
  </div>
</template>

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

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

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  text-align: center;
  margin-top: 60px;
}
</style>

7. 综合性案例

7.1 电商产品展示应用

7.1.1 项目结构
ecommerce-app/
├── node_modules/
├── public/
│   ├── favicon.ico
│   └── index.html
├── src/
│   ├── assets/
│   ├── components/
│   │   ├── ProductList.vue
│   │   ├── ProductItem.vue
│   │   └── Cart.vue
│   ├── views/
│   │   ├── Home.vue
│   │   └── ProductDetail.vue
│   ├── App.vue
│   ├── main.js
│   └── router/
│       └── index.js
├── .gitignore
├── babel.config.js
├── package.json
├── package-lock.json
├── README.md
└── vue.config.js
7.1.2 ProductItem.vue
<template>
  <div class="product-item">
    <img :src="product.image" :alt="product.name" />
    <h3>{{ product.name }}</h3>
    <p>{{ product.description }}</p>
    <p>价格:{{ product.price }} 元</p>
    <button @click="addToCart">加入购物车</button>
  </div>
</template>

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

<style scoped>
.product-item {
  border: 1px solid #ccc;
  padding: 10px;
  width: 200px;
  margin: 10px;
  text-align: center;
}
.product-item img {
  width: 100%;
  height: auto;
}
button {
  background-color: #007bff;
  color: white;
  border: none;
  padding: 10px;
  cursor: pointer;
}
button:hover {
  background-color: #0056b3;
}
</style>
7.1.3 ProductList.vue
<template>
  <div class="product-list">
    <ProductItem
      v-for="product in products"
      :key="product.id"
      :product="product"
      @add-to-cart="handleAddToCart"
    />
  </div>
</template>

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

export default {
  name: 'ProductList',
  components: {
    ProductItem
  },
  props: {
    products: {
      type: Array,
      required: true
    }
  },
  methods: {
    handleAddToCart(product) {
      this.$emit('add-to-cart', product);
    }
  }
};
</script>

<style scoped>
.product-list {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
}
</style>
7.1.4 Cart.vue
<template>
  <div class="cart">
    <h2>购物车</h2>
    <ul>
      <li v-for="item in cartItems" :key="item.id">
        {{ item.name }} - {{ item.price }} 元
      </li>
    </ul>
    <p>总价:{{ totalPrice }} 元</p>
  </div>
</template>

<script>
export default {
  name: 'Cart',
  props: {
    cartItems: {
      type: Array,
      required: true
    }
  },
  computed: {
    totalPrice() {
      return this.cartItems.reduce((sum, item) => sum + item.price, 0);
    }
  }
};
</script>

<style scoped>
.cart {
  border: 1px solid #ccc;
  padding: 20px;
  width: 300px;
  margin: 20px auto;
}
.cart ul {
  list-style: none;
  padding: 0;
}
.cart li {
  margin: 5px 0;
}
</style>
7.1.5 Home.vue
<template>
  <div class="home">
    <h1>产品列表</h1>
    <ProductList :products="products" @add-to-cart="addToCart" />
    <Cart :cartItems="cart" />
  </div>
</template>

<script>
import ProductList from '../components/ProductList.vue';
import Cart from '../components/Cart.vue';

export default {
  name: 'Home',
  components: {
    ProductList,
    Cart
  },
  data() {
    return {
      products: [
        { id: 1, name: '产品1', description: '描述1', price: 100, image: 'https://via.placeholder.com/200x150?text=产品1' },
        { id: 2, name: '产品2', description: '描述2', price: 200, image: 'https://via.placeholder.com/200x150?text=产品2' },
        { id: 3, name: '产品3', description: '描述3', price: 300, image: 'https://via.placeholder.com/200x150?text=产品3' }
      ],
      cart: []
    };
  },
  methods: {
    addToCart(product) {
      this.cart.push(product);
    }
  }
};
</script>

<style scoped>
.home {
  text-align: center;
}
</style>
7.1.6 main.js
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';

createApp(App)
  .use(router)
  .mount('#app');
7.1.7 router/index.js
import { createRouter, createWebHistory } from 'vue-router';
import Home from '../views/Home.vue';

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/product/:id',
    name: 'ProductDetail',
    component: () => import('../views/ProductDetail.vue')
  }
];

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

export default router;
7.1.8 App.vue
<template>
  <div id="app">
    <nav>
      <router-link to="/">首页</router-link>
      <router-link to="/cart">购物车</router-link>
    </nav>
    <router-view />
  </div>
</template>

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

<style>
nav {
  background-color: #007bff;
  padding: 10px;
}
nav a {
  color: white;
  margin: 0 10px;
  text-decoration: none;
}
nav a:hover {
  text-decoration: underline;
}
</style>

总结

本文详细介绍了 Vue CLI 的核心概念、安装步骤、项目结构、单文件组件的编写方法,以及如何实现选项卡切换图片效果,并通过一个电商产品展示应用的综合性案例展示了 Vue CLI 在实际项目中的应用。通过这些内容,您应该能够熟练地使用 Vue CLI 进行 Vue.js 项目的开发和管理。


网站公告

今日签到

点亮在社区的每一天
去签到