Vue3 学习教程,从入门到精通,基于 Vue 3 + Element Plus + ECharts + JavaScript 开发图书销售网站(42)
基于 Vue 3 + Element Plus + ECharts + JavaScript 开发图书销售网站
本文将基于使用 Vue 3、Element Plus、ECharts 和 JavaScript 开发图书销售网站的项目,详细介绍相关的语法知识点及其使用方法。每个知识点都将通过具体的案例代码进行说明,并包含详细的注释。此外,还将提供一些综合性的案例,帮助您更好地理解和应用这些技术。
目录
- Vue 3 基础语法
- Element Plus 组件使用
- ECharts 数据可视化
- Vue Router 路由管理
- Vuex 状态管理
- 综合案例:导航模块
- 综合案例:登录模块
- 综合案例:图书展示模块
- 综合案例:图书详情模块
- 综合案例:图书搜索模块
- 综合案例:购物车模块
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: 'success',});} 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',component: Home,},{path: '/books',name: 'Books',component: Books,},{path: '/books/:id',name: 'BookDetail',component: BookDetail,props: true,},{path: '/login',name: 'Login',component: Login,},{path: '/cart',name: 'Cart',component: 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');
说明
- 使用
createRouter
和createWebHistory
创建路由实例。 - 定义不同的路由路径和对应的组件。
- 在
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({ commit }, book) {commit('addToCart', book);},removeFromCart({ commit }, index) {commit('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: 'success',});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: 'success',});};onMounted(() => {fetchBookDetail();});return {book,addToCart,};},
};
</script><style>
#book-detail {padding: 20px;
}
</style>
说明
- 使用
axios
获取图书详情。 - 使用 Vuex 的
useStore
钩子进行状态管理。 - 使用
ElMessage
组件显示提示信息。 - 使用 Vue Router 的
useRoute
钩子获取路由参数。
10. 综合案例:图书搜索模块
案例描述
实现一个图书搜索模块,允许用户搜索图书。
案例代码
<!-- SearchBar.vue -->
<template><el-inputv-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, computed } from 'vue';
import { useStore } from 'vuex';export default {name: 'Cart',setup() {const store = useStore();const cartItems = computed(() => store.getters.cartItems);const totalPrice = computed(() => {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
钩子获取购物车状态。 - 使用
computed
计算总价。 - 使用
el-table
组件展示购物车内容。 - 使用
el-button
组件实现删除功能。
总结
本文详细介绍了基于 Vue 3、Element Plus、ECharts 和 JavaScript 开发图书销售网站所涉及的语法知识点及其使用方法。通过这些知识点的综合应用,您将能够构建一个现代化的、功能丰富的图书销售网站。希望这些内容对您的项目开发有所帮助!