7

Emotion 文档告诉我们如何在 css 道具中进行可重用的媒体查询。这允许我们在 css prop 中进行以下查询:

<div
  css={{
    color: 'green',
    [mq[0]]: {
      color: 'gray'
    },
    [mq[1]]: {
      color: 'hotpink'
    }
  }}
>

使用mq[0]mq[1]引用断点数组中的前两项。例如: const breakpoints = [576, 768, 992, 1200]

此外,本文更进一步,展示了如何使用断点对象获取命名的可重用媒体查询。它首先根据情感文档创建一个类似的功能,但对于对象:

const mq = n => {
  const bpArray = Object.keys(bp).map(key => [key, bp[key]]);

  const [result] = bpArray.reduce((acc, [name, size]) => {
    if (n === name) return [...acc, `@media (min-width: ${size}px)`];
    return acc;
  }, []);

  return result;
};

这允许我们创建一个带有命名媒体查询的断点对象:

// object
const breakpoints = {
  sm: 500,
  md: 768,
  lg: 992,
  xl: 1200
};


// query
${mq('sm')} { 
  color: gray;
}

到目前为止,一切都很好。

我现在想在情感风格的组件中做类似的事情。因此,我创建了一个断点对象和与上述文章中提到的相同的函数。

然后我尝试在我的情感样式组件中使用速记媒体查询——就像这样:

import styled from '@emotion/styled'

const Container = styled.div`
  ${mq('sm')`max-width: 750px;`}
  ${mq('md')`max-width: 970px;`}
  ${mq('lg')`max-width: 1170px`}
`

但是当我尝试这个时,它不起作用。我收到以下错误消息:

TypeError: Object(...) is not a function

知道为什么会发生这种情况以及我能做些什么来让它发挥作用吗?

谢谢。

4

2 回答 2

5

澄清一下,OP 发布的内容主要存在轻微的语法错误(插值字符串中不应有额外的反引号)。

他的代码的完整示例(包括类型注释)如下所示:

const breakpoints: { [index: string]: number } = {
  sm: 500,
  md: 768,
  lg: 992,
  xl: 1200,
};

const mq = Object.keys(breakpoints)
  .map((key) => [key, breakpoints[key]] as [string, number])
  .reduce((prev, [key, breakpoint]) => {
    prev[key] = `@media (min-width: ${breakpoint}px)`;
    return prev;
  }, {} as { [index: string]: string });

const Container = styled.div`
  ${mq["sm"]} {
    max-width: 750px;
  }
  ${mq["md"]} {
    max-width: 970px;
  }
  ${mq["lg"]} {
    max-width: 1170px;
  }
`;
于 2020-12-13T22:31:37.773 回答
0

@bluenote10 的答案是正确的。如果您想在 css 定义中使用 IDE 添加自动完成功能,这是一种增强的方法。

export const BREAKPOINTS = {
  xs: 420,
  sm: 576,
  md: 768,
  lg: 900,
  xl: 1200,
  xxl: 1536
};

type Mq = keyof typeof BREAKPOINTS;
export const mql = Object.keys(BREAKPOINTS)
  .map((key) => [key, BREAKPOINTS[key as Mq]] as [Mq, number])
  .reduce((prev, [key, breakpoint]) => {
    prev[key] = `@media (min-width: ${breakpoint}px)`;
    return prev;
  }, {} as Record<Mq, string>);
于 2022-01-19T11:03:06.907 回答