大前端代码重构:事件拦截 iOS & Flutter & Vue 您所在的位置:网站首页 橡皮泥手工制作花朵图片 大前端代码重构:事件拦截 iOS & Flutter & Vue

大前端代码重构:事件拦截 iOS & Flutter & Vue

#大前端代码重构:事件拦截 iOS & Flutter & Vue| 来源: 网络整理| 查看: 265

一、需求来源

app需要支持实现游客模式,启动后直接进入首页菜单,但是进入二级页则自动调用登录页面。总结需求就是父视图拦截子视图的响应事件,思考之后发现在事件响应链上做拦截是最优方法。

截屏2023-04-03 18.12.49.png

二、iOS 事件拦截 1、使用示例

absorbing 属性为 true 时,会拦截子视图的事件。点击 button 时只会调用 absorbPointerView(绿色) 的响应方法。

absorbing 属性为 false 时,不会拦截子视图的事件。点击 button 时只会调用 button(蓝色)的响应方法。

Simulator Screen2023-04-03.png

import UIKit import SnapKit import SwiftExpand /**  通过递归遍历将所有子视图设置 isUserInteractionEnabled = false,则该视图可以响应事件;  */ class NNAbsorbPointerViewController: UIViewController {     override func viewDidLoad() {         super.viewDidLoad()         // Do any additional setup after loading the view.         edgesForExtendedLayout = []         view.backgroundColor = .white         title = "NNAbsorbPointerView"                absorbPointerView.addSubview(button)         view.addSubview(absorbPointerView) //        view.recursion{ e in //            e.isUserInteractionEnabled = false; //        }         view.addGestureTap { reco in             debugPrint("\(Date()):reco.view")         }     }     override func viewDidLayoutSubviews() {         super.viewDidLayoutSubviews()         let edge = UIEdgeInsets(all: 50)         button.snp.makeConstraints { make in             make.edges.equalToSuperview().inset(edge)         }         absorbPointerView.snp.makeConstraints { make in             make.edges.equalToSuperview().inset(edge)         }     }     lazy var absorbPointerView: NNAbsorbPointerView = {         let view = NNAbsorbPointerView(frame: .zero);         view.absorbing = true;         view.backgroundColor = .green;         view.addGestureTap { reco in             debugPrint("\(Date()):NNAbsorbPointerView")         }         return view     }()     lazy var button: UIButton = {         let view = UIButton(type: .custom);         view.setTitle("UIButton", for: .normal)         view.setTitleColor(.white, for: .normal)         view.backgroundColor = .blue;         view.addGestureTap { reco in             debugPrint("\(Date()):button")         }         return view     }() } 复制代码 2、自定义视图 NNAbsorbPointerView,用来拦截它子视图事件。 import UIKit class NNAbsorbPointerView: UIView {     /// 是否拦截响应     var absorbing = false;     // **MARK: - 重写加载方法**     override init(frame: CGRect) {         super.init(frame: frame);     }     required init?(coder: NSCoder) {         fatalError("init(coder:) has not been implemented")     }     override func layoutSubviews() {         super.layoutSubviews()     }          override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {         if absorbing {             return self         }         // 1.判断能不能处理事件         if isUserInteractionEnabled == false, isHidden, alpha _AbsorbPointerDemoState(); } class _AbsorbPointerDemoState extends State { bool _disable = false; bool _switchValue = false; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Absorbpointer'), centerTitle: true, elevation: 0, ), body: Column( mainAxisAlignment: MainAxisAlignment.start, children: [ Row( children: [ Text('不可点击:absorbing: ${_disable}'), Switch( value: _disable, onChanged: (bool val) { _disable = val; setState(() {}); }, ) ], ), Divider(), _buildAbsorbPointerNew(absorbing: _disable), MaterialButton( color: Colors.lightBlue, onPressed: () => onClick('我是外面的按钮,不受影响'), child: Text('我是外面的按钮,不受影响'), ), ], ), ); } /// 默认吸收事件,拦截事件 _buildAbsorbPointerNew({bool absorbing = true}) { return InkWell( onTap: () => onClick("outside"), child: Container( color: Colors.green, padding: EdgeInsets.all(20), child: AbsorbPointer( absorbing: absorbing, child: InkWell( onTap: () => onClick("inside"), child: Container( color: Colors.blue, width: 200.0, height: 100.0, alignment: Alignment.center, child: Text("Container"), ), ), ), ), ); } onClick(String msg) { debugPrint(msg); } } 复制代码 四、Web 事件拦截 1、Vue 事件拦截

实现很简单,@click 添加修饰符 capture.stop 即可拦截子标签事件。

点击 button 时,父视图(绿色)会拦截响应事件。 192.168.3.126_57103.png

{{ $route.meta.title }} button import { getCurrentInstance, ref, reactive, watch, onMounted, } from 'vue'; import { useRouter, useRoute } from 'vue-router'; const router = useRouter(); const route = useRoute(); const doThis = () => { console.log(`${new Date()}: doThis`); }; const onClick = () => { console.log(`${new Date()}: onClick`); }; .page{ background-color: green; } 复制代码 2、react 事件拦截 暂无 复制代码 3、angular 事件拦截 暂无 复制代码 最后、总结 1、iOS 还有一种办法,递归遍历所有子视图进行处理,让其不响应事件,事件自然会传递到 目标父视图,只是性能较差; 2、Flutter 中随组件类型不同有略微差距,使用时需要根据实际情况调试。 3、大前端思路都是通的,事件机制一端弄懂了就三端都差不多了,细微差距可以在实际开发中再思考总结。以后大前端加一门后端技能是时代趋势,Keep Learning!!!

AbsorbPointerDemo.dart

NNAbsorbPointerViewController.swift

EventIntercept.vue



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有