实现路由跳转页代码
import Vue from 'vue' import VueRouter from 'vue-router' import Home from '@/views/Home.vue' Vue.use(VueRouter) // 配置路由跳转项 const routes = [ { path:'/', name:'Home', component: Home }, { path:'/detail', name:'Detail', component: ()=> import('@/views/Detail.vue') }, { path:'/shopping', name:'Shopping', component: ()=> import('@/views/Shopping.vue') } ] const router = new VueRouter({ mode: 'history', base: process.env.BASE_URL, routes, }) export default router
app根组件代码
<template> <div id="app"> <div class="lists"> <!-- 切换页 --> <router-link to="/">首页</router-link> <router-link to="/shopping" >购物车<span v-show="total">{{ total }}</span></router-link > </div> <!-- 路由的出口,所有的数据都在这里显示 --> <router-view></router-view> </div> </template> <script> import { mapState } from "vuex"; export default { data() { return {}; }, computed: { ...mapState(["lists"]), total() { let num = 0; this.lists.map((item) => { num += item.num; }); return num; }, }, }; </script> <style lang="scss"> * { margin: 0; padding: 0; box-sizing: border-box; font-size: 16px; } #app { .lists { display: flex; justify-content: space-around; align-items: center; width: 100%; height: 0.5rem; border-top: 1px solid gainsboro; background-color: #fff; position: fixed; bottom: 0; left: 0; a { display: inline-block; width: 50%; height: 0.5rem; color: #000; text-align: center; line-height: 0.5rem; text-decoration: none; position: relative; span { display: inline-block; width: 0.2rem; height: 0.2rem; background-color: red; border-radius: 50%; color: #000; text-align: center; line-height: 0.2rem; position: absolute; top: 0.09rem; left: 30%; opacity: 0.8; } &.router-link-exact-active { color: red; } } } } </style>
效果列表页代码
<template> <div class="home-box"> <ul> <!-- 声明式导航,通过query把id值传递至详情页中 --> <!-- 给 list 属性执行for循环 --> <router-link :to="{ name: 'Detail', query: { id: item.id } }" class="home-row" v-for="item in list" :key="item.id" > <span class="left"> <!-- 图片 --> <img :src="item.imgsrc" /> </span> <span class="right"> <!-- 名称 --> <h3>{{ item.name }}</h3> <p> <!-- 价格 --> <b>¥{{ item.price }}</b> </p> </span> </router-link> </ul> </div> </template> <script> export default { data() { return { list: [], }; }, created() { // 进入页面时执行该方法 this.request(); }, methods: { // 请求 request() { // 请求到所以数据 this.$axios.get(`/api/meishi?star=1&num=15`).then((res) => { // 把请求到的数据赋值给list this.list = res.data; }); }, }, }; </script> <style lang="scss" scoped> .home-box { width: 100%; background-color: #f6f6f6; display: flex; justify-content: center; ul { margin: 0 0.2rem; .home-row { width: 3.55rem; height: 1rem; color: #000; margin-top: 0.1rem; text-decoration: none; padding: 0.1rem; display: inline-block; background-color: #fff; display: flex; justify-content: center; .left { img { width: 0.8rem; } } .right { padding-left: 0.2rem; h3 { width: 2.35rem; font-size: 0.18rem; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; } p { padding-top: 0.2rem; font-size: 0.14rem; text-align: center; display: -webkit-box; //对象作为弹性伸缩盒子模型显示 overflow: hidden; //溢出隐藏 -webkit-box-orient: vertical; //设置伸缩盒子对象的子元素的排列方式 -webkit-line-clamp: 2; //设置 块元素包含的文本行数 } } } } } </style>
详情页代码
<template> <div class="detail-box"> <span> <!-- 图片 --> <img :src="list.imgsrc" /> </span> <span> <!-- 名称 --> <h3>{{ list.name }}</h3> </span> <span> <!-- 介绍 --> <p>{{ list.contents.content.toString() }}</p> </span> <span> <p> <!-- 价格 --> <b>¥{{ list.price }}</b> </p> </span> <span> <!-- 点击跳转至购物车页面,并添加当前页面内容至购物车。同时执行两个点击事件--> <button @click="ShoppingClick(), isends()">加入购物车</button> <!-- 添加时的样式 --> <span :class="['js_animation_box', isEnd ? 'end' : '']"> <img :src="list.imgsrc" /> </span> </span> </div> </template> <script> // 引入vuex里的辅助函数 import { mapState } from "vuex"; export default { data() { return { list: [], isEnd: false, }; }, computed: { // 获取vuex里面的值 ...mapState(["lists"]), }, created() { // 进入时执行请求 this.request(); }, methods: { // 请求 request() { // 使用axios请求所需下标的参数 this.$axios.get(`/api/meishi?id=${this.$route.query.id}`).then((res) => { // 把请求到的值赋值给data里的list参数 this.list = res.data; }); }, // 加入购物车 ShoppingClick() { // 自定义添加的内容 let arr = { // 单选框 checked: true, // id值 id: this.lists.length + 1, // 图片链接 img: this.list.imgsrc, // name名称 name: this.list.name, // 单价 Price: this.list.price, // 数量 num: 1, }; // 触发vuex里的功能,把自定义的内容传递值vuex this.$store.commit("ShoppingClick", arr); // 编程式导航,跳转至购物车页面,等样式执行完毕后跳转 setTimeout(() => { this.$router.push({ name: "Shopping", }); }, 500); }, isends() { // 添加至购物车时的样式 this.isEnd = true; setTimeout(() => { this.isEnd = false; }, 500); }, }, }; </script> <style lang="scss" scoped> .detail-box { width: 100%; height: 100vh; background-color: #f6f6f6; span { display: inline-block; margin: 0 0.05rem; display: flex; justify-content: center; img { width: 3.65rem; height: 3.65rem; } h3 { font-size: 0.2rem; margin-top: 0.15rem; } p { margin-top: 0.15rem; } // 添加开始时的动画效果 .js_animation_box { display: inline-block; width: 0.2rem; height: 0.2rem; opacity: 0; transition: 0.5s all; position: fixed; bottom: 80%; left: 48%; img { width: 0.2rem; height: 0.2rem; } } // 添加结束后的动画效果 .js_animation_box.end { opacity: 1; position: fixed; bottom: 0.2rem; left: 60%; } } } </style>
购物车页面代码
<template> <div class="Shopping-box"> <div class="top">购物车</div> <ul class="content"> <!-- 循环 --> <li class="Shopping-row" v-for="item in lists" :key="item.id"> <!-- 单选框 --> <input type="checkbox" v-model="item.checked" @change="checkClick" /> <!-- 图片 --> <img :src="item.img" alt="" /> <div class="row-right"> <span class="name">{{ item.name }}</span> <!-- 单个价格 --> <p class="price">¥{{ item.Price * item.num }}</p> <span class="number"> <!-- 点击实现单个加一 --> <button @click="addClick(item)">+</button> <!-- 单个数量 --> <input type="text" v-model="item.num" /> <!-- 点击实现单个减一 --> <button @click="subtract(item)">-</button> </span> </div> </li> </ul> <div class="bottom"> <span> <input type="checkbox" v-model="alls" @change="AllClick" /> 全选 </span> <!-- 总价 --> <span>总计:¥{{ total }}</span> </div> </div> </template> <script> // 引入 vuex 的辅助函数 import { mapState } from "vuex"; export default { data() { return {}; }, computed: { // 获取vuex里面的值 ...mapState(["lists", "alls", "number"]), // 总计 total() { // 声明一个变量 num ,默认为0 let num = 0; // 给 lists 数组进行 map 循环 this.lists.map((item) => { // 判断是否选中 if (item.checked) { // num += 数量 乘以 单价 // +=代表:a+=2 a=a+2 num += item.num * item.Price; } }); // 把 num 值 return 给 total return num; }, }, created() { this.$store.commit("createds"); }, methods: { // 全选 AllClick() { // 触发vuex里的同步提交 this.$store.commit("AllClick"); }, // 单选 checkClick() { // 触发vuex里的同步提交 this.$store.commit("checkClick"); }, // 单个数量加 addClick(item) { // 触发vuex里的同步提交 this.$store.commit("addClick", item); }, // 单个数量减 subtract(item) { // 触发vuex里的同步提交,把 item 代表的值传递过去 this.$store.commit("subtract", item); }, }, }; </script> <style lang="scss" scoped> .Shopping-box { width: 100%; // height: 100vh; min-height: 100vh; background-color: #f6f6f6; .top { width: 100%; height: 0.5rem; text-align: center; line-height: 0.5rem; font-size: 0.2rem; background-color: #fff; position: fixed; top: 0; left: 0; } .content { width: 3.55rem; margin: 0 0.1rem; overflow: hidden; .Shopping-row:first-child { margin-top: 0.6rem; } .Shopping-row:last-child { margin-bottom: 0.6rem; } .Shopping-row { height: 1rem; margin-top: 0.12rem; padding: 0.1rem; background-color: #fff; display: flex; justify-content: center; img { width: 0.8rem; height: 0.8rem; margin: 0 0.1rem; } .row-right { .name { display: inline-block; width: 2.3rem; font-weight: 800; font-size: 0.18rem; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; } .price { color: red; font-size: 0.16rem; } .number { height: 0.2rem; display: inline-block; border: 1px solid #f6f6f6; border-radius: 50%; line-height: 0.3rem; button { width: 0.2rem; border-radius: 50%; border: none; text-align: center; } input { text-align: center; width: 0.3rem; border: none; } } } } } .bottom { width: 3.75rem; height: 0.5rem; padding: 0 0.1rem; display: flex; line-height: 0.5rem; font-size: 0.16rem; background-color: #fff; justify-content: space-between; position: fixed; bottom: 0; left: 0; } } </style>
vuex页面代码
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ // 页面刷新时调用 state: { // 如果有本地存储则显示否则显示空数组 lists:JSON.parse(localStorage.getItem('list')) || [], // 全选框 alls:false, }, getters: { }, mutations: { createds(state){ let arr = state.lists.filter((item) => { // 返回checked为true的值 return item.checked; }); // 判断lists里checked为true值得长度是否等于所以的长度,如果等于则全选框选中,否则不选中 arr.length == state.lists.length ? (state.alls = true) : (state.alls = false); }, // 加入购物车 ShoppingClick(state,data){ // 给 lists 进行 some 循环 let a = state.lists.some((item)=>{ // lists 里存在的和添加的name名相同则返回true,否则返回false return item.name == data.name }) // 判断出加入购物车时已经存在的下标 let num = 0 for(let i=0; i<state.lists.length; i++){ if(state.lists[i].name == data.name){ num = i } } // 判断 添加的内容购物车内是否已经存在 if(a){ // 已经存在则数量加一 state.lists[num].num = state.lists[num].num+1 // 并且进行选中 state.lists[num].checked = true // 保存至本地 localStorage.setItem('list',JSON.stringify(state.lists)) }else{ // 如果不存在则添加 state.lists.push(data) // 保存至本地 localStorage.setItem('list',JSON.stringify(state.lists)) } this.commit('createds') }, // 全选 AllClick(state){ // 把全选的值改为相反 state.alls = !state.alls // 循环lists state.lists.some((item)=>{ // lists里input框的值,等于全选的值 item.checked = state.alls }) // 保存至本地 localStorage.setItem('list',JSON.stringify(state.lists)) }, // 单选 checkClick(state){ // 给lists进行过滤 let arr = state.lists.filter((item) => { // 返回checked为true的值 return item.checked; }); // 判断lists里checked为true值得长度是否等于所以的长度,如果等于则全选框选中,否则不选中 arr.length == state.lists.length ? (state.alls = true) : (state.alls = false); // 保存至本地 localStorage.setItem('list',JSON.stringify(state.lists)) }, // 单个价格加 addClick(state,item){ // 传递过来的当前列表里的num加1 item.num = item.num+1 // console.log(state.number); // 保存至本地 localStorage.setItem('list',JSON.stringify(state.lists)) }, // 单个价格减 subtract(state,item){ // 判断数量是否大于1 if(item.num>1){ // 大于1则执行,传递过来的当前列表里的num减1 item.num = item.num-1 // 保存至本地 localStorage.setItem('list',JSON.stringify(state.lists)) } } }, actions: { }, modules: { } })
以上就是列表跳转至详情并加入购物车的代码,不懂得也可以在评论区里问我,以后会持续添加一些新的功能,敬请关注。