宫格导航--纯血鸿蒙组件库AUI

news2025/6/1 1:51:57

摘要:

宫格导航(A_GirdNav):可设置导航数据,建议导航项超过16个,可设置“更多”图标指向的页面路由。最多显示两行,手机每行最多显示4个图标,折叠屏每行最多6个图标,平板每行最多8个图标。多余图标通过“更多”图标跳转。

一、组件调用方式

宫格导航组件的调用非常简单,只需要输入A_GirdNav ,然后给属性 data(导航数据)和 moreRouter(“更多”图标指向的页面路由)赋值即可。在 data 当中需要给文字、图标和跳转的路由赋值。如下图所示:

页面调用代码如下:

import { A_TitleBar } from '../aui/basic/A_TitleBar'
import { A_GirdNav } from '../aui/navigation/A_GirdNav'
import { ColorConstants } from '../constants/ColorConstants'
import { FloatConstants } from '../constants/FloatConstants'
import { GirdConstants } from '../constants/GirdConstants'
import { WindowUtils } from '../utils/WindowUtils'

@Component
export struct Sample2 {
  @StorageLink('pageInfo') pageInfo: NavPathStack = new NavPathStack()
  @StorageLink('primaryColor') primaryColor: ResourceStr = ColorConstants.INFO
  @StorageLink('deviceType') deviceType: string = GirdConstants.DEVICE_SM

  aboutToAppear() {
    WindowUtils.getInstance()?.setFullScreen()
  }

  build() {
    Row() {
      Column() {
        // 标题栏
        A_TitleBar({ text: '调用示例二' })

        // 下拉容器
        Scroll() {
          GridRow({
            columns: { sm: GirdConstants.GRID_COLUMNS[0], md: GirdConstants.GRID_COLUMNS[1], lg: GirdConstants.GRID_COLUMNS[2] },
            gutter: { x: GirdConstants.GRID_GUTTER, y: GirdConstants.GRID_GUTTER },
            breakpoints: { reference: BreakpointsReference.WindowSize } }) {

            GridCol({ span: 12 }) {
              A_GirdNav({
                data: [
                  { text: 'Java', icon: 'mdi-language-java', router: 'OrderDetail/2' },
                  { text: 'Python', icon: 'mdi-language-python', router: '' },
                  { text: 'Vuetify', icon: 'cast-variant', router: '' },
                  { text: '纯血鸿蒙', icon: 'mdi-tablet-cellphone', router: 'AccountPage' },
                  { text: 'Java', icon: 'mdi-language-java', router: 'OrderDetail/2' },
                  { text: 'Python', icon: 'mdi-language-python', router: '' },
                  { text: 'Vuetify', icon: 'cast-variant', router: '' },
                  { text: '纯血鸿蒙', icon: 'mdi-tablet-cellphone', router: 'AccountPage' },
                  { text: 'Java', icon: 'mdi-language-java', router: 'OrderDetail/2' },
                  { text: 'Python', icon: 'mdi-language-python', router: '' },
                  { text: 'Vuetify', icon: 'cast-variant', router: '' },
                  { text: '纯血鸿蒙', icon: 'mdi-tablet-cellphone', router: 'AccountPage' },
                  { text: 'Java', icon: 'mdi-language-java', router: 'OrderDetail/2' },
                  { text: 'Python', icon: 'mdi-language-python', router: '' },
                  { text: 'Vuetify', icon: 'cast-variant', router: '' },
                  { text: '纯血鸿蒙', icon: 'mdi-tablet-cellphone', router: 'AccountPage' },
                  { text: 'Java', icon: 'mdi-language-java', router: 'OrderDetail/2' },
                  { text: 'Python', icon: 'mdi-language-python', router: '' },
                  { text: 'Vuetify', icon: 'cast-variant', router: '' },
                  { text: '纯血鸿蒙', icon: 'mdi-tablet-cellphone', router: 'AccountPage' }
                ],
                moreRouter: 'MoreNavigation'
              })
            }
            .margin({
              top: FloatConstants.SPACE_TOP
            })
          }
          .padding({ bottom:this.deviceType === GirdConstants.DEVICE_LG ? GirdConstants.ZERO : FloatConstants.SPACE_S })
        }
        .scrollBar(BarState.Off)
      }
      .height(GirdConstants.FULL_PERCENT)
    }
    .alignItems(VerticalAlign.Top)
    .padding({
      top: FloatConstants.SPACE_TOP,
      left:FloatConstants.SPACE_LEFT,
      right:FloatConstants.SPACE_RIGHT,
      bottom:this.deviceType === GirdConstants.DEVICE_LG ? GirdConstants.GRID_BOTTOM : FloatConstants.SPACE_BOTTOM
    })
    .width(GirdConstants.FULL_PERCENT)
    .backgroundColor(ColorConstants.APP_BG)
  }
}

本地模拟器下浅色模式和深色模式运行效果如下:

二、在线排版

在会员页面或管理后台的页面当中选择一个页面,比如“首页”,然后点击“页面设计”。如下图所示:

现在“首页”是一个空页面,还没有任何组件。展开左侧组件库中的“导航组件”分组,将“宫格导航组件”拖拽到页面中,如下图所示:

选择右侧“组件设置”下的“宫格导航”组件,点击“配置数据”按钮,可以根据自己的业务需要,新增、删除或修改每一项配置,如下图所示:

现在,切换到代码魔法页面,我们可以在侧栏菜单这里选择“纯血鸿蒙”,(可以切换为深色模式,看代码更舒适),然后点击“生成代码”,如下图所示:

在生成的鸿蒙项目中,展开特性层(features),选择 home 模块,找到 /src/main/ets/view 目录下的 HomeView.ets 页面,查看生成的代码,如下图所示:

三、源码解析

宫格导航组件支持两个属性,一个是 data(导航数据,建议导航项超过16个),另外一个是 moreRouter(“更多”图标指向的页面路由):

卡片导航数据 data 是一个数组 Array<NavigationModel>,其中导航Model的数据结构如下,含三个字段:导航的文字(text)、导航图标(icon)和跳转页面的路由(router)。

继续分析宫格导航组件 A_GirdNav 的源码,在 aboutToAppear() 这个生命周期当中,对设备为折叠屏、平板和手机时的导航数据做了差异化的处理,以实现“一多”适配。其中,设备为折叠屏时,一行最多显示6个图标,最多显示两行。当总的图标数(每个图标对应一项导航数据)小于等于6个时,将所有图标放入一组数据;当总图标数大于6个时分为两组数据,第一组数据取前六项导航数据,第二组数据分两种情况:当总图标数大于12个时(超过两行),则将第7-11个图标放入第二组数据,然后加上一个“更多”图标;如果总图标数不超过12个图标,则将第7个到最后的图标放入第二组数据。如下图所示:

设备为平板时,一行最多显示8个图标,最多显示两行。当总的图标数小于等于8个时,将所有图标放入一组数据;当总图标数大于8个时分为两组数据,第一组数据取前八项导航数据,第二组数据分两种情况:当总图标数大于16个时(超过两行),则将第9-15个图标放入第二组数据,然后加上一个“更多”图标;如果总图标数不超过16个图标,则将第9个到最后的图标放入第二组数据。如下图所示:

设备为手机时,一行最多显示4个图标,最多显示两行。当总的图标数小于等于4个时,将所有图标放入一组数据;当总图标数大于4个时分为两组数据,第一组数据取前四项导航数据,第二组数据分两种情况:当总图标数大于8个时(超过两行),则将第5-7个图标放入第二组数据,然后加上一个“更多”图标;如果总图标数不超过8个图标,则将第5个到最后的图标放入第二组数据。如下图所示:

最后,将原始导航数据中的图标数据做了预处理,变为符合鸿蒙资源命名规则的方式,如下代码所示:

 this.compData.forEach(element => {
      element.icon = 'app.media.' + (element.icon.startsWith('mdi-') || element.icon.startsWith('mdi_') ? '' : 'mdi_') + element.icon.replaceAll('-', '_')
    })
    this.compData2.forEach(element => {
      element.icon = 'app.media.' + (element.icon.startsWith('mdi-') || element.icon.startsWith('mdi_') ? '' : 'mdi_') + element.icon.replaceAll('-', '_')
    })

使用自定义构建函数buildGirdNavigation展示两组导航数据,如下图所示:

ArkUI提供了一种轻量的UI元素复用机制@Builder,其内部UI结构固定,仅与使用方进行数据传递,开发者可以将重复使用的UI元素抽象成一个方法,在build方法里调用。为了简化语言,我们将@Builder装饰的函数也称为“自定义构建函数”。使用@Builder装饰自定义构建函数buildGirdNavigation,通过ForEach循环每一组导航数据,内部通过Image组件包装图标,Text组件包装文字,使用点击事件实现页面路由跳转,如下图所示:

宫格导航组件的完整源码如下:

/*
 * Copyright (c) 2024 AIGCoder.com(AI极客)
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 调用示例一:
 A_GirdNav({
   data: [
     { text: 'Java', icon: 'mdi-language-java', router: 'OrderDetail/2' },
     { text: 'Python', icon: 'mdi-language-python', router: '' },
     { text: 'Vuetify', icon: 'cast-variant', router: '' },
     { text: '纯血鸿蒙', icon: 'mdi-tablet-cellphone', router: 'AccountPage' },
     { text: 'Java', icon: 'mdi-language-java', router: 'OrderDetail/2' },
     { text: 'Python', icon: 'mdi-language-python', router: '' },
     { text: 'Vuetify', icon: 'cast-variant', router: '' },
     { text: '纯血鸿蒙', icon: 'mdi-tablet-cellphone', router: 'AccountPage' },
     { text: 'Java', icon: 'mdi-language-java', router: 'OrderDetail/2' },
     { text: 'Python', icon: 'mdi-language-python', router: '' },
     { text: 'Vuetify', icon: 'cast-variant', router: '' },
     { text: '纯血鸿蒙', icon: 'mdi-tablet-cellphone', router: 'AccountPage' },
     { text: 'Java', icon: 'mdi-language-java', router: 'OrderDetail/2' },
     { text: 'Python', icon: 'mdi-language-python', router: '' },
     { text: 'Vuetify', icon: 'cast-variant', router: '' },
     { text: '纯血鸿蒙', icon: 'mdi-tablet-cellphone', router: 'AccountPage' }
   ]
 })

 调用示例二:“更多”图标指向页面路由
 A_GirdNav({
   data: [
     { text: 'Java', icon: 'mdi-language-java', router: 'OrderDetail/2' },
     { text: 'Python', icon: 'mdi-language-python', router: '' },
     { text: 'Vuetify', icon: 'cast-variant', router: '' },
     { text: '纯血鸿蒙', icon: 'mdi-tablet-cellphone', router: 'AccountPage' },
     { text: 'Java', icon: 'mdi-language-java', router: 'OrderDetail/2' },
     { text: 'Python', icon: 'mdi-language-python', router: '' },
     { text: 'Vuetify', icon: 'cast-variant', router: '' },
     { text: '纯血鸿蒙', icon: 'mdi-tablet-cellphone', router: 'AccountPage' },
     { text: 'Java', icon: 'mdi-language-java', router: 'OrderDetail/2' },
     { text: 'Python', icon: 'mdi-language-python', router: '' },
     { text: 'Vuetify', icon: 'cast-variant', router: '' },
     { text: '纯血鸿蒙', icon: 'mdi-tablet-cellphone', router: 'AccountPage' },
     { text: 'Java', icon: 'mdi-language-java', router: 'OrderDetail/2' },
     { text: 'Python', icon: 'mdi-language-python', router: '' },
     { text: 'Vuetify', icon: 'cast-variant', router: '' },
     { text: '纯血鸿蒙', icon: 'mdi-tablet-cellphone', router: 'AccountPage' },
     { text: 'Java', icon: 'mdi-language-java', router: 'OrderDetail/2' },
     { text: 'Python', icon: 'mdi-language-python', router: '' },
     { text: 'Vuetify', icon: 'cast-variant', router: '' },
     { text: '纯血鸿蒙', icon: 'mdi-tablet-cellphone', router: 'AccountPage' }
   ],
   moreRouter: 'MoreNavigation'
 })
 */

import { ColorConstants } from "../../constants/ColorConstants"
import { FloatConstants } from "../../constants/FloatConstants"
import { GirdConstants } from "../../constants/GirdConstants"
import { NavigationModel } from "../../models/NavigationModel"

/**
 * 【宫格导航】
 * data:导航数据(建议导航项超过16个)
 * moreRouter:“更多”图标指向的页面路由
 */
@Component
export struct A_GirdNav {
  @Prop data: Array<NavigationModel>
  @Prop moreRouter?: string

  @StorageLink('pageInfo') pageInfo: NavPathStack = new NavPathStack()
  @StorageLink('deviceType') deviceType: string = GirdConstants.DEVICE_SM

  @State compMore: NavigationModel = {
    text: '更多',
    icon: 'dots-horizontal-circle-outline',
    router: this.moreRouter
  }
  @State compBlank: NavigationModel = {
    text: '',
    icon: '',
    router: ''
  }
  @State compPadding: Length = '16vp'
  private compMarginTop: Length = '36vp'
  private compMarginBottom: Length = '12vp'
  private compCardHeight: Length = '136vp'
  private compData: Array<NavigationModel> = []
  private compData2: Array<NavigationModel> = []

  aboutToAppear(): void {
    switch (this.deviceType){
      case GirdConstants.DEVICE_MD:
        if(this.data.length > 6){
          this.compData = this.data.slice(0, 6)

          if(this.data.length > 12){
            this.compData2 = this.data.slice(6, 11)
            this.compData2.push(this.compMore)
          }else{
            this.compData2 = this.data.slice(6, this.data.length)
            for (let i = 0; i < 12-this.data.length; i++) {
              this.compData2.push(this.compBlank)
            }
          }
        }else{
          this.compData = this.data.slice(0, this.data.length)
        }
        this.compCardHeight = this.compData2.length > 0 ? '144vp' : '80vp'
        break
      case GirdConstants.DEVICE_LG:
        if(this.data.length > 8){
          this.compData = this.data.slice(0, 8)

          if(this.data.length > 16){
            this.compData2 = this.data.slice(8, 15)
            this.compData2.push(this.compMore)
          }else{
            this.compData2 = this.data.slice(8, this.data.length)
            for (let i = 0; i < 16-this.data.length; i++) {
              this.compData2.push(this.compBlank)
            }
          }
        }else{
          this.compData = this.data.slice(0, this.data.length)
        }
        this.compPadding = '24vp'
        this.compMarginBottom = '16vp'
        this.compCardHeight = this.compData2.length > 0 ? '160vp' : '96vp'
        break
      case GirdConstants.DEVICE_SM:
      default:
        if(this.data.length > 4){
          this.compData = this.data.slice(0, 4)

          if(this.data.length > 8){
            this.compData2 = this.data.slice(4, 7)
            this.compData2.push(this.compMore)
          }else{
            this.compData2 = this.data.slice(4, this.data.length)
            for (let i = 0; i < 8-this.data.length; i++) {
              this.compData2.push(this.compBlank)
            }
          }
        }else{
          this.compData = this.data.slice(0, this.data.length)
        }
        this.compCardHeight = this.compData2.length > 0 ? '136vp' : '80vp'
        break
    }
    this.compData.forEach(element => {
      element.icon = 'app.media.' + (element.icon.startsWith('mdi-') || element.icon.startsWith('mdi_') ? '' : 'mdi_') + element.icon.replaceAll('-', '_')
    })
    this.compData2.forEach(element => {
      element.icon = 'app.media.' + (element.icon.startsWith('mdi-') || element.icon.startsWith('mdi_') ? '' : 'mdi_') + element.icon.replaceAll('-', '_')
    })
  }

  build() {
    Column() {
      this.buildGirdNavigation(this.compData)
      this.buildGirdNavigation(this.compData2)
    }
    .backgroundColor(ColorConstants.CARD_BG)
    .width(GirdConstants.FULL_PERCENT)
    .justifyContent(FlexAlign.SpaceBetween)
    .borderRadius(FloatConstants.RADIUS_CARD)
    .padding(this.compPadding)
    .margin({
      top: this.compMarginTop,
      bottom: this.compMarginBottom
    })
    .height(this.compCardHeight)
  }

  @Builder
  buildGirdNavigation(list: NavigationModel[]) {
    Row() {
      ForEach(list, (item: NavigationModel) => {
        Column({ space: GirdConstants.EIGHT }) {
          Image($r(item.icon))
            .width(FloatConstants.IMAGE_SIZE5)
            .height(FloatConstants.IMAGE_SIZE5)
            .fillColor(ColorConstants.FG_LEVEL1)
          Text(item.text)
            .fontSize(FloatConstants.FONT_SIZE_BODY_S)
            .fontColor(ColorConstants.FG_LEVEL1)
        }
        .onClick(() => {
          if (item.router) {
            // 跳转到新页面
            const router = item.router
            if (router.includes("/")) {
              this.pageInfo.pushPathByName(router.substring(0, router.indexOf("/")),
                router.substring(router.indexOf("/") + 1))
            } else {
              this.pageInfo.pushPathByName(router, null)
            }
          }
        })
        .width(FloatConstants.IMAGE_SIZE10)
      }, (item: NavigationModel, index: number) => index + JSON.stringify(item))
    }
    .justifyContent(FlexAlign.SpaceBetween)
    .width(GirdConstants.FULL_PERCENT)
  }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2392015.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

RNN 循环神经网络:原理与应用

一、RNN 的诞生背景 传统神经网络&#xff08;如 MLP、CNN&#xff09;在处理独立输入时表现出色&#xff0c;但现实世界中存在大量具有时序依赖的序列数据&#xff1a; 自然语言&#xff1a;"我喜欢吃苹果" 中&#xff0c;"苹果" 的语义依赖于前文 "…

若依框架 账户管理 用户分配界面解读

下载下来若依网站后 先对 后端代码进行解读 首先项目架构&#xff1a; 一般用 admin 这个比较多进行二次开发 其他 rouyi-common,rouyi-framework:为公共部分 rouyi-generator&#xff1a;代码生成部分 ruoyi-quartz&#xff1a;定时任务 ruoyi-system&#xff1a;系统任务 …

文档贡献 | 技术文档贡献流程及注意事项(保姆级教程)

内容目录 一、注册流程 二、创建分支&#xff08;Fork&#xff09; 三、使用GitLab界面更新文件的MR流程 四、使用Git命令行工具更新文件的MR流程 五、注意事项 一、注册流程 1、注册页面 在长安链平台注册页面&#xff0c;输入手机号码 &#xff0c;点击 “获取验证码”…

open-vscode-server +nodejs 安装

GitCode - 全球开发者的开源社区,开源代码托管平台GitCode是面向全球开发者的开源社区,包括原创博客,开源代码托管,代码协作,项目管理等。与开发者社区互动,提升您的研发效率和质量。https://gitcode.com/gh_mirrors/op/openvscode-server/?utm_sourceartical_gitcode&ind…

知行之桥如何将消息推送到钉钉群?

在钉钉平台中&#xff0c;机器人主要分为企业机器人和自定义机器人两类。本文将重点介绍如何通过自定义机器人&#xff0c;实现将知行之桥 EDI 系统的通知消息高效推送至钉钉群&#xff0c;帮助企业第一时间掌握业务动态。 一、在钉钉群中添加自定义机器人 在需要接收知行之桥…

09《从依赖管理到容器化部署:Maven 全链路实战笔记,解锁 Java 项目自动化构建的终极奥秘》

目录 一、Maven 核心基础强化 &#xff08;一&#xff09;Maven 架构与工作原理 1. 核心组件解析 2. 工作流程图示​编辑 &#xff08;二&#xff09;项目结构深度实践 1. 标准目录扩展说明 2. 多模块项目典型结构示例​编辑 二、依赖管理高级进阶 &#xff08;一&…

<el-date-picker>组件传参时,选中时间和传参偏差8小时

遇到一个bug&#xff0c;不仔细看&#xff0c;都不一定能发现&#xff0c;bug描述&#xff1a;我们有一个搜索框&#xff0c;里面有一个时间选择器&#xff0c;当我使用<el-date-picker>时&#xff0c;我发现当我选择时分秒之后&#xff0c;显示都正常&#xff0c;但是当…

ST MCU CAN模块--TTCAN模式浅析

ST MCU CAN模块使用总结 1 前言 ​ 传统CAN 采用事件触发消息传输机制,CSMA/ CD AMP( Carrier-Sense Mult iple Access w ith Co llision Detect ion and Arbit ration on Message Priorit ies, 载波侦听、多路访问、冲突检测、优先级仲裁) 介质访问控制机制, 即多个消息同时…

谷歌浏览器Google Chrome v137.0.7151.41 中文版本版+插件 v1.11.1

一、软件介绍 这个版本解压就可以用&#xff0c;界面是中文的。 保留了核心功能&#xff0c; 二、软件特点 便携性 &#xff1a;解压即可使用&#xff0c;不想用了直接删掉整个文件夹。 增强功能 &#xff1a;通过Chrome增强软件劫持补丁chromev1.11.1 x64 (version.dll)实现多…

国芯思辰| 同步降压转换器CN2020应用于智能电视,替换LMR33620

在智能电视不断向高画质、多功能、智能化发展的当下&#xff0c;其内部电源管理系统的性能至关重要。同步降压转换器可以为智能电视提供稳定、高效的运行。 国芯思辰CN2020是一款脉宽调制式同步降压转换器。内部集成两个功率MOS管&#xff0c;在4.5~18V宽输入电压范围内可以持…

DeepSeek 提示词大全

目录 前言一、提示词基础理论 什么是提示词提示词的类型提示词的基本结构 二、提示词设计原则 明确指令结构化表达情境化需求渐进式引导边界与限制 三、场景化提示词模板 写作创作类角色扮演类信息提取类代码编程类教育学习类商业营销类生活助手类 四、提示词优化技巧 迭代式优…

俄罗斯无人机自主任务规划!UAV-CodeAgents:基于多智能体ReAct和视觉语言推理的可扩展无人机任务规划

作者&#xff1a;Oleg Sautenkov 1 ^{1} 1, Yasheerah Yaqoot 1 ^{1} 1, Muhammad Ahsan Mustafa 1 ^{1} 1, Faryal Batool 1 ^{1} 1, Jeffrin Sam 1 ^{1} 1, Artem Lykov 1 ^{1} 1, Chih-Yung Wen 2 ^{2} 2, and Dzmitry Tsetserukou 1 ^{1} 1单位&#xff1a; 1 ^{1} 1斯科尔…

结构性设计模式之Bridge(桥接)

结构性设计模式之Bridge&#xff08;桥接&#xff09; 摘要 桥接模式是一种结构性设计模式&#xff0c;其核心思想是将抽象部分与实现部分分离&#xff0c;使二者能够独立变化。本文通过汽车产品生产案例&#xff08;产品A/B与颜色红/蓝/黄&#xff09;展示了桥接模式的应用&…

Android 16系统源码_无障碍辅助(一)认识无障碍服务

前言 Android 的无障碍辅助功能&#xff08;Accessibility&#xff09;是一套专为残障用户或特殊场景设计的核心技术框架&#xff0c;旨在让所有用户都能便捷地操作设备。其功能覆盖视觉、听觉、运动能力和认知障碍支持&#xff0c;同时为开发者提供标准化 API 以实现应用适配…

分布式数据库备份实践

在分布式备份中可以采取两种方式进行备份&#xff0c;一种是采用手动编写backup.yml文件进行备份&#xff0c;另外一种是吧备份过程交给备份工具自动执行。如果需要个性化进行备份&#xff0c;建议采用手动编写备份文件方式进行备份。 以下是针对两种备份方式的实践&#xff1a…

如何发布npm包?

如何发布npm包&#xff1f; 1. 注册账号[npm官网](https://www.npmjs.com/)2. 检查 npm 源是否在官方 npm 仓库&#xff0c;如果不在&#xff0c;进行切换3. 检查4. 打包配置5. 发布6. 使用错误&#xff1a;版本更新命令 1. 注册账号npm官网 2. 检查 npm 源是否在官方 npm 仓库…

实验设计与分析(第6版,Montgomery)第5章析因设计引导5.7节思考题5.6 R语言解题

本文是实验设计与分析&#xff08;第6版&#xff0c;Montgomery著&#xff0c;傅珏生译) 第5章析因设计引导5.7节思考题5.6 R语言解题。主要涉及方差分析&#xff0c;正态假设检验&#xff0c;残差分析&#xff0c;交互作用图&#xff0c;等值线图。 dataframe <-data.frame…

OpenCV计算机视觉实战(8)——图像滤波详解

OpenCV计算机视觉实战&#xff08;8&#xff09;——图像滤波详解 0. 前言1. 线性滤波1.1 均值滤波1.2 高斯滤波1.3 拉普拉斯滤波1.4 Sobel 滤波 2. 非线性滤波3. 自定义卷积核小结系列链接 0. 前言 在本文中&#xff0c;我们将深入探索线性与非线性滤波的算法原理、性能优化及…

自动化安全脚本学习

1.目录扫描器 目标&#xff1a;使用python编写一个自动化目录扫描工具&#xff0c;实现简单信息收集&#xff0c;判断目标网站是否存在常见路径。 import requests #用于发HTTP请求 from concurrent.futures import ThreadPoolExecutor #实现多线程扫描# 扫描目标 target h…

传输层协议TCP(上)

上一篇https://blog.csdn.net/Small_entreprene/article/details/148143494?fromshareblogdetail&sharetypeblogdetail&sharerId148143494&sharereferPC&sharesourceSmall_entreprene&sharefromfrom_link 上文学习了传输层的协议之一UDP&#xff0c;接下来…