当前位置: 首页 > news >正文

web3 React Dapp书写订单 买入/取消操作

好 上文web3 前端dapp从redux过滤出 (我创建与别人创建)正在执行的订单 并展示在Table上中 我们过滤出了 我创建的 与 别人创建的 且 未完成 未取消的订单数据
这边 我们起一下 ganache 环境

ganache -d

在这里插入图片描述
然后 我们项目 发布一下智能合约

truffle migrate --reset

在这里插入图片描述
然后 登录一下 MetaMask
在这里插入图片描述
在 运行一下测试脚本

truffle exec .\scripts\test.js

然后 打开我们的项目 在根目录下的 scripts 目录中 创建一个文件 我这里叫 createOrder.js
编写代码如下

//指定以token grtoken合约
const GrToken = artifacts.require("grToken.sol")
//交易所合约
const Exchange = artifacts.require("Exchange.sol")
//定义E代理地址
const ETHER_ADDRESS = '0x0000000000000000000000000000000000000000';const toWei = (bn) => {return web3.utils.toWei(bn.toString(), "ether");
}module.exports = async function(callback) {const grTokenDai = await GrToken.deployed();const exchage = await Exchange.deployed();//获取用户列表const accounts = await web3.eth.getAccounts();//循环用 accounts 用户列表中第一个用户创建 五个订单for (let i = 1; i <= 5; i++) {await exchage.makeOrder(grTokenDai.address,toWei(101), ETHER_ADDRESS ,toWei(0.01),{from: accounts[0]});}//循环用 accounts 用户列表中第二个用户创建 五个订单for (let i = 1; i <= 5; i++) {await exchage.makeOrder(grTokenDai.address,toWei(101), ETHER_ADDRESS ,toWei(0.01),{from: accounts[1]});}callback()
}

这里 我们直接脚本执行 第一和第二个用户 分别创建出 五个订单 方便 我们后期操作
然后 我们终端运行

truffle exec .\scripts\createOrder.js

在这里插入图片描述
然后 启动我们的dapp
这里 我们第一个用户 已经可用看到非常多订单信息了
在这里插入图片描述
然后 我们 MetaMask 切换一下当前账户
在这里插入图片描述
我们切换成第二个用户
然后刷新dapp
在这里插入图片描述
也是能看到自己的订单和第一个用户创建的订单

然后 我们将 src目录下的 components 下的 Order.jsx 组件代码更改如下

import React from 'react';
import { Card, Col, Row ,Table,Button } from 'antd';
import {useSelector} from "react-redux"
import moment from "moment"function converTime(t){return moment(t*1000).format("YYYY/MM/DD")
}function convert(unit) {return window.WebData ? unit&&window.WebData.web3.utils.fromWei(unit, "ether") : ""
}function getRenderOrder(order,type) {if(!window.WebData) {return []}const account = window.WebData.account//收集起所有 已完成 或 已取消的数据idlet filterIds = [...order.Cancelorders,...order.Fillorders].map(item=>item.id)let makeorders = order.Allorders.filter(item=> !filterIds.includes(item.id))if (type === 1) {return makeorders.filter(item=>item.user === account)} else {return makeorders.filter(item=>item.user !== account)}
}export default function Order() {const order = useSelector(state => state.order)const columns = [{title: 'ETH',dataIndex: 'amountGive',render:(amountGive)=><b>{ convert(amountGive) }</b>,key: 'amountGive'},{title: 'GrToken',dataIndex: 'amountGet',render:(amountGet)=><b>{ convert(amountGet) }</b>,key: 'amountGet'},{title: '创建时间',dataIndex: 'timestamp',render:(timestamp)=><div>{ converTime(timestamp) }</div>,key: 'timestamp'},];const columns1 = [...columns,{title: '操作',render:(item)=><Button type = "text">取消</Button>}]const columns2 = [...columns,{title: '操作',render:(item)=><Button type = "text">买入</Button>}]return (<div style = {{marginTop:'10px'}}><Row><Col span={8}><Card title="已完成" bordered={false} style = {{ margin: '10px' }}><Table dataSource={order.Fillorders} columns={columns} rowKey={item=> item.id}/></Card></Col><Col span={8}><Card title="我创建的" bordered={false} style = {{ margin: '10px' }}><Table dataSource={getRenderOrder(order,1)} columns={columns1} rowKey={item=> item.id}/></Card></Col><Col span={8}><Card title="其他交易中订单" bordered={false} style = {{ margin: '10px' }}><Table dataSource={getRenderOrder(order,2)} columns={columns2} rowKey={item=> item.id}/></Card></Col></Row></div>);
}

这里 我们引入了 Button 按钮
然后 重新加了 两个 表头数据 columns1 和 columns2
他们都合并了 columns 原本的数据结果 然后多加了一列 叫操作 对应一个Button按钮
我创建的 叫取消
另一个叫 买入 买入别人创建的订单

然后 这里 我们先找到 antd 文档中的 对话框
在这里插入图片描述
首先 这里 我们需要 从react中引入 useState 然后从antd中 引入 Modal对话框组件
在这里插入图片描述
然后 定义一下 对话框开关 和当前操作的订单id 以及逻辑函数

//控制对话框的 布尔值
const [isModalOpen, setIsModalOpen] = useState(false);
//记录当前正在操作的订单id
const [currentId, setCurrentId] = useState(null);//点击取消订单时触发
const triggerCancellation = (id) => {setIsModalOpen(true);setCurrentId(id);
}
//对话框点击 确定 时触发
const handleOk = () => {setIsModalOpen(false);
};
//取消 或 关闭 对话框时触发
const handleCancel = () => {setIsModalOpen(false);
};

在这里插入图片描述
然后 在元素中写出这个Modal对话框组件
在这里插入图片描述
最后 在取消订单的按钮 绑定上 onClick 开启对话框函数
在这里插入图片描述
item.id 表示 我们调用函数时 将当前订单的id 传进来
然后 我们运行项目 点击取消订单
对话框 就弹出来了
在这里插入图片描述
至于取消订单的具体逻辑 我们直接来看交易所代码 我们之前写了个cancelorder函数 用来取消订单 它只需要一个参数 订单的id 然后其他的具体逻辑 我们会自己调事件的
在这里插入图片描述
这里 我们先换回第一个账号吧
在这里插入图片描述
然后 我们将刚才在 src下 components 下的 Order.jsx中 的 handleOk编写代码如下

//对话框点击 确定 时触发const handleOk = () => {const {account,Exchange} = window.WebData;Exchange.methods.cancelorder(currentId).send({from: account})setIsModalOpen(false);};

这里 我们函数也写了注释了 他是只有用户点击确认之后才触发的 就表示 用户已经确定 要取消这个订单了
然后 我们通过我们存在window上的 WebData对象 拿到 交易所智能合约Exchange对象 和 account当前登录用户
然后通过Exchange 调用我们自己写的 取消订单 cancelorder函数 传入 我们之前存起来的 当前订单id currentId 然后 指定 send 因为 我们这个操作是要上链的
然后 我们传入当前用户为from 字段
然后 我们运行代码 点击取消订单
在这里插入图片描述
然后点击确定
在这里插入图片描述
然后 页面右侧 就会弹出这个操作提示按钮 因为这设计到了 燃料操作
在这里插入图片描述
我们直接点击确认
在这里插入图片描述
一路确认 最后完成之后 我们的数据并不会自动更新 因为我们没有订阅 但是 当你手动刷新界面 会发现 我们取消的那条 3ETH 的订单就没有了 因为已经被取消掉了
在这里插入图片描述
然后 我们也可以看MetaMask下面这个活动 会将你取消订单的动作记录下来
在这里插入图片描述
这样 就确认了 我们取消订单的功能 确实是好用的 然后 我们来看买入
我们先加上 逻辑层的一些控制对话框代码

//控制买入弹出开启
const [buy, setBuy] = useState(false);
//取消 或 关闭 对话框时触发
const buyCancel = () => {setBuy(false);
};
//对话框点击 确定 时触发
const buyleOk = () => {setIsModalOpen(false);
};
//点击买入订单时触发
const startBuying = (id) => {setBuy(true);setCurrentId(id);
}

在这里插入图片描述
然后 我们在元素层 加上 买入确定的对话框
在这里插入图片描述
这样 我们点击买入 提示弹窗就出来了
在这里插入图片描述
然后 我们交易所中 也写了一个 fillorder 函数 他也是 只需要一个参数id
通过id完成订单买入
在这里插入图片描述
这样 我们直接将 刚才写的 buyleOk 函数 改成这样就好了

//对话框点击 确定 时触发
const buyleOk = () => {const {account,Exchange} = window.WebData;Exchange.methods.fillorder(currentId).send({from: account})setBuy(false);
};

逻辑还是跟取消订单差不多 用户确定之后 从我们挂在 window上的WebData 对象中 结构出 当前用户和交易所合约对象
然后 我们通过交易所对象 调用fillorder函数 传入当前操作订单的id
他也会改变链上结构 要用send
当前用户为from字段

然后 我们运行代码
然后 我们记好 自己在交易所 ETH的数量 因为我们的grtoken存在燃料的概念 所以 可能有点额外扣除 我们就看ETH
然后 我们点击买入
在这里插入图片描述
然后我们选择确定
在这里插入图片描述
然后 界面右侧 会弹出操作提示 这里 我们点击确定
在这里插入图片描述
因为没有订阅 所以 我们界面并不会自动更新 但我们刷新界面 我们看三个点
当前用户 在交易所的 ETH 加了 0.01 然后 我们完成的订单多了一条 别人的订单 少了一条 还有就是 在交易所的 grToken 减少了
这就说明 我们操作成功了
在这里插入图片描述
最后 我们订单组件的代码是这样

import React, { useState } from 'react';import { Card, Col, Row ,Table,Button, Modal } from 'antd';
import {useSelector} from "react-redux"
import moment from "moment"function converTime(t){return moment(t*1000).format("YYYY/MM/DD")
}function convert(unit) {return window.WebData ? unit&&window.WebData.web3.utils.fromWei(unit, "ether") : ""
}function getRenderOrder(order,type) {if(!window.WebData) {return []}const account = window.WebData.account//收集起所有 已完成 或 已取消的数据idlet filterIds = [...order.Cancelorders,...order.Fillorders].map(item=>item.id)let makeorders = order.Allorders.filter(item=> !filterIds.includes(item.id))if (type === 1) {return makeorders.filter(item=>item.user === account)} else {return makeorders.filter(item=>item.user !== account)}
}export default function Order() {//控制对话框的 布尔值const [isModalOpen, setIsModalOpen] = useState(false);//记录当前正在操作的订单idconst [currentId, setCurrentId] = useState(null);//点击取消订单时触发const triggerCancellation = (id) => {setIsModalOpen(true);setCurrentId(id);}//对话框点击 确定 时触发const handleOk = () => {const {account,Exchange} = window.WebData;Exchange.methods.cancelorder(currentId).send({from: account})setIsModalOpen(false);};//取消 或 关闭 对话框时触发const handleCancel = () => {setIsModalOpen(false);};//控制买入弹出开启const [buy, setBuy] = useState(false);//取消 或 关闭 对话框时触发const buyCancel = () => {setBuy(false);};//对话框点击 确定 时触发const buyleOk = () => {const {account,Exchange} = window.WebData;Exchange.methods.fillorder(currentId).send({from: account})setBuy(false);};//点击买入订单时触发const startBuying = (id) => {setBuy(true);setCurrentId(id);}const order = useSelector(state => state.order)const columns = [{title: 'ETH',dataIndex: 'amountGive',render:(amountGive)=><b>{ convert(amountGive) }</b>,key: 'amountGive'},{title: 'GrToken',dataIndex: 'amountGet',render:(amountGet)=><b>{ convert(amountGet) }</b>,key: 'amountGet'},{title: '创建时间',dataIndex: 'timestamp',render:(timestamp)=><div>{ converTime(timestamp) }</div>,key: 'timestamp'},];const columns1 = [...columns,{title: '操作',render:(item)=><Button type = "text" onClick={()=>{triggerCancellation(item.id)}}>取消</Button>}]const columns2 = [...columns,{title: '操作',render:(item)=><Button type = "text" onClick={()=>{startBuying(item.id)}}>买入</Button>}]return (<div style = {{marginTop:'10px'}}><Row><Col span={8}><Card title="已完成" bordered={false} style = {{ margin: '10px' }}><Table dataSource={order.Fillorders} columns={columns} rowKey={item=> item.id}/></Card></Col><Col span={8}><Card title="我创建的" bordered={false} style = {{ margin: '10px' }}><Table dataSource={getRenderOrder(order,1)} columns={columns1} rowKey={item=> item.id}/></Card></Col><Col span={8}><Card title="其他交易中订单" bordered={false} style = {{ margin: '10px' }}><Table dataSource={getRenderOrder(order,2)} columns={columns2} rowKey={item=> item.id}/></Card></Col></Row><Modaltitle="操作提示"open={isModalOpen}okText="确定"cancelText="取消"onOk={handleOk}onCancel={handleCancel}><p>您确定要取消当前订单吗?</p></Modal><Modaltitle="操作提示"open={buy}okText="确定"cancelText="取消"onOk={buyleOk}onCancel={buyCancel}><p>您确认要买入当前订单吗?</p></Modal></div>);
}

但是 目前体验比较差 因为我们操作完成 不会自动更新 需要手动刷新界面数据才会更新
因为 我们需要对这些事件进行订阅
那么 我们下文继续

相关文章:

web3 React Dapp书写订单 买入/取消操作

好 上文web3 前端dapp从redux过滤出 (我创建与别人创建&#xff09;正在执行的订单 并展示在Table上中 我们过滤出了 我创建的 与 别人创建的 且 未完成 未取消的订单数据 这边 我们起一下 ganache 环境 ganache -d然后 我们项目 发布一下智能合约 truffle migrate --reset然…...

C++学习---信号处理机制、中断、异步环境

文章目录 前言信号处理signal()函数关于异步环境 信号处理函数示例raise()函数 前言 信号处理 关于信号&#xff0c;信号是一种进程间通信的机制&#xff0c;用于在程序执行过程中通知进程发生了一些事件。在Unix和类Unix系统中&#xff0c;信号是一种异步通知机制&#xff0c…...

机器学习——奇异值分解案例(图片压缩-代码简洁版)

本想大迈步进入前馈神经网络 但是…唉…瞅了几眼&#xff0c;头晕 然后想到之前梳理的奇异值分解、主成分分析、CBOW都没有实战 如果没有实际操作&#xff0c;会有一种浮在云端的虚无感 但是如果要实际操作&#xff0c;我又不想直接调用库包 可是…如果不直接调包&#xff0c;感…...

【Go入门】面向对象

【Go入门】面向对象 前面两章我们介绍了函数和struct&#xff0c;那你是否想过函数当作struct的字段一样来处理呢&#xff1f;今天我们就讲解一下函数的另一种形态&#xff0c;带有接收者的函数&#xff0c;我们称为method method 现在假设有这么一个场景&#xff0c;你定义…...

Asp.Net Core 中使用配置文件

本文参考微软文档&#xff1a;ASP.NET Core 中的配置 ASP.NET Core 中的应用程序配置是使用一个或多个配置程序提供程序执行的。 配置提供程序使用各种配置源从键值对读取配置数据&#xff1a; 设置文件&#xff0c;例如 appsettings.json环境变量Azure Key VaultAzure 应用配…...

深入理解JVM虚拟机第二十四篇:详解JVM当中的动态链接和常量池的作用

大神链接&#xff1a;作者有幸结识技术大神孙哥为好友&#xff0c;获益匪浅。现在把孙哥视频分享给大家。 孙哥链接&#xff1a;孙哥个人主页 作者简介&#xff1a;一个颜值99分&#xff0c;只比孙哥差一点的程序员 本专栏简介&#xff1a;话不多说&#xff0c;让我们一起干翻J…...

QGridLayout

QGridLayout QGridLayout 是 Qt 框架中的一个布局管理器类&#xff0c;用于在窗口或其他容器中创建基于网格的布局。 QGridLayout 将窗口或容器划分为行和列的网格&#xff0c;并将小部件放置在相应的单元格中。可以通过调整行、列和单元格的大小来控制布局的样式和结构。 以…...

万能在线预约小程序系统源码 适合任何行业在线预约小程序+预约到店模式 带完整的搭建教程

大家好啊&#xff0c;源码小编又来给大家分享啦&#xff01;随着互联网的发展和普及&#xff0c;越来越多的服务行业开始使用在线预约系统以方便客户和服务管理。例如&#xff0c;美发店、健身房、餐厅等都可以通过在线预约系统提高服务效率&#xff0c;减少等待时间&#xff0…...

Leetcode 2935. Maximum Strong Pair XOR II

Leetcode 2935. Maximum Strong Pair XOR II 1. 解题思路2. 代码实现 题目链接&#xff1a;2935. Maximum Strong Pair XOR II 1. 解题思路 这一题又是一个限制条件下找“最大值”的问题&#xff0c;不过这里的最大值是XOR之后的最大值。 而要求XOR之后结果的最大值&#x…...

[直播自学]-[汇川easy320]搞起来(4)看文档 查找设备(续)

2023.11.12 周六 19&#xff1a;05 补充一下关于以太网查找设备&#xff0c;如果设置如下&#xff1a; 然后点击测试&#xff1a; 点击ping 如果设置如下&#xff1a; 测试和ping和上图一样。 这就设计的有点不大好了&#xff01; 另…...

WebSphere Liberty 8.5.5.9 (四)

WebSphere Liberty 8.5.5.9 (四) [WebSphere Liberty 8.5.5.9]Linux 环境 ~$ unzip wlp-webProfile7-java8-linux-x86_64-8.5.5.9.zip ./ ~$ mkdir wlp-webProfile7-java8-8559 ~$ mv wlp ./wlp-webProfile7-java8-8559启动 WebSphere Liberty 8.5.5.9 服务 ~$ cd /home/tes…...

UE特效案例 —— 角色刀光

目录 一&#xff0c;环境配置 二&#xff0c;场景及相机设置 三&#xff0c;效果制作 刀光制作 地裂制作 击打地面炸开制作 一&#xff0c;环境配置 创建默认地形Landscape&#xff0c;如给地形上材质需确定比例&#xff1b;添加环境主光源DirectionalLight&#xff0c;设…...

11. EPIC定时器

11. EPIC定时器 EPIT定时器简介EPIT定时器结构分析EPIT 定时器相关寄存器EPITx_CREPITx_SREPITx_LR 加载寄存器EPITx_CMPR 比较寄存器EPITx_CNR 计数寄存器 EPIT 配置步骤 例程代码编写bsp_epittimer.hbsp_epittimer.cmain.c EPIT定时器简介 EPIT定时器是增强的周期中断定时器…...

git-bash配置代理

git-bash命令提交执行命令: "git push origin main"时发生错误: “$ git push origin main fatal: unable to access ‘https://github.com/satadriver/locust_server.git/’: Failed to connect to github.com port 443 after 21035 ms: Couldn’t connect to serve…...

【ElasticSearch系列-07】ES的开发场景和索引分片的设置及优化

ElasticSearch系列整体栏目 内容链接地址【一】ElasticSearch下载和安装https://zhenghuisheng.blog.csdn.net/article/details/129260827【二】ElasticSearch概念和基本操作https://blog.csdn.net/zhenghuishengq/article/details/134121631【三】ElasticSearch的高级查询Quer…...

JavaWeb Day09 Mybatis-基础操作02-XML映射文件动态SQL

目录 Mybatis动态SQL介绍​编辑 一、案例 ①Mapper层 ②测试类 ③EmpMapper.xml ④结果​ 二、标签 &#xff08;一&#xff09;if where标签 ​①EmpMapper.xml ②案例 ③总结 &#xff08;二&#xff09;foreach标签 ①SQL语句 ②Mapper层 ③EmpMapper.xml ④…...

CV学习基础

脸部检测是基于图像的明暗变化模式进行判断&#xff0c;需要将图像先进行灰度化处理 马赛克处理需先将图像缩小然后夸大回原尺寸。 保存训练好的算法用joblib 进行以下操作时已经使用cv2.cvtColor()完成了灰度化 图像平滑化&#xff08;模糊处理&#xff09;&#xff1a;cv…...

设计模式之禅之设计模式-原型模式

设计模式之禅之设计模式-原型模式 一&#xff1a;原型模式的定义 ​ 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。 ​ 原型模式(Prototype Pattern)的简单程度仅次于单例模式和迭代器模式。正是由于简单,使用的场景才非常地多。 ​ 原型模式的核心是一…...

Spring的循环依赖问题

文章目录 1.什么是循环依赖2.代码演示3.分析问题4.问题解决5.Spring循环依赖6. 疑问点6.1 为什么需要三级缓存6.2 没有三级缓存能解决吗&#xff1f;6.3 三级缓存分别什么作用 1.什么是循环依赖 上图是循环依赖的三种情况&#xff0c;虽然方式有点不一样&#xff0c;但是循环依…...

RT-DETR算法改进:更换损失函数DIoU损失函数,提升RT-DETR检测精度

💡本篇内容:RT-DETR算法改进:更换损失函数DIoU损失函数 💡本博客 改进源代码改进 适用于 RT-DETR目标检测算法(ultralytics项目版本) 按步骤操作运行改进后的代码即可🚀🚀🚀 💡改进 RT-DETR 目标检测算法专属 文章目录 一、DIoU理论部分 + 最新 RT-DETR算法…...

利用ngx_stream_return_module构建简易 TCP/UDP 响应网关

一、模块概述 ngx_stream_return_module 提供了一个极简的指令&#xff1a; return <value>;在收到客户端连接后&#xff0c;立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量&#xff08;如 $time_iso8601、$remote_addr 等&#xff09;&a…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密

在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...

前端导出带有合并单元格的列表

// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...

macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用

文章目录 问题现象问题原因解决办法 问题现象 macOS启动台&#xff08;Launchpad&#xff09;多出来了&#xff1a;Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显&#xff0c;都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

06 Deep learning神经网络编程基础 激活函数 --吴恩达

深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...

今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存

文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...

基于 TAPD 进行项目管理

起因 自己写了个小工具&#xff0c;仓库用的Github。之前在用markdown进行需求管理&#xff0c;现在随着功能的增加&#xff0c;感觉有点难以管理了&#xff0c;所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD&#xff0c;需要提供一个企业名新建一个项目&#…...

Python 训练营打卡 Day 47

注意力热力图可视化 在day 46代码的基础上&#xff0c;对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...

Vue 模板语句的数据来源

&#x1f9e9; Vue 模板语句的数据来源&#xff1a;全方位解析 Vue 模板&#xff08;<template> 部分&#xff09;中的表达式、指令绑定&#xff08;如 v-bind, v-on&#xff09;和插值&#xff08;{{ }}&#xff09;都在一个特定的作用域内求值。这个作用域由当前 组件…...