我已经创建了一个React (使用“”)和一些样式的组件。当我试图在React中呈现样式组件时,样式组件继承父(App.css)样式,并失去其独特的样式。是否可以维护样式组件?
这是我的代码:
Content.js
import React from 'react';
import ReactDOM from 'react-dom';
import Frame, { FrameContextConsumer } from 'react-frame-component';
import App from "./App";
class Main extends React.Component {
render() {
return (
<Frame head={[<link type="text/css" rel="stylesheet" href={chrome.runtime.getURL("/static/css/content.css")} ></link>]}>
<FrameContextConsumer>
{
({document, window}) => {
return <App document={document} window={window} isExt={true}/>
}
}
</FrameContextConsumer>
</Frame>
)
}
}
App.js
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import Card from './components/Card/index';
class App extends Component {
render() {
return (
<>
<div className="App">
{this.props.isExt ?
<img src={chrome.runtime.getURL("static/media/logo.svg")} className="App-logo" alt="logo" />
:
<img src={logo} className="App-logo" alt="logo" />
}
<Card />
</div>
</>
);
}
}
export default App;
风格:
import React from "react";
import styled, { css } from "styled-components";
export const CardWrapper = styled.div`
overflow: hidden;
padding: 0 0 32px;
margin: 48px auto 0;
width: 300px;
font-family: Quicksand, arial, sans-serif;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.05), 0 0px 40px rgba(0, 0, 0, 0.08);
border-radius: 5px;
`;
export const CardHeader = styled.header`
padding-top: 32px;
padding-bottom: 32px;
`;
export const CardHeading = styled.h1`
font-size: 24px;
font-weight: bold;
text-align: center;
`;
export const CardBody = styled.div`
padding-right: 32px;
padding-left: 32px;
`;
export const CardFieldset = styled.fieldset`
position: relative;
padding: 0;
margin: 0;
border: 0;
& + & {
margin-top: 24px;
}
&:nth-last-of-type(2) {
margin-top: 32px;
}
&:last-of-type {
text-align: center;
}
`;
export const CardInput = styled.input`
padding: 7px 0;
width: 100%;
font-family: inherit;
font-size: 14px;
border-top: 0;
border-right: 0;
border-bottom: 1px solid #ddd;
border-left: 0;
transition: border-bottom-color 0.25s ease-in;
&:focus {
border-bottom-color: #e5195f;
outline: 0;
}
`;
export const CardIcon = styled.span`
color: #666;
cursor: pointer;
opacity: .25;
transition: opacity .25s ease-in;
&:hover {
opacity: .95;
}
${props =>
props.big &&
css`
font-size: 26px;
`}
${props =>
props.eye &&
css`
position: absolute;
top: 8px;
right: 0;
`}
${props =>
props.small &&
css`
font-size: 14px;
`}
`;
export const CardOptionsNote = styled.small`
padding-top: 8px;
display: block;
width: 100%;
font-size: 12px;
text-align: center;
text-transform: uppercase;
`;
export const CardOptions = styled.ul`
padding: 0;
margin: 16px 0 8px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
justify-content: center;
width: 100%;
list-style-type: none;
`;
export const CardOptionsItem = styled.li`
&:nth-of-type(n + 2) {
margin-left: 16px;
}
`;
export const CardButton = styled.button`
display: block;
width: 100%;
padding: 12px 0;
font-family: inherit;
font-size: 14px;
font-weight: 700;
color: #fff;
background-color: #e5195f;
border: 0;
border-radius: 35px;
box-shadow: 0 10px 10px rgba(0, 0, 0, 0.08);
cursor: pointer;
transition: all 0.25s cubic-bezier(0.02, 0.01, 0.47, 1);
&:hover {
box-shadow: 0 15px 15px rgba(0, 0, 0, 0.16);
transform: translate(0, -5px);
}
`;
export const CardLink = styled.a`
display: inline-block;
font-size: 12px;
text-decoration: none;
color: #aaa;
border-bottom: 1px solid #ddd;
cursor: pointer;
transition: color 0.25s ease-in;
&:hover {
color: #777;
}
`;
构成部分:
import React from "react";
import {
CardWrapper,
CardHeader,
CardHeading,
CardBody,
CardIcon,
CardFieldset,
CardInput,
CardOptionsItem,
CardOptions,
CardOptionsNote,
CardButton,
CardLink
} from './Card';
const Card = () => {
return (
<>
<CardWrapper>
<CardHeader>
<CardHeading>Sign in</CardHeading>
</CardHeader>
<CardBody>
<CardFieldset>
<CardInput placeholder="Username" type="text" required />
</CardFieldset>
<CardFieldset>
<CardInput placeholder="E-mail" type="text" required />
</CardFieldset>
<CardFieldset>
<CardInput placeholder="Password" type="password" required />
<CardIcon className="fa fa-eye" eye small />
</CardFieldset>
<CardFieldset>
<CardOptionsNote>Or sign up with</CardOptionsNote>
<CardOptions>
<CardOptionsItem>
<CardIcon className="fab fa-google" big />
</CardOptionsItem>
<CardOptionsItem>
<CardIcon className="fab fa-twitter" big />
</CardOptionsItem>
<CardOptionsItem>
<CardIcon className="fab fa-facebook" big />
</CardOptionsItem>
</CardOptions>
</CardFieldset>
<CardFieldset>
<CardButton type="button">Sign Up</CardButton>
</CardFieldset>
<CardFieldset>
<CardLink>I already have an account</CardLink>
</CardFieldset>
</CardBody>
</CardWrapper>
</>
);
};
export default Card;
尝试为CardWrapper注入样式表:
/*global chrome*/
/* src/content.js */
import React from 'react';
import { useContext, FrameContext } from 'react';
import ReactDOM from 'react-dom';
import Frame, { FrameContextConsumer } from 'react-frame-component';
import { StyleSheetManager } from 'styled-components';
import App from "./App";
export const StyledFrame = (props) => {
const {
CardWrapper,
CardHeader,
CardHeading,
CardBody,
CardFieldset,
CardInput,
CardIcon,
CardOptionsNote,
CardOptions,
CardOptionsItem,
CardButton,
CardLink,
} = props;
class Main extends React.Component {
render() {
return (
<Frame head={[<link type="text/css" rel="stylesheet" href={chrome.runtime.getURL("/static/css/content.css")} ></link>]}>
<InjectFrameStyles>
{props.CardWrapper}
</InjectFrameStyles>
</Frame>
)
}
}
};
const InjectFrameStyles = (props) => {
const { document } = useContext(FrameContext);
return <StyleSheetManager target={document.head}>{props.CardWrapper}</StyleSheetManager>;
}
const app = document.createElement('div');
app.id = "my-extension-root";
document.body.appendChild(app);
ReactDOM.render(<Main />, app);
app.style.display = "none";
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if( request.message === "clicked_browser_action") {
toggle();
}
}
);
function toggle(){
if(app.style.display === "none"){
app.style.display = "block";
}else{
app.style.display = "none";
}
}
发布于 2021-03-10 02:13:28
我也有同样的问题。最后,我创建了一个名为StyledFrame的助手组件。
所发生的情况是,您的样式组件css正在父框架中呈现。您需要拦截这些样式,并将它们呈现在您的iframe中。这就是StyleSheetManager的作用。
您可以像使用框架组件一样使用StyledFrame。
import React, { useContext } from 'react';
import Frame, { FrameContext } from 'react-frame-component';
import { StyleSheetManager } from 'styled-components';
export const StyledFrame = (props) => {
const { style, children, ...otherProps } = props;
return (
<Frame
initialContent={
'<!DOCTYPE html><html><head></head><body><div class="frame-root"></div><div id="modal-root"></div></body></html>'
}
style={{ display: 'block', overflow: 'scroll', border: 0, ...style }}
{...otherProps}
>
<InjectFrameStyles>{props.children}</InjectFrameStyles>
</Frame>
);
};
const InjectFrameStyles = (props) => {
const { document } = useContext(FrameContext);
return <StyleSheetManager target={document.head}>{props.children}</StyleSheetManager>;
};https://stackoverflow.com/questions/66556752
复制相似问题