Flask 与小程序 的图片数据交互 过程及探讨研究学习

今天不知道怎么的,之前拿编程浪子地作品抄过来粘上用好好的,昨天开始照片突的就不显示了。

今天不妨再耐味地细细探究一下微信小程序wxml 和flask服务器端是怎么jpg图片数据交互的。

mina/pages/food/index.wxml

XML 复制代码
<!--index.wxml-->
<!--1px = 750/320 = 2.34rpx;-->
<view class="container">
  <!--轮播图-->
  <view class="swiper-container">
    <swiper class="swiper_box" autoplay="{{autoplay}}" interval="{{interval}}" duration="{{duration}}" bindchange="swiperchange">
      <block wx:for="{{banners}}" wx:key="id">
        <swiper-item>
          <image bindtap="tapBanner" data-id="{{item.id}}" src="{{item.pic_url}}" class="slide-image" width="750rpx" height="562.5rpx" />
        </swiper-item>
      </block>
    </swiper>
    <view class="dots">
      <block wx:for="{{banners}}" wx:key="unique">
        <view class="dot{{index == swiperCurrent ? ' active' : ''}}"></view>
      </block>
    </view>
  </view>
  <!--分类展示-->
  <view class="type-container">
    <scroll-view class="type-navbar" scroll-x="true">
      <view class="type-box" wx:for-items="{{categories}}" wx:key="id">
        <view id="{{item.id}}" class="type-navbar-item {{activeCategoryId == item.id ? 'type-item-on' : ''}}" bindtap="catClick">
          {{item.name}}
        </view>
      </view>
<!--      这段代码是一个小程序中的一个视图组件,它使用了小程序的模板语法。具体来说,这段代码定义了一个视图组件,其中包含一个view标签,
        该标签具有id属性和class属性,并且绑定了一个tap事件处理函数"catClick"。
    在view标签内部,使用了双花括号语法来插入动态数据,其中item.id和item.name是动态的数据,根据实际情况进行渲染。-->
    </scroll-view>
  </view>
  <!--搜索框-->
  <view class="search-view" style="background:{{ scrollTop === 0 ?'-webkit-linear-gradient(top, rgba(105,195,170, 1), rgba(105,195,170, 0.3))' :( scrollTop<200 ? 'rgba(105,195,170,'+(scrollTop/400+0.3) +')' : 'rgba(105,195,170,1)')  }} ">
    <view class="search-content">
      <image src="/images/search-pic.png" class="search-icon" />
      <input placeholder="请输入搜索内容" class="search-input" maxlength="30" confirm-type="搜索" bindinput='listenerSearchInput'>
      </input>
      <button class='search-btn' bindtap="toSearch">搜索</button>
    </view>
  </view>

  <view class="goods-container">
    <!--    wx:for-items="{{goods}}" 是一个循环遍历的功能,将 goods 数组中的每个元素都渲染成一个 goods-box 组件。-->
    <view class="goods-box" wx:for-items="{{goods}}"  bindtap="toDetailsTap" data-id="{{item.id}}">
      <view class="img-box">
        <image src="{{item.pic_url}}" class="image" mode="aspectFill" lazy-load="true" />
      </view>
      <view class="goods-title">{{item.name}}</view>
      <view style='display:flex;'>
        <view class="goods-price">¥ {{item.min_price}}</view>
        <view wx:if="{{item.price && item.price > 0 && item.min_price != item.price}}" class="goods-price" style='color:#aaa;text-decoration:line-through'>¥ {{item.price}}</view>
      </view>
    </view>
  </view>
  <view hidden="{{loadingMoreHidden ? true : false}}" class="no-more-goods">哥也是有底线的</view>
</view>

如上例代码所示,图片的展示是通过一个image src='{{item.pic_url}}'标签引入的。通常情况下,item是一个对象或数组,它包含了多个属性,其中pic_url就是其中一个属性。在这个例子中,item.pic_url表示图片的URL地址,通过该地址可以加载并显示对应的图片。

总之,image 标签是小程序中用于显示图片的组件,通过 src="{``{item.pic_url}}" 绑定了图片的地址。追根溯源,找goods数组是从哪里传来的。

goods数组是通过小程序端地js文件绑定的一个getBannerAndCat()函数,并将其设置在onshow生命周期里,通过调用getFoodList(),自动进行的数据读取和刷新。

javascript 复制代码
 //解决切换不刷新维内托,每次展示都会调用这个方法
    onShow:function(){
        this.getBannerAndCat();
    },
问题: 这个item对象或数组从何而来?是小程序端的js文件吗?

mina/pages/food/index.js

javascript 复制代码
//index.js
//获取应用实例
var app = getApp();
Page({
    data: {
        indicatorDots: true,
        autoplay: true,
        interval: 3000,
        duration: 1000,
        loadingHidden: false, // loading
        swiperCurrent: 0,
        categories: [],
        activeCategoryId: 0,
        goods: [],
        scrollTop: "0",
        loadingMoreHidden: true,
        searchInput: '',
        p:1,
        processing:false
    },
    onLoad: function () {
        var that = this;
        wx.setNavigationBarTitle({
            title: app.globalData.shopName
        });
    },
    //解决切换不刷新维内托,每次展示都会调用这个方法
    onShow:function(){
        this.getBannerAndCat();
    },
    scroll: function (e) {
        var that = this, scrollTop = that.data.scrollTop;
        that.setData({
            scrollTop: e.detail.scrollTop
        });
    },
    //事件处理函数
    swiperchange: function (e) {
        this.setData({
            swiperCurrent: e.detail.current
        })
    },
    listenerSearchInput:function( e ){
        this.setData({
            searchInput: e.detail.value
        });
    },
    toSearch:function( e ){
        this.setData({
            p:1,
            goods:[],
            loadingMoreHidden:true
        });
        this.getFoodList();
	},
    // tapBanner是一个函数,它用于处理轮播图的点击事件具体的实现逻辑如下:
    tapBanner: function (e) {
        // 首先,通过e.currentTarget.dataset.id获取到当前点击的轮播图的id。
        // 然后,判断id是否为0,如果不为0,则执行以下操作:
        if (e.currentTarget.dataset.id != 0) {
            // 使用wx.navigateTo函数进行页面跳转,跳转到指定的页面。
            wx.navigateTo({
                // 跳转的目标页面是"/pages/food/info",并且通过url参数传递了点击轮播图的id,参数名为id。
                url: "/pages/food/info?id=" + e.currentTarget.dataset.id
            });
        //     这段代码的作用是当用户点击轮播图,如果轮播图的id不为0,则跳转到指定的页面,并将点击轮播图的id作为参数传递给标页面。
        }
    },
    // toDetailsTap是一个函数,它是在小程序中用于点击事件的回调函数。当触发点击事件时,会执行该函数。
    toDetailsTap: function (e) {
        // 该函数的作用是跳转到指定的页面。在函数内部,通过调用wx.navigateTo方法来实现页面跳转。
        // 其中,url参数指定了跳转的目标页面路径,通过拼接字符串的方式将参数id传递给目标页面。
        // 总结一下,toDetailsTap函数的作用是在点击事件发生时,跳转到指定的页面,并将参数id传递给目标页面。
        wx.navigateTo({
            url: "/pages/food/info?id=" + e.currentTarget.dataset.id
        });
    },
    getBannerAndCat: function () {
        var that = this;
        // 使用微信小程序的wx.request方法发送一个请求。
        wx.request({
            // 请求的URL是通过app.buildUrl("/food/index")方法构建的
            url: app.buildUrl("/food/index"),
            // 请求头部信息通过app.getRequestHeader()方法获取
            header: app.getRequestHeader(),
            // 请求成功后,会将返回的数据保存在resp变量中。
            success: function (res) {
                var resp = res.data;
                // 如果返回的code不等于200,会通过app.alert方法弹出一个提示框显示返回的错误信息,并结束函数的执行。
                if (resp.code != 200) {
                    app.alert({"content": resp.msg});
                    return;
                }
                // 如果返回的code等于200,会将返回的banner_list和cat_list数据分别保存在banners和categories变量中,
                that.setData({
                    banners: resp.data.banner_list,
                    categories: resp.data.cat_list
                });
                // 并调用getFoodList方法
                that.getFoodList();
            }
        });
    },
    // 这段代码是一个小程序中的一个函数,名为catClick。它的作用是在点击某个分类时,根据点击的分类id更新数据,并调用getFoodList函数获取对应分类的商品列表。
    catClick: function (e) {
        this.setData({
            // 通过e.currentTarget.id获取点击的分类id。
            activeCategoryId: e.currentTarget.id
        });
        // 使用setData方法更新数据,将activeCategoryId设置为点击的分类id。
        this.setData({
            // 将loadingMoreHidden设置为true,p设置为1(表示当前页数为1),goods设置为空数组(清空商品列表)。
            loadingMoreHidden: true,
            p:1,
            goods:[]
        });
        // 调用getFoodList函数获取对应分类的商品列表。
        this.getFoodList();
    },
    onReachBottom: function () {
        var that = this;
        setTimeout(function () {
            that.getFoodList();
        }, 500);
    },
    // 通过发送请求获取食品列表,并将获取到的数据更新到页面上。
    getFoodList: function () {
        var that = this;
        // 首先,函数会检查是否正在处理其他请求,如果是,则直接返回,避免重复请求。
        if( that.data.processing ){
            return;
        }
        // 接着,函数会检查是否还有更多数据需要加载,如果没有,则直接返回。
        if( !that.data.loadingMoreHidden ){
            return;
        }
        // 然后,函数会将processing标志设置为true,表示正在处理请求。
        that.setData({
            processing:true
        });
        // 接下来,函数会发送一个请求到服务器,请求的URL是"/food/search",并且会带上一些参数,
        // 如cat_id(食品分类ID)、mix_kw(搜索关键词)、p(页码)等。
        wx.request({
            url: app.buildUrl("/food/search"),
            header: app.getRequestHeader(),
            data: {
                cat_id: that.data.activeCategoryId,
                mix_kw: that.data.searchInput,
                p: that.data.p,
            },
            // 当服务器返回响应时,函数会判断响应的状态码是否为200,如果不是,则弹出一个提示框显示错误信息,并返回。
            success: function (res) {
                var resp = res.data;
                if (resp.code != 200) {
                    app.alert({"content": resp.msg});
                    return;
                }
                // 如果响应的状态码为200,则从响应数据中获取到食品列表,并将其与之前已有的食品列表进行合并。
                var goods = resp.data.list;
                that.setData({
                    goods: that.data.goods.concat( goods ),
                    p: that.data.p + 1,
                    //最后,函数会更新页面上的数据,包括goods(食品列表)、p(页码)和processing(处理状态),
                    // 并将processing标志设置为false,表示请求处理完成。
                    processing:false
                });
                // 判断变量resp.data.has_more的值是否为0。如果resp.data.has_more的值为0,
                // 则执行setData方法,将loadingMoreHidden属性设置为false。
                if( resp.data.has_more == 0 ){
                    that.setData({
                        loadingMoreHidden: false
                    });
                }

            }
        });
    }
});

那接下来,就去flask服务器端看看/food/search路由是什么情况,图片传参是怎么传的。

web/controllers/api/Food.py

python 复制代码
@route_api.route("/food/search" )
def foodSearch():
    resp = {'code': 200, 'msg': '操作成功~', 'data': {}}
    req = request.values
    cat_id = int( req['cat_id'] ) if 'cat_id' in req else 0
    mix_kw = str(req['mix_kw']) if 'mix_kw' in req else ''
    p = int( req['p'] ) if 'p' in req else 1

    if p < 1:
        p = 1

    page_size = 10
    offset = ( p - 1 ) * page_size
    query = Food.query.filter_by(status=1 )
    if cat_id > 0:
        query = query.filter_by(cat_id = cat_id)

    if mix_kw:
        rule = or_(Food.name.ilike("%{0}%".format(mix_kw)), Food.tags.ilike("%{0}%".format(mix_kw)))
        query = query.filter(rule)

    food_list = query.order_by(Food.total_count.desc(), Food.id.desc())\
        .offset( offset ).limit( page_size ).all()

    data_food_list = []
    if food_list:
        for item in food_list:
            tmp_data = {
                'id': item.id,
                'name': "%s"%( item.name ),
                'price': str( item.price ),
                'min_price':str( item.price ),
                'pic_url': UrlManager.buildImageUrl(item.main_image)
            }
            data_food_list.append(tmp_data)
    resp['data']['list'] = data_food_list
    resp['data']['has_more'] = 0 if len( data_food_list ) < page_size else 1
    return jsonify(resp)

common/libs/UrlManager.py

python 复制代码
# -*- coding: utf-8 -*-
import time
from app import app
class UrlManager(object):
    def __init__(self):
        pass
 
    @staticmethod
    def buildImageUrl( path ):
        app_config = app.config['APP']
        url = app_config['domain'] + app.config['UPLOAD']['prefix_url'] + path
        return url
相关推荐
Nu11PointerException2 小时前
JAVA笔记 | ResponseBodyEmitter等异步流式接口快速学习
笔记·学习
@小博的博客5 小时前
C++初阶学习第十弹——深入讲解vector的迭代器失效
数据结构·c++·学习
南宫生6 小时前
贪心算法习题其四【力扣】【算法学习day.21】
学习·算法·leetcode·链表·贪心算法
懒惰才能让科技进步7 小时前
从零学习大模型(十二)-----基于梯度的重要性剪枝(Gradient-based Pruning)
人工智能·深度学习·学习·算法·chatgpt·transformer·剪枝
love_and_hope7 小时前
Pytorch学习--神经网络--搭建小实战(手撕CIFAR 10 model structure)和 Sequential 的使用
人工智能·pytorch·python·深度学习·学习
Chef_Chen7 小时前
从0开始学习机器学习--Day14--如何优化神经网络的代价函数
神经网络·学习·机器学习
芊寻(嵌入式)7 小时前
C转C++学习笔记--基础知识摘录总结
开发语言·c++·笔记·学习
hong1616888 小时前
跨模态对齐与跨领域学习
学习
阿伟来咯~8 小时前
记录学习react的一些内容
javascript·学习·react.js
Suckerbin9 小时前
Hms?: 1渗透测试
学习·安全·网络安全