首页
以为不错,给我的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.scrollTop
var 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.scrollTop
now=scrollTop-step;
},10)
}else if(document.body.scrollTop){
var scrollTop=document.body.scrollTop
var 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.scrollTop
now=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的图片,这个用来是不是给出transition
index:1,
timer:null,//setInterval
clickdelay: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)-200
return 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=true
if(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=true
if(this.index==1){
this.index=this.originalData.num
}else{
this.index-=1
}
this.animate(-this.originalData.img_width)
},
animate(offset){
var node=this.$refs.wrapperContent
var self=this;
var left=parseInt(node.style.left)-offset
this.isTrans=true
node.style.left=left+'px'
setTimeout(function(){
if(left<-(self.originalData.num*self.originalData.img_width)){
self.isTrans=false
node.style.left=-self.originalData.img_width+'px'
self.clickdelay=false //当抵达末了一张图片时
}
if(left>-100){
self.isTrans=false
node.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_width
this.index=flag
this.animate(offset)
}
}
},
mounted(){
/*下面是推断过渡动画是不是完成*/
var node=this.$refs.wrapperContent
var transitions = {
'transition':'transitionend',
'OTransition':'oTransitionEnd',
'MozTransition':'transitionend',
'WebkitTransition':'webkitTransitionEnd'
}
var self=this
for(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上的用户输入致使的状况变化。
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…