Vue3.0商城页面的开发--思路

理一下基于Vue3.0商城页面的开发思路。是基于Js+Vue+大厂面试这里的视频写的。
在这里插入图片描述

1. 组件基本嵌套思想:

在这里插入图片描述

2. MALL组件中的导航部分样式动态改变:

通过一个组件数据current表示当时选中的导航项的名称,为每个导航项注册点击事件
以“手机”为例:<a :class = "{active: this.current == '手机' @click = changeClass('手机')}">手机</a>

methods:{
    changeClass(c){
        this.current = c
    }
}

同时,由于a标签有默认事件,可通过<a :class = "{active: this.current == '手机' @click.prevent = changeClass('手机')}">手机</a>的方法阻止默认事件,解决点击a标签时的页面闪烁问题。

3. 展示列表组件中的内容如何根据导航变化——计算属性computed

假设我们已经在MALL组件中,获取到了所有项的数据列表itemsitems中的每一项都有classfication属性,由于我们需要从已知的数据中过滤数据,这时要想到computed计算属性。

MALL组件中:

computed: {
    showItems: {
        get () {
            let items = this.items
            if (this.current != ''){
                items = this.items.filter(item => item.current == this.current)
            }
            return items
        }
    }
}

在MALL组件中:<show-list :dataList = showItems/>
在展示列表组件中接收:props: ['dataList'],然后在展示列表组件中就可以使用dataList 数据,就相当于这个组件的data函数中已经有了dataList(个人理解哈)

4. 分页组件
  1. 思考这个子组件需要接收哪些数据(props):
    total(总的数据量)
    prepage(每一页显示的数量)
    page(当前页码)
    由此我们可得出总的页数:
    pages: Math.ceil( this.total / this.prepage)
    将总页数pages放在computed中,而不能放在data中,因为做到这里,展示列表组件中展示的数据是根据导航栏的不同分类展示了全部,并没有根据页码分页,如果放在data中,只会在页面刚开始渲染的时候计算一次pages的值,后面点击其他分类时,实际上total的值已经改变为新的类别下的总数量,但data中不会再重新实时更新计算了,因此需要放入computed中以达到每次点击不同分类都能更新total,从而更新pages
  2. 基本template模板:
<a>上一页</a>
<a v-for = "p of pages">{{p}}</a>
<a>下一页</a>

这里注意,v-for是可以遍历数组,对象和数字的。

  1. 当前页码高亮处理:
    可以通过动态class属性绑定:
<a >上一页</a>
<a :class = "{current: p == page}" v-for = "p of pages">{{p}}</a>
<a>下一页</a>
  1. 上一页、页码、下一页的点击事件处理:
<a @click.prevent = "changePage(page - 1)">上一页</a>
<a :class = "{current: page == p}"  v-for = "p of pages"  @click.prevent = "changePage(p)">{{p}}</a>
<a @click.prevent = "changePage(page + 1)">下一页</a>

第一想法必然是在分页组件的methods中写changePage函数:

methods: {
    changePage(p){
        this.page = p
    }
}

但这是错误的! 因为page这个数据是用props接收的,所以这是父组件(展示列表组件)中的数据。如果我们直接在子组件中修改了这个数据,父组件并没有同步到,在父组件中很有可能还有其他的子组件用到这个数据。因此,我们必须要让父组件去修改这个数据,然后子组件就可以通过props接收到它的变化。
那么父组件如何修改呢?可通过$emit事件的方式,在子组件中触发事件,父组件中接收到事件信号,修改数据。
分页子组件中:

methods: {
    changePage(p){
        this.$emit("changePage", p)
    }
}

展示列表父组件中(不同类别下的各自总数量上面已经说过了,是接受了MALL组件传入的dataList数据):

<k-pagination :pages = dataList.length  :perpage = prepage  :page = page  :changePage = "change"/>
methods: {
    change(p){
        this.page = p
    }
}

这样就在父组件中修改了page,会自动通过props传送到子组件中同步修改。、

  1. 展示列表组件中根据页码显示不同的项

展示列表组件中:

<ul>
    <li v-for = "item of listItems">...(具体不详细写了)</li>
</ul>
computed: {
    listItems: {
        get () {
            let start = (this.page - 1) * this.prepage
            let end = start + this.prepage
            return this.dataList.slice(start, end)
        }
    }
}
5. 购物车组件

在这里插入图片描述
在这里插入图片描述

  1. 购物车组件显示:
    展示列表k-items 组件下,点击导航栏中的购物车后就显示购物车组件内容,说明展示列表组件购物车组件不同时显示,我们可以用动态组件的方法切换这两个组件:<component :is="currentView"></component>is绑定的值是组件名称,可为导航注册点击事件,改变currentView的值,展示列表组件k-items购物车k-carts这两个组件中所需要绑定的数据和方法都可以直接写在component这一个组件中即可。
  2. 选中
    当购物车中的任意一个项被选中时,需要将这个项的checked属性变为true,又要改变通过props接收的数据,可为这个单选框控件绑定change事件,<input @change = "changeChecked(item, $event)" />k-carts组件中的changeChecked方法为:
methods: {
    changeChecked(item, e){
        this.$emit("changechecked", item, e.target.checked)
    }
}

k-items 组件中,<component :is="currentView" :changechecked = “changeChecked”></component>,并在此组件的changeChecked方法中,将该项的checked属性变为true

  1. 全选和反选
    双向绑定全选控件<input v-model = "checkedall"/>,通过v-model实现数据的双向流动。这里由于checkedallk-carts组件内部自身的数据,因此可以双向绑定。(但如果是要改变通过props接收的数据,子组件是不能擅自修改的,必须通过$emit通过父组件去修改)
    k-carts组件中:
computed: {
    checkedall: {
        //get函数用来实现自动全选:当每一项的checked为true时,全选按钮就自动选中
        get () {  
            return this.cartItems.every(ci => ci.checked)
        },
        //set函数实现手动全选:监视当前属性值的变化,当属性值发生变化时执行,更新相关的属性数据
        set (newVal) {
            return this.$emit("changeall", newVal)
        }
    }
}

k-items组件中:
<component :is="currentView" :changechecked = “changeChecked” :changeall = "changeAll"></component>

methods: {
    changeAll(item, checked){
       this.cartItems.forEach(ele => {
           ele.checked = checked
       })
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值