dash + fac + fuc 相关笔记
安装
dash 官网跳转
pip install dash
组件库 文档跳转
pip install dash feffery-antd-components -U
工具库 文档跳转
pip install feffery-utils-components -U
样式工具
pip install feffery-dash-utils
模块引入
import dash # dash应用核心 from dash import html # dash自带的原生html组件库 import feffery_antd_components as fac # fac 通用组件库 import feffery_utils_components as fuc # fuc 通用工具库 from dash.dependencies import Input, Output, State, ALL, MATCH, ClientsideFunction # 用于构建应用交互功能的不同角色 from feffery_dash_utils.style_utils import style # 样式工具库
实例化
import dash from dash import html app = dash.Dash(__name__, title="测试") app.layout = html.Div("测试1") if __name__ == '__main__': app.run(debug=True)
可用的参数
title 页面标题
suppress_callback_exceptions=True 避免未出现的标签的回调报错, 进行忽略, 多级动态页面的时候很多标签不是一开始就存在, 因此在校验回调函数的时候会有报错
layout 定义
只能存在一个且必须存在, 后者覆盖前者
# 单个标签 app.layout = html.Div("测试1") # 多个标签 app.layout = [html.Div("测试1"), html.Div("测试2")] # 动态内容 def make_time_div(): return html.Div(time.time()) app.layout = make_time_div # 简写 app.layout = lambda: html.Div(time.time())
布局排列
排列
fac.AntdSpace 排列, 可水平, 可竖直 direction="vertical"
居中
fac.AntdCenter 居中, 默认基于元素最大宽度, 可设置基于父元素 style={"width": "100%"}
行
fac.AntdRow 按照24个单元长度定义, gutter 设置间距, 传两个就分别横向和纵向
列
fac.AntdCol span=4 设置宽度, 一行最多24 超过自动换行, 子元素block=True 可以撑满父元素
样式 - 默认方式
style={ "background": "#bae7ff", # 背景色 "width": "100%", # 宽度 "height": 300, # 高度 "padding": 30, # 内边距 格式: 数字/字符串 如: "30px 50px" 上下 左右 "30px 40px 50px 60px" 上右下左 "margin": 50, # 外边距 "position": "relation", # 布局类型 absolute 绝对(默认) relation 相对(父) fixed 固定 "left": 50, # 绝对布局定位使用, left/right/top/bottom 可正可负 "zIndex": 10, # z 轴高度, 数越大越靠上 }
样式 - 工具方式
# 使用feffery-dash-utils库,可以不用使用键值对的方式设置style from feffery_dash_utils.style_utils import style # 样式工具库导入 # 属性会有提示, 如果属性没有时可以使用字典拆包的方式,**{'margin':'100px'} style=style(padding=10, background="red", fontSize=200)
全局样式
通过 className 指定类名. 然后在项目路径下创建 assets 文件夹, 里面的 .ccs 文件全局生效
回调函数
导入
from dash.dependencies import Input, Output, State
示例
# 输出写在前面, 输入写在后面 # 可以多个输出, 则返回也要多个, 按顺序传出, 也可以不输出, 如仅仅输入 unloaded 去识别用户关闭/刷新页面时, 不需要输出 # 可以跟多个输入, 多个输入则就需要多个参数, 按顺序入参, 输入必须至少写一个 # State会进行记录, 但是不会即时显现, 需要在 Input 的触发下才会显现 # prevent_initial_call 可以阻止初次执行, 避免页面加载就触发, 如果没有输出, 则可以忽略 @app.callback(Output("output-show", "children"), Output("output-show2", "children"), Input("input-button-1", "nClicks"), State("input-button-2", "nClicks"), prevent_initial_call=True) def update_output_show_children(n_1, n_2): n_1 = n_1 or 0 n_2 = n_2 or 0 # 全部不更新 if n_1 % 2: return dash.no_update # 不更新前一个 if n_1 == 3: return dash.no_update, f"总点击次数: {n_1 + n_2}" return [f"按钮1点击次数: {n_1}, 按钮2点击次数: {n_2}", f"总点击次数: {n_1 + n_2}"]
说明
callback 传入 Output 作为输出, 多个则按顺序 return 传出
可传入多个 Input 进行输入, 传入多个则逻辑函数需要相同数量参数, 按顺序入参
State 同样作为 入参, 按照顺序传入
Input 作为触发条件, 而 State 需要基于 Input 才可以触发
演示
结合上面示例, 按钮 1 点击后. 则后面的数字都会变化
但是 按钮 2 点击后, 后面数字未变化
但是 再次点击 按钮 1, 数字变化后, 可以看到 按钮 2 的点击是被记录下来的
只有 按钮 1 点击后才可以让 按钮 2 的操作显现
浏览器回调
部分场景下要求较高 , 需要使用原生的 js 的方式进行回调从而避免与服务器的请求导致的延迟
使用 app.clientside_callback 定义 js 的相关回调代码, 代码较为简单的可以直接字符串在第一个参数中传递, 后面还是传输出和输入
app.clientside_callback( "(nClick) => true", Output('my-div' 'children'), [Input('my-input', 'value'), Input('another-input', 'value')] )
如果较为复杂的 js 代码可以使用 js 文件定义后, 以文件的方式进行引入
from dash.dependencies import Input, Output, ClientsideFunction app.clientside_callback( ClientsideFunction('my_clientside_library', 'my_function'), Output('my-div' 'children'), [Input('my-input', 'value'), Input('another-input', 'value')] )
示例
使用 clientside_callback 选择 namespace 和 方法名即可, 定义的 js代码文件放在项目的 assets 文件夹下
set_props 更新属性
Output 作为回调定义的输出, 也可以在函数内使用 set_props 做同样的操作
示例
如下, 实现一个点击按钮同时输出一个信息提醒和更新显示点击次数
import time import dash # dash应用核心 from dash import html # dash自带的原生html组件库 import feffery_antd_components as fac # fac 通用组件库 import feffery_utils_components as fuc # fuc 通用工具库 from dash.dependencies import Input, Output, State, ALL, MATCH, ClientsideFunction # 用于构建应用交互功能的不同角色 from feffery_dash_utils.style_utils import style # 样式工具库 app = dash.Dash(__name__, title="测试系统") app.layout = html.Div( [ fac.Fragment(id="message"), fac.AntdSpace( [ fac.AntdButton("执行计算", id="cal", type="primary"), fac.AntdText(id="result") ] ), ], style=style(padding=50) ) # 1. 常规方式实现 # @app.callback( # [Output("message", "children"), # Output("result", "children")], # Input("cal", "nClicks"), # prevent_initial_call=True # ) # def cal_and_alert_message(n_click): # return fac.AntdMessage(content="执行成功", type="info"), f"第{n_click}次计算成果" # 1. set_props 方式实现 @app.callback( # Output 里面就不用写了, 可以直接写在具体下面的函数逻辑里面用 set_props Output("result", "children"), Input("cal", "nClicks"), prevent_initial_call=True ) def cal_and_alert_message(n_click): # 传入要更新的组件的 id, 以及要更新的属性 dash.set_props(component_id="message", props={"children": fac.AntdMessage(content="执行成功", type="info")}) # set_props 的更新不是执行完这行代码就更新了, 依旧是在return 之后才会更新 # 如果下面 time.sleep(3) 就 3s 后才可以看到效果 return f"第{n_click}次计算成果" if __name__ == '__main__': app.run(debug=True)
Patch 局部更新
导入
from dash import Patch
案例
在下面的案例中点击每次在原有的基础上添加一个元素, 这样需要将原始的信息用State 拿到后传回去
如果数据量很大的情况下频繁地拿取和回传原始信息回对性能造成压力
使用Patch 则可以对输出的对象直接进行追加, 不需要先拿过来在更新后传过去
这样只需要传过去要追加的信息即可
import time import dash # dash应用核心 from dash import html, Patch # dash自带的原生html组件库 import feffery_antd_components as fac # fac 通用组件库 import feffery_utils_components as fuc # fuc 通用工具库 from dash.dependencies import Input, Output, State, ALL, MATCH, ClientsideFunction # 用于构建应用交互功能的不同角色 from feffery_dash_utils.style_utils import style # 样式工具库 app = dash.Dash(__name__, title="测试系统") app.layout = html.Div( fac.AntdSpace([ fac.AntdButton("执行计算", id="add", type="primary"), fac.AntdSpace([], id="items", direction="vertical")], direction="vertical" ), style=style(padding=50) ) # 1. 传统方式, 定义 State 把老的元素拿出来之后进行追加更新 # 数据量大元素复杂的的情况下性能较差 # @app.callback( # Output("items", "children"), # Input("add", "nClicks"), # State("items", "children"), # prevent_initial_call=True # ) # def add_items(n_clicks, o_items): # return [*o_items, f"row {n_clicks}"] # 2. Patch, 不需要定义 State 拿到原始数据 # 只需要将当前要追加的信息进行处理即可 @app.callback( Output("items", "children"), Input("add", "nClicks"), prevent_initial_call=True ) def add_items(n_clicks): p = Patch() p.append(f"row {n_clicks}") return p if __name__ == '__main__': app.run(debug=True)
模式匹配
导入
from dash.dependencies import Input, Output, ALL, MATCH
案例
50个按钮, 想统计所有按钮的点击次数的加和, 以及让被点击的变色, 再点击就变回去, 同时悬浮当前的被点击次数
如果使用传统的方式那就要写50个Input了, 采用 ALL 可以一次性监控所有的复合条件的 Input 即可,
如果只想匹配某一个, 则设置 MATCH 即可, 于 ALL 的区别是只传入一个值, ALL 传入的是列表参数
id 采用字典模式定义, 用部分精准, 部分模糊的方式去匹配即可
import time import dash # dash应用核心 from dash import html, Patch # dash自带的原生html组件库 import feffery_antd_components as fac # fac 通用组件库 import feffery_utils_components as fuc # fuc 通用工具库 from dash.dependencies import Input, Output, State, ALL, MATCH, ClientsideFunction # 用于构建应用交互功能的不同角色 from feffery_dash_utils.style_utils import style # 样式工具库 app = dash.Dash(__name__, title="测试系统") app.layout = html.Div( fac.AntdSpace( [ fac.AntdSpace( [ fac.AntdTooltip( fac.AntdButton( f"按钮{i}", id={"type": "button", "index": i}, type="primary" ), title="nClick: 0", id={"type": "tooltip", "index": i}, ) # MATCH 的情况下, 需要让 id 使用字典模式 for i in range(10) ], wrap=True ), fac.AntdText(id="all-click-sum") ], direction="vertical", style=style(width="100%") ), style=style(padding=50) ) @app.callback( Output("all-click-sum", "children"), # 匹配基于想要匹配的属性调整为 ALL 即可 Input({"type": "button", "index": ALL}, "nClicks"), prevent_initial_call=True ) def show_all_click_sum(n): return f"共点击了 {sum([i for i in n if i])}" @app.callback( # 匹配基于想要匹配的属性调整为 MATCH 即可 Output({"type": "tooltip", "index": MATCH}, "title"), Output({"type": "button", "index": MATCH}, "danger"), Input({"type": "button", "index": MATCH}, "nClicks"), prevent_initial_call=True ) def button_show_tip_change_type(n_clicks): return f"nClicks: {n_clicks}", bool(n_clicks % 2) if __name__ == '__main__': app.run(debug=True)
running 参数
此参数可以作用于一些特殊耗时运算场景下的加载处理,如模态框, 抽屉等
如下面的实力, 一个回调用于马上打开模态框, 另一个回调用于计算模态框里面的数据
如果数据计算较长, 则会出现模态框打开后数据耗时2s后才刷新出现的情况
添加loading 的效果, 则需要基于running参数进行处理, 在计算未完成时设置 loading 为 True, 完成后设置为 False
- 在计算的回答函数装饰其中输入running=[(数组)];
- running的是一个列表,列表中要传入一个元组。
- 元组有3个参数,第一参数是('id':属性'),第二三个值,是当回调函数运行时要显示的值和运行完成要显示的值。running=[(Output("modal", "loading"), True, False),]
import time import dash # dash应用核心 from dash import html, Patch # dash自带的原生html组件库 import feffery_antd_components as fac # fac 通用组件库 import feffery_utils_components as fuc # fuc 通用工具库 from dash.dependencies import Input, Output, State, ALL, MATCH, ClientsideFunction # 用于构建应用交互功能的不同角色 from feffery_dash_utils.style_utils import style # 样式工具库 app = dash.Dash(__name__, title="测试系统") app.layout = html.Div( [ fac.AntdButton( "打开模态框", id="open-model", type="primary" ), fac.AntdModal( id="model", title="我是模态框", renderFooter=True ) ], style=style(padding=50) ) # 1. 打开对话框 @app.callback( Output("model", "visible"), Input("open-model", "nClicks"), prevent_initial_call=True ) def button_show_tip_change_type(n_clicks): return True # 2. 更新对话框里面的内容 @app.callback( Output("model", "children"), Input("open-model", "nClicks"), # 3. 添加 running 参数 running=[ (Output("model", "loading"), True, False) ], prevent_initial_call=True ) def button_show_tip_change_type(n_clicks): # 模拟耗时运算逻辑 time.sleep(2) return f"点击次数: {n_clicks}" if __name__ == '__main__': app.run(debug=True)
ctx上下文
常用的如下 inputs, inputs_list, outputs_list 和 triggered
import time import dash # dash应用核心 from dash import html, Patch # dash自带的原生html组件库 import feffery_antd_components as fac # fac 通用组件库 import feffery_utils_components as fuc # fuc 通用工具库 from dash.dependencies import Input, Output, State, ALL, MATCH, ClientsideFunction # 用于构建应用交互功能的不同角色 from feffery_dash_utils.style_utils import style # 样式工具库 app = dash.Dash(__name__, title="测试系统") app.layout = html.Div( [ fac.AntdSpace( [ fac.AntdButton("按钮1", id="b1", type="primary"), fac.AntdButton("按钮2", id="b2", type="primary"), fac.AntdInput(id="input", placeholder="请输入内容"), fac.AntdText(id="o1"), fac.AntdText(id="o2"), fac.AntdText(id="o3"), ] ) ], style=style(padding=50) ) @app.callback( Output("o1", "children"), Output("o2", "children"), Output("o3", "children"), Input("b1", "nClicks"), Input("b1", "nClicks"), Input("input", "value"), ) def show_out(n1, n2, v): # {'b1.nClicks': 1, 'input.value': None} print(dash.ctx.inputs) # 输入 # [{'id': 'b1', 'property': 'nClicks', 'value': 1}, # {'id': 'b1', 'property': 'nClicks', 'value': 1}, # {'id': 'input', 'property': 'value'}] print(dash.ctx.inputs_list) # 输入的另一个格式展示 # [{'id': 'o1', 'property': 'children'}, # {'id': 'o2', 'property': 'children'}, # {'id': 'o3', 'property': 'children'}] print(dash.ctx.outputs_list) # 输出 # [{'prop_id': 'b1.nClicks', 'value': 1}] print(dash.ctx.triggered) # 触发 return n1, n2, v if __name__ == '__main__': app.run(debug=True)
重复 Output
部分场景下存在对多个输入对应一个输出的场景
默认的情况下是不允许多个输入对应同一个输出,不然会彼此冲突
import time import dash # dash应用核心 from dash import html, Patch # dash自带的原生html组件库 import feffery_antd_components as fac # fac 通用组件库 import feffery_utils_components as fuc # fuc 通用工具库 from dash.dependencies import Input, Output, State, ALL, MATCH, ClientsideFunction # 用于构建应用交互功能的不同角色 from feffery_dash_utils.style_utils import style # 样式工具库 app = dash.Dash(__name__, title="测试系统") app.layout = html.Div( [ fac.AntdSpace( [ fac.AntdButton("按钮1", id="b1", type="primary"), fac.AntdButton("按钮2", id="b2", type="primary"), fac.AntdModal(id="model", title="我是模态框", renderFooter=True), ] ) ], style=style(padding=50) ) # # 1. 两个按钮都可以触发的情况下分两个触发回调去执行 # @app.callback( # Output("model", "visible"), # Output("model", "children"), # Input("b1", "nClicks"), # prevent_initial_call=True # ) # def show_out(n): # return True, "我是按钮1触发的" # # # 1.1 第二个触发的回调里面设置 allow_duplicate=True 可允许重复输入覆盖 # @app.callback( # Output("model", "visible", allow_duplicate=True), # Output("model", "children", allow_duplicate=True), # Input("b2", "nClicks"), # prevent_initial_call=True # ) # def show_out(n): # return True, "我是按钮2触发的" # 2. 也可以合并在一起, 如果可以合并的话 @app.callback( Output("model", "visible", allow_duplicate=True), Output("model", "children", allow_duplicate=True), Input("b1", "nClicks"), Input("b2", "nClicks"), prevent_initial_call=True ) def show_out(n1, n2): print(dash.ctx.triggered_id) return True, "我是按钮1触发的" if dash.ctx.triggered_id == "b1" else "我是按钮2触发的" if __name__ == '__main__': app.run(debug=True)
轮训任务, 定时任务
轮训任务
导入
from dash import dcc
定义
dcc.Interval( id="interval", interval=1000, # 1000ms 周期 )
每次执行触发以 n_intervals 作为输入参数表示执行次数
定时任务
导入
import feffery_antd_components as fac
定义
fuc.FefferyTimeout(id="timeout")
参数
delay 数字 如:3000 ms单位
每次执行后以 timeoutCount 作为输入参数表示执行次数
实例
import time import random import dash # dash应用核心 from dash import html, dcc, Patch # dash自带的原生html组件库 import feffery_antd_components as fac # fac 通用组件库 import feffery_utils_components as fuc # fuc 通用工具库 from dash.dependencies import Input, Output, State, ALL, MATCH, ClientsideFunction # 用于构建应用交互功能的不同角色 from feffery_dash_utils.style_utils import style # 样式工具库 app = dash.Dash(__name__, title="测试系统") app.layout = html.Div( [ fac.AntdTabs( items=[ # 轮训任务的选项 { "label": "轮训任务", "key": "轮训任务", "children": html.Div( [ # 轮训相关的组件 dcc.Interval( id="interval", interval=1000, # 1000ms 周期 ), fac.AntdStatistic( id="i-out", precision=2, title="实时变动的某个数值", value=123.45, valueStyle={"color": "#cf1322"}, prefix=fac.AntdIcon(icon="antd-arrow-up") ) ] ) }, # 定时任务的选项 { "label": "定时任务", "key": "定时任务", "children": html.Div( [ # 定时相关的组件 fuc.FefferyTimeout(id="timeout"), fac.AntdButton( "3s 后弹出通知", id="notice-button", type="primary" ), fac.Fragment(id="notice") ] ) }, ] ) ], style=style(padding=50) ) # 轮训任务, 每秒进行执行一次 @app.callback( Output("i-out", "value"), Output("i-out", "valueStyle"), Output("i-out", "prefix"), Input("interval", "n_intervals"), State("i-out", "value"), prevent_initial_call=True ) def show_out(n_intervals, v): new_v = random.uniform(-1, 1) + v if new_v > v: return new_v, {"color": "#cf1322"}, fac.AntdIcon(icon="antd-arrow-up") return new_v, {"color": "#3f8600"}, fac.AntdIcon(icon="antd-arrow-down") # 定时任务, 点击按钮新建定时任务, 按钮禁用 @app.callback( Output("timeout", "delay"), Output("notice-button", "disabled"), Input("notice-button", "nClicks"), prevent_initial_call=True ) def show_out(n): return 3 * 1000, True # 定时任务执行, 发起通知, 更新按钮启用, @app.callback( Output("notice", "children"), Output("notice-button", "disabled", allow_duplicate=True), Input("timeout", "timeoutCount"), prevent_initial_call=True ) def show_out(tc): return fac.AntdNotification( message="我通知了", description=f"对应的timeoutCount: {tc}", type="info" ), False if __name__ == '__main__': app.run(debug=True)
客户端数据缓存
导入和使用
from dash import dcc # 默认内存缓存 dcc.Store(id="m-data"), # Session 缓存 dcc.Store(id="s-data", storage_type="session"), # Local内存缓存 dcc.Store(id="l-data", storage_type="local"),
- 内存类型, 刷新后会消失
- session 类型刷新后不会消失, 但是关闭后会消失
- local 刷新, 关闭都不会消失
完整示例
import time import random import dash # dash应用核心 from dash import html, dcc, Patch # dash自带的原生html组件库 import feffery_antd_components as fac # fac 通用组件库 import feffery_utils_components as fuc # fuc 通用工具库 from dash.dependencies import Input, Output, State, ALL, MATCH, ClientsideFunction # 用于构建应用交互功能的不同角色 from feffery_dash_utils.style_utils import style # 样式工具库 app = dash.Dash(__name__, title="测试系统") app.layout = html.Div( [ # 空节点, 不会展示出来, 适合放 store, timeout 之类的 fac.Fragment( [ # 默认内存缓存 dcc.Store(id="m-data"), # Session 缓存 dcc.Store(id="s-data", storage_type="session"), # Local内存缓存 dcc.Store(id="l-data", storage_type="local"), ] ), fac.AntdSpace( [ fac.AntdSpace( [ fac.AntdButton("内存缓存赋值", id="m-set"), fac.AntdButton("session缓存赋值", id="s-set"), fac.AntdButton("local缓存赋值", id="l-set"), ], ), fac.AntdSpace( [ fac.AntdText(id="m-show"), fac.AntdText(id="s-show"), fac.AntdText(id="l-show"), ], id="store-show", direction="vertical" ) ], direction="vertical" ), ], style=style(padding=50) ) @app.callback( Output("m-data", "data"), Input("m-set", "nClicks"), prevent_initial_call=True, ) def store_memory_set_data(n): return f"内存型缓存{n}" @app.callback( Output("s-data", "data"), Input("s-set", "nClicks"), prevent_initial_call=True, ) def store_session_set_data(n): return f"session型缓存{n}" @app.callback( Output("l-data", "data"), Input("l-set", "nClicks"), prevent_initial_call=True, ) def store_local_set_data(n): return f"local型缓存{n}" @app.callback( Output("m-show", "children"), Output("s-show", "children"), Output("l-show", "children"), Input("m-data", "data"), Input("s-data", "data"), Input("l-data", "data"), ) def update_value(*args): return args if __name__ == '__main__': app.run(debug=True)
多页面应用
导入定义
from dash import dcc dcc.Location(id="url")
属性说明
id 描述:这是一个必需的属性,用于在 Dash 应用中唯一标识 dcc.Location 组件。在定义回调函数时,会使用这个 id 来指定输入或输出的组件 示例:dcc.Location(id='url - location')
refresh 描述:布尔值。当设置为 True 时,每次 URL 发生改变都会导致整个页面刷新;当设置为 False(默认值)时,页面不会自动刷新
构建单页应用时非常有用,可以在不刷新整个页面的情况下更新页面内容,从而提供更流畅的用户体验。 示例:dcc.Location(id='my - location', refresh = False)
pathname 描述:这是一个表示当前 URL 路径部分的属性
例如,对于 URL https://example.com/page1,pathname 的值就是 /page1
在 Dash 应用中,可以通过回调函数监听 pathname 的变化来根据不同的页面路径显示不同的内容。
search 描述:它表示 URL 中的查询字符串部分
例如,对于 URL https://example.com/page1?param1=value1¶m2=value2
search 的值就是 ?param1=value1¶m2=value2
可以在 Dash 应用中使用这个属性来获取 URL 中的查询参数并进行相应的处理
hash 描述:表示 URL 中的哈希部分(即 # 后面的部分)
例如,对于 URL https://example.com/page1#section2
hash 的值就是 #section2
虽然在现代 Web 应用中哈希部分的使用相对较少,但在某些情况下,例如用于页面内导航或者标记特定的页面状态时,这个属性仍然可能有用。
代码实例
import time import random import dash # dash应用核心 from dash import html, dcc, Patch # dash自带的原生html组件库 import feffery_antd_components as fac # fac 通用组件库 import feffery_utils_components as fuc # fuc 通用工具库 from dash.dependencies import Input, Output, State, ALL, MATCH, ClientsideFunction # 用于构建应用交互功能的不同角色 from feffery_dash_utils.style_utils import style # 样式工具库 app = dash.Dash(__name__, title="测试系统") app.layout = html.Div( [ dcc.Location(id="url"), # 页眉 fac.AntdCenter( [ fac.AntdMenu( id="menu", menuItems=[ { "component": "Item", "props": {"key": "index", "title": "首页", "href": "/"}, }, { "component": "Item", "props": {"key": "part1", "title": "页面1", "href": "/part1"}, }, { "component": "Item", "props": {"key": "part2", "title": "页面2", "href": "/part2"}, } ], mode="horizontal", defaultSelectedKey="index", style=style(width="100%") ) ], style=style( height=64, background="white", boxShadow="rgba(0,0,0,0.03) 0px 1px 2px 0px, " "rgba(0,0,0,0.02) 0px 1px 6px -1px, " "rgba(0,0,0,0.02) 0px 2px 4px 0px") ), # 内容容器 html.Div(id="content-container", style=style(padding=24)) ], style=style(minHeight="100vh", background="#edf2fa") ) @app.callback(Output("content-container", "children"), Input("url", "pathname")) def router(pathname): if pathname == "/": return "首页" elif pathname == "/part1": return "页面1" elif pathname == "/part2": return "页面2" return "404" if __name__ == '__main__': app.run(debug=True)
Cookie 相关处理
用 flask 的 request 中进行获取即可
import time import random import dash # dash应用核心 from flask import request from dash import html, dcc, Patch # dash自带的原生html组件库 import feffery_antd_components as fac # fac 通用组件库 import feffery_utils_components as fuc # fuc 通用工具库 from dash.dependencies import Input, Output, State, ALL, MATCH, ClientsideFunction # 用于构建应用交互功能的不同角色 from feffery_dash_utils.style_utils import style # 样式工具库 from urllib.parse import unquote app = dash.Dash(__name__, title="测试系统") app.layout = html.Div( [ fac.AntdButton("点击添加 cookie", id="b1", type="primary"), fuc.FefferyCookie(cookieKey="test-cookie", value="我是cibo") ], style=style(padding=50) ) @app.callback(Input("b1", "nClicks")) def router(n): print(request.cookies) print(request.cookies.get("test-cookie")) print(unquote(request.cookies.get("test-cookie"))) if __name__ == '__main__': app.run(debug=True)
本文来自博客园,作者:羊驼之歌,转载请注明原文链接:https://www.cnblogs.com/shijieli/p/18591314
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?