Vue3 学习教程,从入门到精通,基于 Vue 3 + Element Plus + ECharts + JavaScript 开发图书销售网站(42)

基于 Vue 3 + Element Plus + ECharts + JavaScript 开发图书销售网站

本文将基于使用 Vue 3Element PlusEChartsJavaScript 开发图书销售网站的项目,详细介绍相关的语法知识点及其使用方法。每个知识点都将通过具体的案例代码进行说明,并包含详细的注释。此外,还将提供一些综合性的案例,帮助您更好地理解和应用这些技术。

目录

  1. Vue 3 基础语法
  2. Element Plus 组件使用
  3. ECharts 数据可视化
  4. Vue Router 路由管理
  5. Vuex 状态管理
  6. 综合案例:导航模块
  7. 综合案例:登录模块
  8. 综合案例:图书展示模块
  9. 综合案例:图书详情模块
  10. 综合案例:图书搜索模块
  11. 综合案例:购物车模块

1. Vue 3 基础语法

知识点

  • 创建 Vue 应用:使用 createApp 创建 Vue 实例。
  • 组件基础:定义和使用组件。
  • 数据绑定:使用 v-model 进行双向数据绑定。
  • 指令:使用 v-if, v-for, v-bind, v-on 等指令。

案例代码

<!-- App.vue -->
<template>
  <div id="app">
    <h1>{{ message }}</h1>
    <input v-model="message" placeholder="编辑消息" />
    <ul>
      <li v-for="(item, index) in items" :key="index">{{ item }}</li>
    </ul>
    <button @click="addItem">添加项</button>
  </div>
</template>

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

export default {
  name: 'App',
  setup() {
    const message = ref('欢迎来到图书销售网站');
    const items = ref(['图书1', '图书2', '图书3']);

    const addItem = () => {
      items.value.push(`图书${items.value.length + 1}`);
    };

    return {
      message,
      items,
      addItem,
    };
  },
};
</script>

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

说明

  • 使用 ref 创建响应式数据。
  • 使用 v-model 实现输入框的双向数据绑定。
  • 使用 v-for 指令渲染列表。
  • 使用 @click 指令绑定点击事件。

2. Element Plus 组件使用

知识点

  • 引入 Element Plus:在项目中安装并引入 Element Plus。
  • 使用组件:使用 Element Plus 提供的各种 UI 组件,如按钮、表格、表单等。

案例代码

<!-- Login.vue -->
<template>
  <el-form :model="loginForm" @submit.prevent="handleLogin" class="login-form">
    <el-form-item label="用户名">
      <el-input v-model="loginForm.username" placeholder="请输入用户名"></el-input>
    </el-form-item>
    <el-form-item label="密码">
      <el-input v-model="loginForm.password" type="password" placeholder="请输入密码"></el-input>
    </el-form-item>
    <el-form-item>
      <el-button type="primary" native-type="submit">登录</el-button>
    </el-form-item>
  </el-form>
</template>

<script>
import { ref } from 'vue';
import { ElMessage } from 'element-plus';

export default {
  name: 'Login',
  setup() {
    const loginForm = ref({
      username: '',
      password: '',
    });

    const handleLogin = () => {
      if (loginForm.value.username === 'admin' && loginForm.value.password === 'password') {
        ElMessage({
          message: '登录成功',
          type: 'su***ess',
        });
      } else {
        ElMessage({
          message: '用户名或密码错误',
          type: 'error',
        });
      }
    };

    return {
      loginForm,
      handleLogin,
    };
  },
};
</script>

<style>
.login-form {
  width: 300px;
  margin: 0 auto;
}
</style>

说明

  • 使用 Element Plus 的 el-form, el-form-item, el-input, el-button 等组件构建登录表单。
  • 使用 ElMessage 组件显示提示信息。
  • 使用 v-model 实现表单数据的双向绑定。

3. ECharts 数据可视化

知识点

  • 引入 ECharts:在项目中安装并引入 ECharts。
  • 创建图表:使用 ECharts 提供的 API 创建各种类型的图表。
  • 数据绑定:将 Vue 的数据与 ECharts 图表进行绑定。

案例代码

<!-- SalesChart.vue -->
<template>
  <div ref="chart" class="chart"></div>
</template>

<script>
import { ref, onMounted } from 'vue';
import * as echarts from 'echarts';

export default {
  name: 'SalesChart',
  setup() {
    const chart = ref(null);

    const chartOptions = {
      title: {
        text: '图书销售统计',
      },
      tooltip: {},
      xAxis: {
        data: ['一月', '二月', '三月', '四月', '五月', '六月'],
      },
      yAxis: {},
      series: [
        {
          name: '销量',
          type: 'bar',
          data: [500, 700, 600, 800, 750, 900],
        },
      ],
    };

    onMounted(() => {
      const myChart = echarts.init(chart.value);
      myChart.setOption(chartOptions);
    });

    return {
      chart,
    };
  },
};
</script>

<style>
.chart {
  width: 600px;
  height: 400px;
  margin: 0 auto;
}
</style>

说明

  • 使用 ref 创建图表容器的引用。
  • 使用 onMounted 生命周期钩子在组件挂载后初始化 ECharts 实例。
  • 使用 setOption 方法设置图表的配置项和数据。

4. Vue Router 路由管理

知识点

  • 安装 Vue Router:在项目中安装并配置 Vue Router。
  • 路由配置:定义不同的路由路径和组件。
  • 导航链接:使用 <router-link> 进行导航。

案例代码

// router/index.js
import { createRouter, createWebHistory } from 'vue-router';
import Home from '../views/Home.vue';
import Books from '../views/Books.vue';
import BookDetail from '../views/BookDetail.vue';
import Login from '../views/Login.vue';
import Cart from '../views/Cart.vue';

const routes = [
    {
        path: '/',
        name: 'Home',
        ***ponent: Home,
    },
    {
        path: '/books',
        name: 'Books',
        ***ponent: Books,
    },
    {
        path: '/books/:id',
        name: 'BookDetail',
        ***ponent: BookDetail,
        props: true,
    },
    {
        path: '/login',
        name: 'Login',
        ***ponent: Login,
    },
    {
        path: '/cart',
        name: 'Cart',
        ***ponent: Cart,
    },
];

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

export default router;
// main.js
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
import ElementPlus from 'element-plus';
import 'element-plus/dist/index.css';

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

说明

  • 使用 createRoutercreateWebHistory 创建路由实例。
  • 定义不同的路由路径和对应的组件。
  • main.js 中使用 app.use(router) 注册路由。

5. Vuex 状态管理

知识点

  • 安装 Vuex:在项目中安装并配置 Vuex。
  • 状态管理:定义和管理全局状态。
  • 获取和提交状态:使用 mapState, mapGetters, mapActions 等辅助函数。

案例代码

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

export default createStore({
    state: {
        cart: [],
    },
    mutations: {
        addToCart(state, book) {
            state.cart.push(book);
        },
        removeFromCart(state, index) {
            state.cart.splice(index, 1);
        },
    },
    actions: {
        addToCart({ ***mit }, book) {
            ***mit('addToCart', book);
        },
        removeFromCart({ ***mit }, index) {
            ***mit('removeFromCart', index);
        },
    },
    getters: {
        cartItems: (state) => state.cart,
        cartCount: (state) => state.cart.length,
    },
});
// main.js
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';
import ElementPlus from 'element-plus';
import 'element-plus/dist/index.css';

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

说明

  • 使用 createStore 创建 Vuex store。
  • 定义 state, mutations, actions, getters 来管理状态。
  • main.js 中使用 app.use(store) 注册 Vuex。

6. 综合案例:导航模块

案例描述

实现一个导航模块,包含首页、图书、购物车、登录等导航链接。

案例代码

<!-- NavBar.vue -->
<template>
    <el-menu :default-active="activeIndex" class="el-menu-demo" mode="horizontal" @select="handleSelect">
        <el-menu-item index="1">首页</el-menu-item>
        <el-menu-item index="2">图书</el-menu-item>
        <el-menu-item index="3">购物车</el-menu-item>
        <el-menu-item index="4">登录</el-menu-item>
    </el-menu>
</template>

<script>
import { ref } from 'vue';
import { useRouter, useRoute } from 'vue-router';

export default {
    name: 'NavBar',
    setup() {
        const activeIndex = ref('1');
        const router = useRouter();

        const handleSelect = (key, keyPath) => {
            switch (key) {
                case '1':
                    router.push('/');
                    break;
                case '2':
                    router.push('/books');
                    break;
                case '3':
                    router.push('/cart');
                    break;
                case '4':
                    router.push('/login');
                    break;
                default:
                    break;
            }
        };

        return {
            activeIndex,
            handleSelect,
        };
    },
};
</script>

<style>
.el-menu-demo {
    justify-content: center;
}
</style>

说明

  • 使用 Element Plus 的 el-menu 组件创建导航栏。
  • 使用 handleSelect 方法处理导航链接点击事件。
  • 使用 Vue Router 的 useRouter 钩子进行路由跳转。

7. 综合案例:登录模块

案例描述

实现一个登录模块,包含用户名和密码输入,以及登录验证。

案例代码

<!-- Login.vue -->
<template>
    <el-form :model="loginForm" @submit.prevent="handleLogin" class="login-form">
        <el-form-item label="用户名">
            <el-input v-model="loginForm.username" placeholder="请输入用户名"></el-input>
        </el-form-item>
        <el-form-item label="密码">
            <el-input v-model="loginForm.password" type="password" placeholder="请输入密码"></el-input>
        </el-form-item>
        <el-form-item>
            <el-button type="primary" native-type="submit">登录</el-button>
        </el-form-item>
    </el-form>
</template>

<script>
import { ref } from 'vue';
import { ElMessage } from 'element-plus';
import { useRouter } from 'vue-router';
import { useStore } from 'vuex';

export default {
    name: 'Login',
    setup() {
        const loginForm = ref({
            username: '',
            password: '',
        });
        const router = useRouter();
        const store = useStore();

        const handleLogin = () => {
            if (loginForm.value.username === 'admin' && loginForm.value.password === 'password') {
                ElMessage({
                    message: '登录成功',
                    type: 'su***ess',
                });
                store.dispatch('addToCart', { title: '示例图书', price: 39.99 });
                router.push('/');
            } else {
                ElMessage({
                    message: '用户名或密码错误',
                    type: 'error',
                });
            }
        };

        return {
            loginForm,
            handleLogin,
        };
    },
};
</script>

<style>
.login-form {
    width: 300px;
    margin: 0 auto;
}
</style>

说明

  • 使用 Vuex 的 useStore 钩子进行状态管理。
  • 使用 ElMessage 组件显示登录结果。
  • 使用 Vue Router 的 useRouter 钩子进行路由跳转。

8. 综合案例:图书展示模块

案例描述

实现一个图书展示模块,展示图书列表,并提供分页功能。

案例代码

<!-- Books.vue -->
<template>
    <div id="books">
        <h1>图书列表</h1>
        <el-table :data="books" style="width: 100%">
            <el-table-column prop="title" label="书名" width="180"></el-table-column>
            <el-table-column prop="author" label="作者" width="180"></el-table-column>
            <el-table-column prop="price" label="价格" width="100"></el-table-column>
            <el-table-column label="操作" width="100">
                <template #default="scope">
                    <el-button type="primary" @click="viewDetail(scope.row)">查看详情</el-button>
                </template>
            </el-table-column>
        </el-table>
        <el-pagination
            @current-change="handleCurrentChange"
            :current-page="currentPage"
            :page-size="pageSize"
            layout="total, prev, pager, next, jumper"
            :total="totalBooks">
        </el-pagination>
    </div>
</template>

<script>
import { ref, onMounted } from 'vue';
import axios from 'axios';
import { useRouter } from 'vue-router';

export default {
    name: 'Books',
    setup() {
        const books = ref([]);
        const currentPage = ref(1);
        const pageSize = 10;
        const totalBooks = ref(0);
        const router = useRouter();

        const fetchBooks = () => {
            axios.get('/api/books', {
                params: {
                    page: currentPage.value,
                    size: pageSize,
                },
            }).then(response => {
                books.value = response.data.books;
                totalBooks.value = response.data.total;
            }).catch(error => {
                console.error('获取图书列表失败', error);
            });
        };

        const handleCurrentChange = (page) => {
            currentPage.value = page;
            fetchBooks();
        };

        const viewDetail = (book) => {
            router.push(`/books/${book.id}`);
        };

        onMounted(() => {
            fetchBooks();
        });

        return {
            books,
            currentPage,
            pageSize,
            totalBooks,
            handleCurrentChange,
            viewDetail,
        };
    },
};
</script>

<style>
#books {
    padding: 20px;
}
</style>

说明

  • 使用 Element Plus 的 el-table 组件展示图书列表。
  • 使用 el-pagination 组件实现分页功能。
  • 使用 axios 进行数据请求。
  • 使用 Vue Router 的 useRouter 钩子进行路由跳转。

9. 综合案例:图书详情模块

案例描述

实现一个图书详情模块,展示图书的详细信息。

案例代码

<!-- BookDetail.vue -->
<template>
    <div id="book-detail">
        <h1>{{ book.title }}</h1>
        <p>作者: {{ book.author }}</p>
        <p>价格: ¥{{ book.price }}</p>
        <p>{{ book.description }}</p>
        <el-button type="primary" @click="addToCart">加入购物车</el-button>
    </div>
</template>

<script>
import { ref, onMounted } from 'vue';
import axios from 'axios';
import { useRouter, useRoute } from 'vue-router';
import { useStore } from 'vuex';

export default {
    name: 'BookDetail',
    setup() {
        const book = ref({});
        const router = useRouter();
        const route = useRoute();
        const store = useStore();

        const fetchBookDetail = () => {
            axios.get(`/api/books/${route.params.id}`)
                .then(response => {
                    book.value = response.data;
                })
                .catch(error => {
                    console.error('获取图书详情失败', error);
                });
        };

        const addToCart = () => {
            store.dispatch('addToCart', book.value);
            ElMessage({
                message: '已加入购物车',
                type: 'su***ess',
            });
        };

        onMounted(() => {
            fetchBookDetail();
        });

        return {
            book,
            addToCart,
        };
    },
};
</script>

<style>
#book-detail {
    padding: 20px;
}
</style>

说明

  • 使用 axios 获取图书详情。
  • 使用 Vuex 的 useStore 钩子进行状态管理。
  • 使用 ElMessage 组件显示提示信息。
  • 使用 Vue Router 的 useRoute 钩子获取路由参数。

10. 综合案例:图书搜索模块

案例描述

实现一个图书搜索模块,允许用户搜索图书。

案例代码

<!-- SearchBar.vue -->
<template>
    <el-input
        v-model="query"
        placeholder="搜索图书"
        @input="handleSearch"
        suffix-icon="el-icon-search">
    </el-input>
</template>

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

export default {
    name: 'SearchBar',
    setup() {
        const query = ref('');
        const debounceTimer = ref(null);

        const handleSearch = () => {
            if (debounceTimer.value) {
                clearTimeout(debounceTimer.value);
            }
            debounceTimer.value = setTimeout(() => {
                if (query.value.trim() !== '') {
                    axios.get('/api/search', {
                        params: {
                            q: query.value,
                        },
                    }).then(response => {
                        console.log('搜索结果', response.data);
                        // 处理搜索结果
                    }).catch(error => {
                        console.error('搜索失败', error);
                    });
                }
            }, 500);
        };

        return {
            query,
            handleSearch,
        };
    },
};
</script>

<style>
.el-input {
    width: 300px;
    margin: 20px auto;
}
</style>

说明

  • 使用 el-input 组件创建搜索输入框。
  • 使用 debounce 方法防止频繁请求。
  • 使用 axios 进行搜索请求。

11. 综合案例:购物车模块

案例描述

实现一个购物车模块,包含添加商品到购物车,查看购物车内容,删除商品。

案例代码

<!-- Cart.vue -->
<template>
    <div id="cart">
        <h1>购物车</h1>
        <el-table :data="cartItems" style="width: 100%">
            <el-table-column prop="title" label="书名" width="180"></el-table-column>
            <el-table-column prop="price" label="价格" width="100"></el-table-column>
            <el-table-column label="操作" width="100">
                <template #default="scope">
                    <el-button type="danger" @click="removeItem(scope.$index)">删除</el-button>
                </template>
            </el-table-column>
        </el-table>
        <p>总价: ¥{{ totalPrice }}</p>
    </div>
</template>

<script>
import { ref, ***puted } from 'vue';
import { useStore } from 'vuex';

export default {
    name: 'Cart',
    setup() {
        const store = useStore();
        const cartItems = ***puted(() => store.getters.cartItems);
        const totalPrice = ***puted(() => {
            return cartItems.value.reduce((total, item) => total + item.price, 0);
        });

        const removeItem = (index) => {
            store.dispatch('removeFromCart', index);
        };

        return {
            cartItems,
            totalPrice,
            removeItem,
        };
    },
};
</script>

<style>
#cart {
    padding: 20px;
}
</style>

说明

  • 使用 Vuex 的 useStore 钩子获取购物车状态。
  • 使用 ***puted 计算总价。
  • 使用 el-table 组件展示购物车内容。
  • 使用 el-button 组件实现删除功能。

总结

本文详细介绍了基于 Vue 3、Element Plus、ECharts 和 JavaScript 开发图书销售网站所涉及的语法知识点及其使用方法。通过这些知识点的综合应用,您将能够构建一个现代化的、功能丰富的图书销售网站。希望这些内容对您的项目开发有所帮助!

转载请说明出处内容投诉
CSS教程网 » Vue3 学习教程,从入门到精通,基于 Vue 3 + Element Plus + ECharts + JavaScript 开发图书销售网站(42)

发表评论

欢迎 访客 发表评论

一个令你着迷的主题!

查看演示 官网购买