添加书架页面,做路由配置
首先添加书架页面,到views中的store中添加一个StoreShelf表示书架
然后到路由中进行注册
然后书城首页的返回键我们是想要点击返回的话就跳转到书架页面,所以如下this.$router.push('/store/shelf')
做书架标题组件
我们在components中创建一个shelf文件夹然后创建一个书架标题组件即ShelfTitle.vue,并且在书架组件即StoreShelf.vue中引入注册使用书架标题组件。然后我们继续做书架标题组件。
我们这个标题下面还有一个副标题,就是你在选择图书的时候这里就会展示出你选了多少本书,所以这个副标题不是一段固定的文本,而是一个变化的,所以我们定义为一个变量,因为它是在变化的,所以我们把它放到computed计算属性中
实现编辑的交互
然后我们去实现编辑逻辑,点击编辑后会变文字变成取消,并且点击编辑后书架下面的副标题才会出现,我们选择书籍后副标题的文本会发生变化会自动统计选择的书籍数量。
点击编辑变取消,点击取消变编辑
也就是我们需要一个变量来控制编辑-取消的显示状态,所以我们到vuex中定义一个变量叫isEditMode,用来控制是否进入编辑模式,同理在mixin.js中引入,然后我们引入mixin,然后我们给编辑按钮添加一个点击事件叫onEditClick,在这个方法中我们让setIsEditMode去修改state中isEditMoed的值,即如果此时是编辑模式就展示取消,如果不是编辑模式就展示编辑,所以在上面我们用三元表达式{{isEditMode?'取消':'编辑'}},如下
编辑模式下副标题展示,不是编辑模式下副标题不展示
这个副标题是否展示是与是否是编辑模式决定,而isEditMode这个变量就控制着是否是编辑模式,所以根据这个变量v-show展示副标题即可
编辑模式中,如果还没有选择书籍,副标题就展示请选择书籍;如果选择了几本书籍,副标题需要展示已选择xx本书籍
我们在vuex中定义一个变量shelfSelected: [],是一个数组变量,记录选择了什么书
首先我们应该获取到当前选择的书数量,然后再根据这个数组中有没有图书,如果有图书即长度不为0则返回已选择多少本图书,如果没有图书则返回请选择图书,如下
实现搜索框的交互
我们用什么布局来做搜索框,使得点击搜索框的时候搜索框向上移动?
我们定义一个全屏的滚动条组件,然后将搜索框距离top顶部有标题栏的高度,书架列表就距离top顶部有标题栏和搜索框的高度,为什么这样做呢,我们采用这种绝对定位来做这个页面有什么好处呢,好处在于,我们点击搜索框的时候搜索框的移动会比较容易实现,因为我们布局这个搜索框的时候是距离top顶部有高度的,我们点击搜索框时就将它的top置为0,即可实现搜索框向上移动的效果了,这比用translate3d更加好做
书架搜索框布局实现
我们在书架组件中引入滚动条组件即Scroll.vue组件,如下我们让它是绝对定位并且覆盖全屏
然后我们components的shelf下定义一个搜索框组件,然后如下,这里搜索图标搜索框叉叉图标是用flex布局实现,因为中间搜索框需要自适应充满剩余的位置嘛。然后设置input里面的显示文字样式是通过&::-webkit-input-placeholder,同理这个搜索框去掉点击显示图框这个是通过&:focus{ outline:none }实现,搜索框的边框是通过border:none来实现
然后来实现这个叉叉图标的交互
搜索框的叉叉图标是搜索框中有内容时才展示,没有内容时不展示,所以定义一个变量叫searchText来保存搜索框中的输入的文本,然后v-show去判断这个变量长度大于0就说明有输入的文字就展示叉叉图标,否则不展示叉叉图标;
然后给叉叉图标加个点击事件,点击事件中就把搜索框中searchText置为空即可实现点击叉叉图标就把搜索框中文字删除的交互
现在我们实现搜索框的移动
我们点击搜索框后,搜索框上移,我们给整个搜索框绑定一个class,这个样式就是让搜索框上移,搜索框上移的条件就是点击了搜索框,所以是:class="{'search-top':ifInputClicked}",这个样式中就把top置为0即可,然后再给个transition过渡动画,观测top值
然后搜索框上移后标题栏需要隐藏,点击取消可以让搜索框下移回来并且展示标题栏,所以
接下来实现点击搜索框后下面的tab展示
首先tab栏是否显示是看搜索框是否是被点击状态,所以用v-if=ifInputClicked来控制tab是否显示;然后tab栏不是直接三个文本默认\按进度\按购买直接展示出来那么简单,因为你点击它是需要被知道你点击的是哪一个所以这三个需要有个id来识别是哪个tab,所以computed中定义一个tabs属性,里面返回一个数组,数组中就是这三个tab的文本和id,然后去循环展示出这三个文本;然后你点击某一个后你需要知道当前点击的是哪一个,所以需要定义一个变量selectedTab来保存你点击的那个tab的id,所以给整个tab组件绑定一个点击事件,点击就把当前点击的tab的id传过去,然后点击事件中就去改变这个selectedTab的值;最后被点击的tab我们想要它有高光样式,所以给它们绑定一个class,如果当前的tab的id等于selectedTab的id即展示高光样式
然后这个tab也是用绝对定位,它top是52就是搜索框的高度;然后给display:flex;然后每个tab都是flex:1;这样它们就都是自适应撑满
接下来我们去实现书架里的图书
图书列表方框中的三种状态
这里图书分为三种状态:第一种为默认状态;第二种状态就是分类状态,就是当我们把几本书加入同一类之后它会显示出一个分类模块;第三种状态就是我们的添加状态。
三种状态就需要有三种组件支持,然后我们通过动态组件,动态的来判断当前应该属于哪种状态,这是图书书架的实现思路。
首先我们要获取数据源
如下就是我们准备在mock中的书架数据
然后我们要先到api的store.js中配置获取mock模拟数据的书架接口
然后需要到StoreShelf中获取这个mock模拟的书架数据,把这个shelf接口方法引入进来,然后在mouted钩子函数中调用这个方法
如下我们可以看到返回的数据,其中这个type是1则表示是个图书,那么它的title就是这个图书名,如果type是2则表示它是个分类,那么它的title就是这个分类名称就是你分类起的分类名,然后这个分类中的itemList就是这个分类中的图书。type为3是添加状态,是我们手动实现,等一下会做
然后处理数据,我们在vuex中定义一个数组变量,保存我们获取回来的书架数据。这样我们数据就准备好了
方框组件与三种组件结构关系
接下来我们实现书架图书列表组件,我们在components中的shelf中增加一个ShelfList组件,然后ShelfList组件下的每一块就是一个ShelfItem.vue组件(就是这一块不是一个图书就是一个分类不然就是添加状态的图片),然后每个框下有可能是一本书或者一个分类或者一个添加状态,所以还需要三个子组件分别表示这三种状态,状态1即默认图书我们叫ShelfItemImage.vue,状态2即分类组件我们叫它ShelfItemCategory.vue,状态3即添加组件我们叫ShelfItemAdd.vue
然后ShelfItem就那方框中我们用使用动态组件,即动态的去加载这里的三个组件,我们根据传入的参数然后使用动态组件判断三个组件到底加载哪一个
然后我们去实现这些组件
首先我们来实现ShelfList组件即图书列表组件即搜索框下哪些图书
然后我们发现滑动的时候那个搜索框也跟着滑上去了,我们是希望搜索框固定在上面不跟着滑动的,所以要固定搜索框,所以在ShelfSearch的搜索框中我们绑定一个样式,即整个搜索栏被点击的时候是固定在底部的,所以用上position:fixed;固定定位给它top:0;left:0;即固定在顶部,这样你鼓动图书列表是时候就不会带跑它啦
然后滚动的时候我们希望搜索框下面有阴影,就接收滚动条组件传递过来的偏移量,然后监测这个偏移量嘛,一旦偏移量大于0说明滑动了,那就展示阴影
如下我们在书架组件中绑定@onSrcoll,然后定义一个onScroll方法,这个方法中接收滚动条组件中传过来的值;滚动条组件中滚动条一旦滚动就会触发$emit把偏移量传过来。得到滚动偏移量后我们就把vuex中的偏移量值更新
然后我们到标题栏组件中,定义一个变量叫ifHideShadow用来控制是否显示阴影,默认为true即不显示阴影;然后我们watch监听vuex中的偏移量,如果偏移量大于0即展示阴影即置为false,否则置为true,然后给标题搜索整个栏绑定一个样式,即ifHideShadow为true时则显示这个样式,这个样式即置box-shodow为none,平时就box-shadow:0 2px 2px 0;