8- vue django restful framework

作者: 天涯明月笙 | 来源:发表于2018-03-10 20:12 被阅读626次

Vue+Django REST framework实战

搭建一个前后端分离的生鲜超市网站
Django rtf 完成 商品类别页

vue展示商品列表页数据

  1. 点击某一个导航的一级类,将数据显示出来。或点击搜索,搜索出结果

这两个功能要一起完成: 格局是一样的,左侧导航,右侧商品列表。

  • 点击某一个导航分类会显示它底下的二级三级分类,一级它有多少商品。

  • 搜索只会显示一级与二级分类。

  • 商品列表页有他的分页和排序。

当我们点击生鲜食品和搜索都用的是同一个左侧nav组件。但是它又有所区别

点击搜索,它请求的是所有的category显示到二级目录,而点击生鲜食品。它只请求当前类别下的二级和三级目录。

如何才能在一个组件中区别出世导航栏过来的,还是搜索页面过来的。

在head里面就能找到这两者vue router的区别。

markmark

可以看到不管是通过点击弹出的还是导航都是跳转到上图所示的vue router

markmark

点击热搜榜则跳转的是search router

  • 查看vue router里面的跳转逻辑

src/router/index.js

markmark

list为商品分类,而search为搜索

markmark

可以看出component指向同一个组件。只是url不一样。当然url附带的参数也不一样;

一个是id 一个是keyword

src/views/list/list.vue 中

在页面生命周期的create方法中进行了getalldata的调用:

created () {
            this.getAllData ();
        },

getAllData中我们可以获取到this.$route.params虽然共用的是一个组件,但是路径里传的参数不同。

  getAllData () {
                console.log(this.$route.params)
                if(this.$route.params.id){
                    this.top_category = this.$route.params.id;
                    this.getMenu(this.top_category); // 获取左侧菜单列表
                }else{
                    this.getMenu(null); // 获取左侧菜单列表
                    this.pageType = 'search'
                    this.searchWord = this.$route.params.keyword;
                }

                this.getCurLoc(); // 获取当前位置
                this.getListData(); //获取产品列表
                this.getPriceRange(); // 获取价格区间
            },

如果传过来的是id,那么会是上面代码中的getMenu,传入当前的category的id作为参数。

获取到某一个category的二级三级分类。

getMenu(id) {
                if(id != null){
                  getCategory({
                    id:this.$route.params.id
                  }).then((response)=> {
                    this.cateMenu = response.data.sub_cat;
                    this.currentCategoryName = response.data.name
                  }).catch(function (error) {
                    console.log(error);
                  });
                }else {
                  getCategory({}).then((response)=> {
                    this.cateMenu = response.data;
                    this.isObject = false
                  }).catch(function (error) {
                    console.log(error);
                  });
                }

            },

如果id不为空,也就是分类查询二级三级,那么则调用getCategory,将当前的cateMenu和currentCategoryName 使用response.data中的进行填充。

src/views/list/list-nav/listNav.vue:

markmark

可以看到传递进来的参数,我们是在list中获取到的数据想要传递到listnav中来,就要用

<list-nav :currentCategoryName="currentCategoryName" :cateMenu="cateMenu" :proNum="proNum" :isObject="isObject" @on-change="changeMenu"></list-nav>

通过冒号后面加变量及参数名。将当前页内值传递到list_nav.因为不止要获得类别,还要获取商品一共多少件。

左侧的列表调用的都是getCategory函数,之前我们已经将其配置为本地化数据。

商品的列表页

获取产品的列表会判断我们是只几天的search。还是要获取商品getGoods

getListData() {
                if(this.pageType=='search'){
                  getGoods({
                    search: this.searchWord, //搜索关键词
                  }).then((response)=> {
                    this.listData = response.data.results;
                    this.proNum = response.data.count;
                  }).catch(function (error) {
                    console.log(error);
                  });
                }else {
                  getGoods({
                    page: this.curPage, //当前页码
                    top_category: this.top_category, //商品类型
                    ordering: this.ordering, //排序类型
                    pricemin: this.pricemin, //价格最低 默认为‘’ 即为不选价格区间
                    pricemax: this.pricemax // 价格最高 默认为‘’
                  }).then((response)=> {

                    this.listData = response.data.results;
                    this.proNum = response.data.count;
                  }).catch(function (error) {
                    console.log(error);
                  });
                }

            },

搜索的时候不需要知道当前的页码,排序规则。而如果page_type不是搜索(page_type的设定是位于getalldata中根据请求参数判断设定的),那么我们可以调用getGoods

getGoods位于api.js中

//获取商品列表
export const getGoods = params => { return axios.get(`${local_host}/goods/`, { params: params }) }

getListData中的getgoods可以看到前端使用的参数名称。

我们可以前往view中将分页的参数修改为page与前端保持一致。

    page_query_param = "page"

参数top_category就是我们的第一级别。它是将我们参数中的id值传入。

因此在后台我们也需要配套的做一个category的过滤器。

如何获取一级分类下的所有商品。

goods/filters.py:class GoodsFilter

    top_category = filters.NumberFilter(name="category",method='top_category_filter')

    def top_category_filter(self, queryset, name, value):
        # 不管当前点击的是一级目录二级目录还是三级目录。
        return queryset.filter(Q(category_id=value)|Q(category__parent_category_id=value)|Q(category__parent_category__parent_category_id=value))

然后将queryset return回去。

pricemin以及pricemax与我们的前端代码中的不一致。

所以修改goods/filters.py中的与前端保持一致。

分页数据中会自带一个count值。

markmark

往上翻一点; getListdata中的getGoods里面我们获取到了response.data.count;
然后存入了proNum中。proNum是我们当前页面data中的变量,通过list nav:传递到了list nav页面

                <list-sort @on-sort="changeSort" :proNum="proNum"></list-sort>

list sort也是同样传递了这个变量过去。

  • 设置分页size与前端保持一致
class GoodsPagination(PageNumberPagination):
    page_size = 12
  • GoodsListViewSet中的order字段与前端保持一致
    ordering_fields = ('sold_num', 'shop_price')

vue的商品搜索功能

search_fields = ('name', 'goods_brief', 'goods_desc')

没有需要配置的接口,因为search仍然调用的是后端的goods接口。

价格区间

<price-range :priceRange="priceRange" @on-change="changePrice"></price-range>

为price-range组件传递了priceRange参数

 getPriceRange () {
                this.$http.post('/priceRange', {
                    params: {
                        proType: this.type, //商品类型
                    }
                }).then((response)=> {

                    this.priceRange = response.data;
                }).catch(function (error) {
                    console.log(error);
                });
            },

getPriceRange会在getAllData也就是crate生命周期被调用。

$http.post是发起向mock中的数据接口的请求。

Mock.mock('/priceRange',

推荐将这些数据设置到后台中。价格区间根据不同的商品类别等计算。

相关文章

网友评论

本文标题:8- vue django restful framework

本文链接:https://www.haomeiwen.com/subject/dzomfftx.html