【HarmonyOS开发】通过媒体查询,实现一次开发,多端部署

news2024/9/24 8:35:37

 媒体查询(Media Queries)是一种在CSS中使用的技术,用于根据设备的特性和属性(如屏幕宽度、设备类型等)来应用不同的样式规则。通过媒体查询,可以根据不同的设备或屏幕尺寸为用户提供优化的布局和样式。

1、Web中CSS的媒体查询

1.1 根据屏幕宽度应用样式

@media screen and (max-width: 768px) {
  /* 当屏幕宽度小于等于 768px 时应用的样式 */
  /* 适用于移动设备或小屏幕 */
}

@media screen and (min-width: 769px) and (max-width: 1024px) {
  /* 当屏幕宽度在 769px 到 1024px 之间时应用的样式 */
  /* 适用于平板设备或中等屏幕 */
}

@media screen and (min-width: 1025px) {
  /* 当屏幕宽度大于等于 1025px 时应用的样式 */
  /* 适用于桌面设备或大屏幕 */
}

1.2 根据设备类型应用样式

@media screen and (orientation: landscape) {
  /* 当设备处于横向(landscape)方向时应用的样式 */
}

@media screen and (orientation: portrait) {
  /* 当设备处于纵向(portrait)方向时应用的样式 */
}

@media print {
  /* 在打印时应用的样式 */
}

1.3 组合多个条件的媒体查询

@media screen and (min-width: 768px) and (max-width: 1024px),
       (orientation: portrait) {
  /* 当屏幕宽度在 768px 到 1024px 之间或设备处于纵向方向时应用的样式 */
}

2、Web中JS的媒体查询

可以使用window.matchMedia()方法来执行媒体查询,并根据查询结果执行相应的操作。这个方法返回一个MediaQueryList对象,该对象具有matches属性,表示查询是否匹配。将查询的结果存储在Window全局变量即可。

// 创建一个媒体查询对象
var mediaQuery = window.matchMedia('(max-width: 768px)');

// 检查媒体查询的匹配状态
if (mediaQuery.matches) {
  // 当媒体查询匹配时执行的操作
  // 适用于移动设备或小屏幕
  console.log('Media query matches!');
} else {
  // 当媒体查询不匹配时执行的操作
  // 适用于平板设备或大屏幕
  console.log('Media query does not match!');
}

// 添加一个媒体查询监听器
mediaQuery.addListener(function(mediaQueryList) {
  if (mediaQueryList.matches) {
    // 当媒体查询匹配时执行的操作
    console.log('Media query matches!');
  } else {
    // 当媒体查询不匹配时执行的操作
    console.log('Media query does not match!');
  }
});

3、Vue/React中的媒体查询

3.1 Vue中使用媒体查询

3.1.1 计算属性

<template>
  <div :class="containerClass">
    <p>Content goes here</p>
  </div>
</template>

<script>
import { ref, onMounted, onUnmounted } from 'vue';

export default {
  setup() {
    const containerClass = ref('');

    const updateContainerClass = () => {
      containerClass.value = window.innerWidth < 768 ? 'small-screen' : 'large-screen';
    };

    onMounted(() => {
      updateContainerClass();
      window.addEventListener('resize', updateContainerClass);
    });

    onUnmounted(() => {
      window.removeEventListener('resize', updateContainerClass);
    });

    return {
      containerClass
    };
  }
};
</script>

<style>
.small-screen {
  /* 在小屏幕上应用的样式 */
}

.large-screen {
  /* 在大屏幕上应用的样式 */
}
</style>

3.1.2 三方库(vue-mq)

  • vue-mq(以这个为例)
  • vue-breakpoint-component
  • vue-responsive
  • vue-media-query-mixin
npm install vue-mq
// main.js中配置
import { createApp } from 'vue';
import App from './App.vue';
import VueMq from 'vue-mq';

const app = createApp(App);

app.use(VueMq, {
  breakpoints: {
    mobile: 768,
    tablet: 1024,
    desktop: 1280,
    // 根据需要添加其他断点
  }
});

app.mount('#app');
// 使用
<template>
  <div :class="$mq">
    <p>Content goes here</p>
  </div>
</template>

<style>
.mobile {
  /* 在移动设备上应用的样式 */
}

.tablet {
  /* 在平板设备上应用的样式 */
}

.desktop {
  /* 在桌面设备上应用的样式 */
}
</style>

3.2 React中使用媒体查询(三方库)

  • react-responsive(以这个为主)
  • react-responsive-hooks
  • react-media
  • react-match-media
import React from 'react';
import styles from './MyComponent.module.css';
import { useMediaQuery } from 'react-responsive';

const MyComponent = () => {
  const isSmallScreen = useMediaQuery({ maxWidth: 768 });
  const isMediumScreen = useMediaQuery({ minWidth: 769, maxWidth: 1024 });
  const isLargeScreen = useMediaQuery({ minWidth: 1025 });

  return (
    <div className={`${styles.container} ${isSmallScreen ? styles.smallScreen : ''} ${isMediumScreen ? styles.mediumScreen : ''} ${isLargeScreen ? styles.largeScreen : ''}`}>
      <p>Content goes here</p>
    </div>
  );
};

export default MyComponent;

4、Harmony中的媒体查询

鸿蒙中主要通过 @ohos.mediaquery 实现媒体查询,进行断点  

// 参考:https://developer.harmonyos.com/cn/docs/documentation/doc-references-V3/js-apis-mediaquery-0000001478181613-V3#ZH-CN_TOPIC_0000001573928789__mediaquerymatchmediasync

import mediaquery from '@ohos.mediaquery'

4.1 封装媒体查询方法(.ts)

import mediaQuery from '@ohos.mediaquery'

class BreakpointSystem {
  private currentBreakpoint: string = 'md'
  private smListener: mediaQuery.MediaQueryListener
  private mdListener: mediaQuery.MediaQueryListener
  private lgListener: mediaQuery.MediaQueryListener

  private updateCurrentBreakpoint(breakpoint: string) {
    if (this.currentBreakpoint !== breakpoint) {
      this.currentBreakpoint = breakpoint
      AppStorage.Set<string>('currentBreakpoint', this.currentBreakpoint)
    }
    console.log('======currentBreakpoint======', this.currentBreakpoint)
  }

  private isBreakpointSM = (mediaQueryResult) => {
    if (mediaQueryResult.matches) {
      this.updateCurrentBreakpoint('sm')
    }
  }

  private isBreakpointMD = (mediaQueryResult) => {
    if (mediaQueryResult.matches) {
      this.updateCurrentBreakpoint('md')
    }
  }

  private isBreakpointLG = (mediaQueryResult) => {
    if (mediaQueryResult.matches) {
      this.updateCurrentBreakpoint('lg')
    }
  }

  public register() {
    this.smListener = mediaQuery.matchMediaSync('(320vp<=width<600vp)')
    this.smListener.on('change', this.isBreakpointSM)
    this.mdListener = mediaQuery.matchMediaSync('(600vp<=width<840vp)')
    this.mdListener.on('change', this.isBreakpointMD)
    this.lgListener = mediaQuery.matchMediaSync('(840vp<=width)')
    this.lgListener.on('change', this.isBreakpointLG)
  }

  public unregister() {
    this.smListener.off('change', this.isBreakpointSM)
    this.mdListener.off('change', this.isBreakpointMD)
    this.lgListener.off('change', this.isBreakpointLG)
  }
}

export default new BreakpointSystem()

4.2 使用封装的函数

4.2.1 轮播图中使用

import breakpointSystem from '../common/BreakpointSystem'

@Component
export default struct IndexSwiper {
  @StorageProp('currentBreakpoint') currentBreakpoint: string = 'md'

  @Builder swiperItem(imageSrc) {
    Image(imageSrc)
      .width('100%')
      .aspectRatio(2.5)
      .objectFit(ImageFit.Fill)
  }

  aboutToAppear() {
    breakpointSystem.register()
  }

  aboutToDisappear() {
    breakpointSystem.unregister()
  }

  build() {
    Swiper() {
      this.swiperItem($r('app.media.ic_public_swiper1'))
      this.swiperItem($r('app.media.ic_public_swiper2'))
      this.swiperItem($r('app.media.ic_public_swiper3'))
      this.swiperItem($r('app.media.ic_public_swiper1'))
      this.swiperItem($r('app.media.ic_public_swiper2'))
      this.swiperItem($r('app.media.ic_public_swiper3'))
    }
    .autoPlay(true)
    .indicator(false)
    .itemSpace(10)
    .displayCount(this.currentBreakpoint === 'sm' ? 1 : (this.currentBreakpoint === 'md' ? 2 : 3))
    .width('100%')
    .padding({ left: 12, right: 12, bottom: 16, top: 16 })
  }
}

4.2.2 TarBar中使用

import breakpointSystem from '../common/BreakpointSystem'

@Entry
@Component
struct Index {
  @State currentIndex: number = 0
  @StorageProp('currentBreakpoint') currentBreakpoint: string = 'md'
  private onTabChange = (index: number) => {
    this.currentIndex = index
  }

  aboutToAppear() {
    breakpointSystem.register()
  }

  aboutToDisappear() {
    breakpointSystem.unregister()
  }

  @Builder
  tabItem(index: number, title: Resource, icon: Resource, iconSelected: Resource) {
    TabBarItem({
      index: index,
      currentIndex: this.currentIndex,
      title: title,
      icon: icon,
      iconSelected: iconSelected
    })
  }

  build() {
    Tabs({ barPosition: this.currentBreakpoint === 'lg' ? BarPosition.Start : BarPosition.End }) {
      TabContent() {
        Home()
      }
      .tabBar(this.tabItem(0, $r('app.string.tabBar1'), $r('app.media.ic_home_normal'), $r('app.media.ic_home_actived')))

      TabContent() {
      }
      .tabBar(this.tabItem(1, $r('app.string.tabBar2'), $r('app.media.ic_app_normal'), $r('app.media.ic_app_actived')))

      TabContent() {
      }
      .tabBar(this.tabItem(2, $r('app.string.tabBar3'), $r('app.media.ic_game_normal'), $r('app.media.ic_mine_actived')))

      TabContent() {
      }
      .tabBar(this.tabItem(3, $r('app.string.tabBar4'), $r('app.media.ic_search_normal'), $r('app.media.ic_search_actived')))
    }
    .barWidth(this.currentBreakpoint === 'lg' ? 96 : '100%')
    .barHeight(this.currentBreakpoint === 'lg' ? '60%' : 56)
    .vertical(this.currentBreakpoint === 'lg')
    .onChange(this.onTabChange)
    .backgroundColor('#F1F3F5')
  }
}

4.3 效果图

5、额外加一个Hilog的封装扩展(.ts)

import hilog from '@ohos.hilog';

export class Logger {
  // 日志对应的领域标识
  private domain: number = 0xF811;
  // tag日志标识
  private prefix: string = '[Logger_Utils]';
  // 格式字符串,用于日志的格式化输出
  private format: string = '%{public}s, %{public}s';

  constructor(prefix: string) {
    this.prefix = prefix;
  }

  debug(...args: string[]): void {
    hilog.debug(this.domain, this.prefix, this.format, args);
  }

  info(...args: string[]): void {
    hilog.info(this.domain, this.prefix, this.format, args);
  }

  warn(...args: string[]): void {
    hilog.warn(this.domain, this.prefix, this.format, args);
  }

  error(...args: string[]): void {
    hilog.error(this.domain, this.prefix, this.format, args);
  }
}

export default new Logger('[Logger_Utils]');

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

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

相关文章

C#编程-使用构造函数和析构函数

使用构造函数和析构函数 如果想要在以创建对象时就初始化成员变量,可以创建名为构造函数的特殊函数。您可能还需要使用对象后从内存中删除这些对象。这可通过称为析构函数的函数实现。 实现构造函数 构造函数是在创建对象时自动调用的特殊方法。无须显式地调用构造函数。请…

StratifiedGroupKFold解释和代码实现

StratifiedGroupKFold解释和代码实现 文章目录 一、StratifiedGroupKFold解释和代码实现是什么&#xff1f;二、 实验数据设置2.1 实验数据生成代码2.2 代码结果 三、实验代码3.1 实验代码3.2 实验结果3.3 结果解释 四、样本类别类别不平衡 一、StratifiedGroupKFold解释和代码…

全国计算机等级考试| 二级Python | 真题及解析(11)

一、选择题 1.有关循环结构的说法不正确的是( )。 A.循环结构是算法的基本结构之一 B.有的的程序设计中没有循环结构 C.循环结构在程序设计有可能会有嵌套出现 D.在PYTHON 程序设计语言中循环结构一般使用IF语句实现。 2.在Python中要交换变量a和b中的值,应使…

《数字图像处理-OpenCV/Python》连载:空间滤波之高斯滤波器

《数字图像处理-OpenCV/Python》连载&#xff1a;空间滤波之高斯滤波器 本书京东 优惠购书链接 https://item.jd.com/14098452.html 本书CSDN 独家连载专栏 https://blog.csdn.net/youcans/category_12418787.html 第 10 章 图像卷积与空间滤波 图像滤波是指在尽可能保留图像细…

9.X形图案

题目 import java.util.Scanner;// 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextInt()) { // 注意 while 处…

CCNP课程实验-04-BGP_CFG

目录 实验条件网络拓朴 基础配置需求实现IGP部分1. 按照图示配置OSPF区域&#xff0c;RID为Loopback 0地址。其中Area 146要配置为OSPF的特殊区域。2. 配置其它路由协议&#xff0c;重分布使得路由互相注入&#xff0c;实现全网互通。3. R1配置策略路由&#xff0c;使得R2经R1去…

react-hooks-kit v1 正式发布

evanpatchouli/react-hooks-kit - (npmjs.com) v1.0.0 正式发布&#xff01; 下载安装 npm i evanpatchouli/react-hooks-it -S官方文档 在 Gitee 阅读在 Github 阅读 概览 这是一个无依赖的轻量级 React Hooks 库&#xff0c;总共有 60 hooks。 它包含了一系列易于使用…

linux 内核链表操作

操作系统内核, 如同其他程序, 常常需要维护数据结构的列表. 有时, Linux 内核已经同 时有几个列表实现. 为减少复制代码的数量, 内核开发者已经创建了一个标准环形的, 双 链表; 鼓励需要操作列表的人使用这个设施. 当使用链表接口时, 你应当一直记住列表函数不做加锁. 如果你的…

小妙招:教你如何查询获取企业工商数据

在行业互联网领域&#xff0c;工商数据的运用场景多种多样。无论是对产业链的上下游企业&#xff0c;还是为企业背景调查、客户获取、财税服务、知识产权服务&#xff0c;乃至于外贸企业&#xff0c;商品批发等业务&#xff0c;TO B服务型企业都离不开工商数据的支持。这些五花…

主动IRS(Active IRS)模型总结

文章目录 A Framework for Transmission Design for Active RIS-Aided Communication with Partial CSIHybrid active and passive IRS从已有passive IRS算法拓展到active IRS算法 active IRS 与 passive IRS模型的区别 A Framework for Transmission Design for Active RIS-Ai…

centos7 ping不通域名

如果ip能ping通&#xff0c;ping不通域名可以试试以下操作&#xff1a; 1.编辑resolv.conf文件 vi /etc/resolv.conf 添加 nameserver 8.8.8.8 2.编辑nsswitch.conf vi /etc/nsswitch.conf 改成下图所示&#xff1a; 3.编辑sysctl.conf vi /etc/sysctl.conf 加上两行内…

爬虫如何获取免费代理IP(二)

89ip代理爬取代码实现 一、代码实现 import requests import time import random from fake_useragent import UserAgent from lxml import etree import os import csv""" 89ip代理爬取 """class IPSipder(object):def __init__(self):self.u…

rime中州韵小狼毫 inputShow lua Translator 输入字符透传翻译器

在 rime中州韵小狼毫 help lua Translator 中我们分享了如何使用 lua 脚本定义一个 translator&#xff0c;并以 五笔・拼音 为例引用了该 translator&#xff0c;并且达到了预期的效果。 今天&#xff0c;我们继续通过 lua 脚本为 rime中州韵/小狼毫 输入法打造一个 translat…

【Linux Shell】1. Shell 简述

文章目录 【 1. Shell 解释器、Shell语言、Shell脚本 】【 2. Shell 环境 】【 3. 一个简单的 Shell 脚本 】3.1 Shell 脚本的编写3.2 Shell 脚本的运行3.2.1 作为可执行程序运行 Shell 脚本3.2.2 作为解释器参数运行 Shell 脚本 【 1. Shell 解释器、Shell语言、Shell脚本 】 …

C++学习(二)

我们是在学习过了C语言&#xff0c;基础上来看这篇文章的&#xff0c;如果你是直接学C&#xff0c;这篇文章不太适合你的&#xff0c;因为这里只讲C基础中与C语言不同之处。 一.main函数区别 在C语言中&#xff0c;我们写main函数是不是可以省略前面的int,但是在C中&#xff…

React(2): 使用 html2canvas 生成图片

使用 html2canvas 生成图片 需求 将所需的内容生成图片div 中包括 svg 等 前置准备 "react": "^18.2.0","react-dom": "^18.2.0","html2canvas": "^1.4.1",实现 <div ref{payRef}></div>const pa…

Character Controller Smooth

流畅的角色控制器 Unity的FPS解决方案&#xff01; 它是一种具有非常平滑运动和多种设置的解决方案&#xff1a; - 移动和跳跃 - 坐的能力 - 侧翻角度 - 不平整表面的处理 - 惯性守恒 - 重力 - 与物理物体的碰撞。 - 支持没有家长控制的平台 此解决方案适用于那些需要角色控制器…

Spring Boot 整合 MinIO自建对象存储服务

GitHub 地址&#xff1a;GitHub - minio/minio: The Object Store for AI Data Infrastructure 另外&#xff0c;MinIO 可以用来作为云原生应用的主要存储服务&#xff0c;因为云原生应用往往需要更高的吞吐量和更低的延迟&#xff0c;而这些都是 MinIO 的优势。安装过程跳过。…

(七)独立按键

文章目录 独立按键原理图三行代码法简单概述代码书写键码推算如何使用短按键长按键 状态机法简单概述代码书写键码推算如何使用短按键长按键 现象 独立按键原理图 三行代码法 简单概述 代码书写 u8 Trg 0x00;//短按键 u8 Cont 0x00;//长按键 void BtnThree(void) {u8 reada…

李沐机器学习系列2--- mlp

1 Introduction LP中有一个很强的假设&#xff0c;输入和输出是线性关系&#xff0c;这一般是不符合事实的。 通过几何的方式去对信息进行理解和压缩是比较高效的&#xff0c;MLP可以表示成下面的形式。 1.1 从线性到非线性 X ∈ R n d X \in R^{n \times d} X∈Rnd表示输入…