一个vue2.0+vuex+vue-router搭建的单页潮流购物网站

news/2024/5/2 19:01:07/文章来源:https://blog.csdn.net/weixin_34082854/article/details/89088152

项目demo地址
github源码地址

首页

觉得不错,给我的github源码点个赞吧QAQ

图片描述

前言

这篇文章是总结自己写项目时的思路,遇到的问题,和学到的东西,本文只截取一部分来讲,源码已奉上,觉得项目还行的点个赞吧,谢谢

一、搭建环境

  • 安装vue-cli

npm install -g vue-cli

  • 创建webpack项目

vue init webpack vogue
cd vogue

  • 安装依赖

npm install

  • 安装vue-router

npm install vue-router --save-dev

  • 安装vuex

npm install vuex --save-dev

  • 运行

npm run dev

二、目录结构

图片描述

  • components中是所有页面组件

  • store中的index.js存放了vuex状态管理的东西,此处本应分成actions.js,mutations.js,getters.js的,可是我试了很多次没成功,还是将他们放在一个文件中,显得有点冗余了,这点失误了,会找原因的

  • static中存放了图片,图片是压缩了的,网站是https://tinypng.com/,还存放了字体,和一点css,css放在这里有一个原因就是,我想给某个元素设置background时,将style写在static里才行。

  • dist文件是后来npm run build后生成的,生成的dist中的index.html中的link都是没有加引号的,我自己加上才可以直接运行

三、项目开发

开发过程中,页面是一个一个写的,不过还是要先确定路由,路由嵌套

main.js

先说说路由吧,写在了main.js中,直接上图
图片描述

文章开头有首页,home的路径就是‘/home’,这里路由嵌套,用‘:id’来识别,Brands.vue组件在后文中会解释如何得到id,home页的八个导航,分别导向‘/home’,‘/news’,'/collections','/shop','/home/clot','/home/madness','/home/bape','/home/assc',购物车导向'/cart','login|register'导向‘/login’,'/newsarticle'是在news组件中导向的,‘/shoppingitem’是shop组件中导向的

App.vue

图片描述
图片描述
v-for列表渲染的数据如left_navs和contents均来自state
对象迭代

<div v-for="(value, key, index) in object">{{ index }}. {{ key }} : {{ value }}
</div>

如何得到state中的数据

 import {mapGetters} from 'vuex'computed:{...mapGetters({show:'getShow',items:'getFootItems',cart:'getCart',brands:'getBrands',left_navs:'getLeft_nav'})},

在布局上,我的思路是:首页三行,上下定高,中间自适应高度,于是在app.vue的created()中设置事件委托

    var self=this;window.onload=()=>{this.$store.dispatch('change_hw',{h:document.documentElement.clientHeight||document.body.clientHeight,w:document.documentElement.clientWidth||document.body.clientWidth})}window.onresize=()=>{if(self.timer){clearTimeout(self.timer)}self.timer=setTimeout(function(){self.$store.dispatch('change_hw',{h:document.documentElement.clientHeight||document.body.clientHeight,w:document.documentElement.clientWidth||document.body.clientWidth})},100)}window.onscroll=()=>{var scrollTop = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop;if(scrollTop>10){this.scroll=true;}else{this.scroll=false;}}}

然后中间那行用的三栏布局,左右定宽中间自适应宽度,再设置一个min-height不免得将中间的轮播弄来没有了,具体见css

细节:其中用data中的scroll,用来显示可以让页面一键划到顶端的按钮,滑动动画代码如下

scrolltoTop:()=>{if(document.documentElement.scrollTop){var scrollTop=document.documentElement.scrollTopvar step=scrollTop/30;var now=scrollTop-step;var i=0;var time=setInterval(function(){i++;if(i>32){clearInterval(time)}document.documentElement.scrollTop=now;scrollTop=document.documentElement.scrollTopnow=scrollTop-step;},10)}else if(document.body.scrollTop){var scrollTop=document.body.scrollTopvar step=scrollTop/30;var now=scrollTop-step;var i=0;var time=setInterval(function(){i++;if(i>32){clearInterval(time)}document.body.scrollTop=now;scrollTop=document.body.scrollTopnow=scrollTop-step;},10)}},

这里比较坑的地方就是document.documentElement.scrollTop和document.documentElement.scrollTop需要注意

Home.vue

图片描述
这里给出了brands的样式,也就是说导航栏的home,clot,madness,bape,assc都有这个组件,

HomeFirst.vue

2.21号修改
重新改了下轮播,通过改变left来实现无限轮播,思路如下:

<div class="wrapper-content" :class="{wrapper_trans:isTrans}" :style="{width:originalData.img_width*(originalData.num+2)+'px',height:originalData.img_height+'px',left:-originalData.img_width+'px'}" ref="wrapperContent"><img class="wrapper-content_img" alt="4" :src="'../static/images/home_4.jpg'" :style="{width:originalData.img_width+'px',height:originalData.img_height+'px'}"/><img class="wrapper-content_img" alt="1" :src="'../static/images/home_1.jpg'" :style="{width:originalData.img_width+'px',height:originalData.img_height+'px'}"/><img class="wrapper-content_img" alt="2" :src="'../static/images/home_2.jpg'" :style="{width:originalData.img_width+'px',height:originalData.img_height+'px'}"/><img class="wrapper-content_img" alt="3" :src="'../static/images/home_3.jpg'" :style="{width:originalData.img_width+'px',height:originalData.img_height+'px'}"/><img class="wrapper-content_img" alt="4" :src="'../static/images/home_4.jpg'" :style="{width:originalData.img_width+'px',height:originalData.img_height+'px'}"/><img class="wrapper-content_img" alt="1" :src="'../static/images/home_1.jpg'" :style="{width:originalData.img_width+'px',height:originalData.img_height+'px'}"/>
</div>

共四张图片,前后再加一张,变成六张,当向后滚动到第五张时,index为4,下一次滚动,滚动到第六张结束后立即跳到第二张,index依然为3。向前滑动道理一样

methods如下

export default {data (){return {originalData:{img_width:350,img_height:350,btn_width:40,btn_height:40,num:4,delay:300},isTrans:true,//因为到最后一张图片,index为1时,需要立即跳到第二张index也为1的图片,这个用来是否给出transitionindex:1,timer:null,//setIntervalclickdelay:false//用来防止连续点击}},computed:{...mapGetters({hw:'getHW'}),home_first_width:function(){return parseInt(this.hw.w)-400;            },home_first_height:function(){var a= parseInt(this.hw.h)-200return a<389?389:a},home_first_height_margin:function(){return parseInt(this.home_first_height-300)/2}},methods:{next(){if(this.clickdelay){return }this.clickdelay=trueif(this.index==this.originalData.num){this.index=1}else{this.index+=1}this.animate(this.originalData.img_width)},prev(){if(this.clickdelay){return }this.clickdelay=trueif(this.index==1){this.index=this.originalData.num}else{this.index-=1}this.animate(-this.originalData.img_width)    },animate(offset){var node=this.$refs.wrapperContentvar self=this;var left=parseInt(node.style.left)-offsetthis.isTrans=truenode.style.left=left+'px'setTimeout(function(){if(left<-(self.originalData.num*self.originalData.img_width)){self.isTrans=falsenode.style.left=-self.originalData.img_width+'px'self.clickdelay=false //当到达最后一张图片时 }if(left>-100){self.isTrans=falsenode.style.left=-self.originalData.num*self.originalData.img_width+'px'self.clickdelay=false //当到达第一张图片时  }},this.originalData.delay)},play(){var self=this;this.timer=setInterval(function(){self.next()},2000)},stop(){this.clickdelay=false//用来防止连续点击clearInterval(this.timer)this.timer=null},turnTo(flag){if(flag==this.index){return}else{var offset=(flag-this.index)*this.originalData.img_widththis.index=flagthis.animate(offset)}}},mounted(){/*下面是判断过渡动画是否完成*/ var node=this.$refs.wrapperContentvar transitions = {'transition':'transitionend','OTransition':'oTransitionEnd','MozTransition':'transitionend','WebkitTransition':'webkitTransitionEnd'}var self=thisfor(var t in transitions){if( node.style[t] !== undefined ){var transitionEvent=transitions[t];}}transitionEvent && node.addEventListener(transitionEvent, function() {self.clickdelay=false              });this.play()},created(){this.$store.dispatch('changeShow','home')}}

Shop.vue

图片描述

methods:{changeLike(index){this.$store.dispatch('changeLike',index)//改变是否喜欢},changeFlagTrue(index){this.$store.dispatch('changeFlagTrue',index)//改变是否显示喜欢},changeFlagFalse(index){this.$store.dispatch('changeFlagFalse',index)//改变是否显示喜欢},changeSelectedItem(index){this.$store.dispatch('changeSelectedItem',index)//改变进入商品}}

每个商品被点击时都要改变进入的是哪个商品,changeSelectedItem来完成,这个页面想法来源于1626潮牌网,觉得挺好看的,于是自己写了下来,尤其是mouseover显示的是否喜欢,处理的还是可以,不过chrome和Firefox还是会有闪烁的效果没有处理好

shoppingitem.vue

图片描述
这个组件中重要的就是数量的增减,因为每个商品都有一个对象存储数据,并且加入购物车还需要判断购物车中是否有相同信息的商品,还有点击加入购物车后直接跳转到购物车页面,方法如下

methods:{changeSize(index){this.$store.dispatch('changeSize',index)},changeColor(num){this.$store.dispatch('changeColor',num)},changeNumSub(){if(this.item.num>1){this.$store.dispatch('changeNumSub')}},changeNumAdd(){if(this.item.num<8){this.$store.dispatch('changeNumAdd')}},addToCart(){if(!!this.item.color&&!!this.item.size){this.$store.dispatch('addToCart')}}}

index.js中的方法如下

ADD_TO_CART(state){var cart=state.cart;var thing=mutations.clone(state.selectedItem);//查看购物车是否已经有相同的商品,信息都一样if(!cart.length){cart.push(thing)    }else{var flag=cart.some(function(e){return e.color==thing.color&&e.size==thing.size&&e.src==thing.src})try{if(!flag){cart.push(thing);throw new Error("can't find")}cart.forEach(function(e,index){if(e.color==thing.color&&e.size==thing.size&&e.src==thing.src){cart[index].num+=thing.num;foreach.break=new Error("StopIteration");}})    }catch(e){//用于跳出循环}}state.selectedItem={};},

添加到购物车中的方法中,我用try,catch来跳出forEach循环,还有这句state.selectedItem={};如果state.selectedItem是直接引用别的对象,那么另一个对象也会跟着改变,为了避免引用,我用了如下方法

//js复制对象clone(myObj){if(typeof(myObj) != 'object') return myObj;if(myObj == null) return myObj;var myNewObj = new Object();for(var i in myObj)myNewObj[i] = mutations.clone(myObj[i]);return myNewObj;},

Brands.vue

图片描述
在created(){}中用this.$route.params.id来得到进入那个路由,因为这四个brand布局样式什么的大致都一样,然后watch来检测this.$route.params.id的改变,以此来getIntro也就是每个brand的数据

组件的介绍大致就是这些

四、Vuex

我在vuex这里没有做好,状态和数据应该分开,而且actions,mutations,getters,state,应该分开,不然太冗余了

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到 Vue 的官方调试工具 devtools extension,提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。
这个状态自管理应用包含以下几个部分:
state,驱动应用的数据源;
view,以声明方式将state映射到视图;
actions,响应在view上的用户输入导致的状态变化。

clipboard.png

clipboard.png

index.js中的state

大概罗列一点

const state={loginway:'',show:'home',clientheight:0,clientwidth:0,footItems:[{title:'ABOUT US',contents:{content_1:'contact us',content_2:'about vogue'}},{title:'SERVICE',contents:{content_1:'payment methods',content_2:'track order'}},{title:'POLICY',contents:{content_1:'privacy policy',content_2:'terms & condition'}},{title:'FOLLOW US',contents:{content_1:'Facebook',content_2:'Instagram'}},    ],left_nav:{home:'home',news:'news',collections:'collections',shop:'shop'},
]

index.js中的mutations

const mutations={CHANGE_HW(state,obj){state.clientwidth=obj.w;state.clientheight=obj.h;},CHANGE_SHOW(state,type){state.show=type},CHANGE_NOWBRAND(state,type){state.nowbrand=type+'Intro'},CHANGE_LIKE(state,index){state.goods[index].isLike=!state.goods[index].isLike;if(!state.goods[index].isLike){state.goods[index].likes+=1}else{state.goods[index].likes-=1}},
]

更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutations 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数:

index.js中的actions

const actions={change_hw({commit},obj){commit('CHANGE_HW',obj)},changeShow({commit},type){commit('CHANGE_SHOW',type)},changeNowbrand({commit},type){commit('CHANGE_NOWBRAND',type)},changeLike({commit},index){commit('CHANGE_LIKE',index)},
]

Action 类似于 mutation,不同在于:

Action 提交的是 mutation,而不是直接变更状态。
Action 可以包含任意异步操作。

index.js中的getters

const getters={getHW:function(state){return {h:state.clientheight,w:state.clientwidth}},getBrands:function(state){return state.brandsArr},getLeft_nav:function(state){return state.left_nav},getShow:function(state){return state.show}
]

有时候我们需要从 store 中的 state 中派生出一些状态,或用于得到信息

五、总结

自己写的这个项目,蛮有收获的,遇到了问题到处问,都解决的差不多了,
下面罗列了一些收货和本项目的不足

  • Firefox中不支持 table 的 min-height

  • CSS 的话 考虑用 normalize.css解决不同浏览器初始样式不一样的问题

  • css 的命名啥的可以参考一下 BEM 的命名规范

  • 代码组织有点杂乱

  • vuex只要专心做页面状态管理,尽量不要掺杂页面数据

  • <input type="checkbox" @change="selectAll" id="selectAll" v-model="isAll"/>此处的isAll是从state中get到得数据,可以被改变,我自己尝试得到的这个结论

  • 轮播还需要改进

  • 第一次在gh-pages中显示时,发现图片加载太慢 ,于是我把图片压缩了

  • 在用git上传代码是出过差错,解决了。

最后感谢您能阅读到这里,本人小白,努力学习中,献丑了。

参考资料

  • Vue2.0中文文档:https://cn.vuejs.org/

  • Vue-router2.0中文文档:http://router.vuejs.org/zh-cn...

  • Vuex2.0中文文档:http://router.vuejs.org/zh-cn...

  • git教程:http://www.liaoxuefeng.com/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_809441.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

谷歌浏览器外贸版_外贸建站SEO检测必备工具Woorank

本章主讲的内容是外贸建站SEO检测必备工具 Woorank .很多同学在建完站点并进行了一定的基础优化之后&#xff0c;会有一定的迷茫阶段。在内心里会产生一些自我疑问&#xff1a;为什么我的网站优化后并没有太大的流量改善&#xff1f;为什么优化后询盘数量并没有增多&#xff1f…

var模型可以用spss做吗_想做一个网站,用网页自助建站可以吗?该怎么做?

很多人都想拥有一个属于自己的网站&#xff0c;却又苦于不懂编程&#xff0c;不懂设计&#xff0c;无从下手。那么&#xff0c;在没有技术的情况下&#xff0c;可以建一个自己的网站吗&#xff1f;答案是当然可以&#xff01;过程也很简单&#xff0c;借助于一些网页自助建站系…

app制作流程步骤_网站创建与制作的详细流程步骤

现代制作网站的流程步骤早已不同往日&#xff0c;它发生了翻天覆地的变化。传统模式的网站教学大多数在十几年前就已经被淘汰。准备工具&#xff1a;手机号码、QQ邮箱、网站名称流程步骤&#xff1a;网络搜索-鸣蝉智能建站 - 创建网站 - 注册账号 - 选择网站类型 - 挑选行业模板…

魅族服务器升级维护中,网站升级维护中页面

网站升级维护中页面 内容精选换一换使用智能边缘系统注册设备之前需要升级HiLens Kit系统固件版本至2.2.200.011。HiLens Kit系统固件执行两次升级操作后&#xff0c;版本会升级到2.2.200.011&#xff0c;同时HiLens_Device_Agent固件会升级到1.0.6(如果设备HiLens Kit处于使用…

超星网站服务器,云服务器 超星

云服务器 超星 内容精选换一换云耀云服务器创建成功后&#xff0c;您可以根据需求&#xff0c;修改云服务器的名称。系统支持批量修改多台云耀云服务器的名称&#xff0c;修改完成后&#xff0c;这些云耀云服务器的名称相同。登录控制台。单击管理控制台左上角的&#xff0c;选…

网站服务器盒子,云服务器盒子

云服务器盒子 内容精选换一换子网创建好后&#xff0c;网段是不支持修改的。如需修改子网网段可以通过更换子网来实现。云服务器已关机。登录管理控制台。选择“计算 > 弹性云服务器”。在弹性云服务器列表中的右上角&#xff0c;输入弹性云服务器名、IP地址或ID&#xff0c…

php蜘蛛池计费系统,「seo基础知识」网站排名骤然下降的原「蜘蛛池 计费系统 seo」因是哪些?...

搜索引擎优化根底常识有许多&#xff0c;可是闭于网站排名突然降落&#xff0c;那个工作便比力值得理解了&#xff01;假如网站排名突然降落能够有以下多少个本果。软文以辅助seo为主(一)网站被乌客进犯了&#xff0c;假如您的网站被乌客进犯&#xff0c;呈现了年夜量的404 503…

推荐几个很实用的编程网站

目录 一、 W3School 二、LeetCode 三、PythonTip 四、 Codewars 五、 Code Monkey 本文精选了有关代码、编程、Java、Python、SQL、Git、和Ruby on Rails学习的网站。这些网站为以下内容的学习提供了免费的优质资源&#xff1a;编程语言(Python和Java等) 、常用技术(SQL等…

分享9个ps、pr免费教程网站

1、doyodo doyodo自学网站,致力于为用户提供优质的PR,AE,C4D,PS,AI,ID等各类设计软件教程,同时提供设计与剪辑的最新设计资讯速 传送门&#xff1a;https://www.yiihuu.com/ 2、我要自学网 电脑办公&#xff0c;平面设计&#xff0c;机械设计&#xff0c;程序开发&#xff0c…

.interface文件怎么看啊_怎么无密码登录网站后台?试试变量覆盖漏洞

1前言各位师傅们有没有这样的经历&#xff0c;看着大佬随便爆破就可以进别人网站的后台&#xff0c;嘴上mmp&#xff0c;心里还要mmp&#xff0c;怎么自己的字典就那么呢&#xff0c;没办法&#xff0c;苦求无门&#xff0c;只能自己另寻办法解决。经过学习发现这么个变量覆盖漏…

网站托管:遇到问题友链怎么办?

友情链接在网站内部起到一个沟通外联的作用&#xff0c;而且质量好的友情链接还能够优化网站的权重&#xff0c;为网站带来一部分流量。所以&#xff0c;友情链接在网站托管优化工作中虽然工作量不大&#xff0c;但是是非常重要的一部分。但是现在郑州网站建设重内容创作&#…

怎么把整个网站的代码中的一个词去掉_SEO重拎SITE命令:看收录,判降权…还能发现网站结构疏漏...

给部门编辑们提供SEO文章发布指南时&#xff0c;发现大伙对于SITE命令尚缺乏了解和应用。回到我自己入门SEO的那个时间点 &#xff0c;是先从掌握几个SEO命令开始的&#xff0c;其中最为实用的就是SITE命令&#xff0c;因为它可以查看网站的收录量。除此之外&#xff0c;SITE命…

webmatrix如何使用php,用微软的webmatrix配置PHP网站

类型&#xff1a;图像浏览大小&#xff1a;13.0M语言&#xff1a;英文 评分&#xff1a;3.6标签&#xff1a;立即下载用upupw总是报错&#xff0c;启动不起来php系统&#xff0c;后来发现php其实也是建立在iis基础之上的&#xff0c;所以改用webmatrix配置系统环境&#xff0c;…

Silverlight实例秀——可切换视图的DataTemplate(做网站必备技术)

小序&#xff1a;敏捷开发也是要有个度的。搞敏捷&#xff0c;最起码的限度是程序员要对手里使用的工具比较精通。相信大家都见过这个场景&#xff1a;问&#xff1a;“你在做什么&#xff1f;”程序员&#xff1a;“我在敏捷开发。”问&#xff1a;“这样设计不对吧……”程序…

tomcat网站根目录在哪里_千岛湖网站SEO公司哪里有,360SEO优化_万推霸屏

首页 > 新闻中心发布时间&#xff1a;2020-11-11 16:49:59 导读&#xff1a;万推霸屏为您提供千岛湖网站SEO公司哪里有,360SEO优化的相关知识与详情&#xff1a; 事实上&#xff0c;我们的技术太复杂&#xff0c;这带来了巨大的技术障碍。在进行优化的时候我们需要注意的是要…

用jekyll制作高大上的网站(一)——安装与配置

很多人会制作自己的主页&#xff0c;页面美观简洁&#xff0c;一直很在意是怎么做的。 最近公司需要做个文档库的主页&#xff0c;就研究了一些开源的工具&#xff0c;后面发现了jekyll&#xff08;读杰克尔&#xff09;&#xff0c;将纯文本转换为静态博客网站。 一、Ruby jek…

大型网站运维探讨和心得(转载)

2019独角兽企业重金招聘Python工程师标准>>> 看到一篇不错的心得体会&#xff1b;相信我们做技术的都会有或多或少的担忧自己的未来职业发展&#xff1a; 今天看到一篇心得体会&#xff0c;转过来和大家一起探讨一下&#xff1a; 一、什么是大型网站运维? 首先明确…

计算机安全知识百度,seo百度_计算机专业基础知识包括哪些内容? 计算机网络与安全基础知识...

可选中1个或多个下面的关键词&#xff0c;搜索相关资料。也可直接点“搜索资料”搜索整个问题。我是计算机专业的&#xff0c;它分为软件和硬件&#xff0c;硬件电路基础&#xff0c;电子电路&#xff0c;电脑组装&#xff0c;CPU 芯片。显卡。声卡。微机接口&#xff1b;软件c…

动态网站设计——笔记

rowspan 使用时 逐一使用可以避免多出一行 脑子多运动一点 clospan 合并行 一样的 <table style"width: 100%;"><tr><td rowspan"3"><img alt"" src"images/Screenshot_2022_0416_184734.png" style"heigh…

服务器被黑了做非法网站,网站被黑如何处理

日常生活中&#xff0c;偶尔会遇到网站被恶意植入非法信息的可能&#xff0c;那么遇到这种情形我们要以什么样的方式来判断网站是否被黑了呢&#xff1f;一、以下就是网站被黑的处理方法&#xff1a;1.可以联系主机提供商&#xff0c;对方做出应对。2.处理一些被修改过的文件。…