How to style a nested component from its parent component in Vuejs? - javascript

I am going to create a layout like 'header sidebar main-content sidebar footer ' with flexbox by Vuejs.
I created separate .vue files for each part of the layout , I mean something like a sidebar.vue and a header.vue and so on ....
And I am going use them in App.vue file like :
<template>
<div id="app">
<app-header ></app-header>
<app-sidebar></app-sidebar>
<app-content></app-content>
<app-sidebar></app-sidebar>
<app-footer></app-footer>
</div>
</template>
<script>
import header from "./components/header";
import sidebar from "./components/sidebar";
import content from "./components/content";
import footer from "./components/footer";
export default {
components: {
"app-header": header,
"app-sidebar": sidebar,
"app-content": content,
"app-footer": footer
}
};
</script>
<style lang="scss">
body {
margin: 0;
padding: 0;
}
#app {
border: 3px solid red;
min-height: 100vh;
display: flex;
flex-wrap: wrap;
> * {
border: 1px solid black;
}
}
the main problem is I can not select these custom nested components from App.vue file to style them. for example i can not use app-header{} like other normal tags in html and css to select it and style it within style tags inside of App.vue file . is there anyway to solve it ?
NOTE : I know I can assign a class to each of these nested components and then select them to use with css class selector .

I would handle this by creating a property in each of the child components (maybe HeaderClass, BodyClass, and so on). That way, any component that consumes these child components can pass whatever classes they desire and style them accordingly.
<app-header :headerclass="parent-header-class"> </app-header>
Inside of your child component, you can use these properties and v-bind the class inside the HTML, as shown in the example below:
<template>
<div :class=`${headerClass} internal-class-example button`> </div>
</template>
Note: This does not allow you to use any scoped parent CSS to pass to the child. The classes you pass down must be global. Otherwise, the child component will not know what it is.

Related

How i can apply a background image to the body of only ONE Component React

I have a main component on every page, which is Navbar, and I have another component, which is a page to contact us. I want to make a background for a component that contact us, but it does not affect the Navbar? Also, if I give body tag the background image, all the other components will take the same background as the photo cuz i give it to the body! what i can do in this case?
You have to wrap each component in a different div.
<div>
Navbar
</div>
<div style={{backgroundColor: 'color here'}}>
Contact us
</div>
Style inside the div or add a className and style in a separate file with CSS:
<div className="yourClass">
Contact us
</>
and in a separate .css file:
.yourClass {
background-color: 'color name';
}
Simple HTML question, just apply the class to only one of your elements, and don't have them nested.
<containing-element>
<navbar />
<contact-page className="contact" />
</containing-element>
You can then style .contact
.contact {
background-color: #FF0000;
}

What's the CSS behavior in React JS? [duplicate]

This question already has answers here:
Why is css imported into the global scope in React?
(2 answers)
Closed 1 year ago.
Note:
No need to understand my code, just focus on the 3 components files Palette.js, Palette.css and footer.js
Firstly I created my footer component in Palette.js and write CSS for its styling in Palette.css, which is linked to only Palette.js. in order to use the footer in different files, I created a new footer component in a separate file[footer.js] but forget to import styles from Palette.css which are used to style my footer, I removed my whole footer component from Palette.js and import my footer component from footer.js in Palette.js
My footer component looks like [footer.js without any stylesheet]
import React, { Component } from 'react'
function Footer(props){
const { creater, emoji, paletteName} = props;
return (
<footer>
<h2 className="palette-creater">Palette Created by : {creater}</h2>
<div className="palette-identity">
<span className="palette-emoji">
{emoji}
</span>
<span className="palette-name">
{paletteName}
</span>
</div>
<h3 className="palette-copyright">All rights reserved # Colors.io 2021</h3>
</footer>
)
}
export default Footer;
My Palette.js looks like
import React, { Component } from 'react'
import ColorBox from './ColorBox';
import NavBar from './NavBar';
import Footer from './footer' ;// imported my footer
import './Palette.css';
//styles for footer component in footer.js are still in this file
export default class Palette extends Component{
render(){
return (
<Footer creater={creater} emoji={emoji} paletteName={paletteName} />
)
}
}
As you can see my footer.js has no styles and my Palette.js has a CSS file palette.css which has styles for my footer. Also, the styles for my footer in the Palette.css looks like
footer{
background-color: #ced0d1;
font-family: 'Red Hat Display', sans-serif;
padding: 5px;
text-align: center
}
.palette-creater{
padding-top: 10px;
padding-bottom: 10px;
margin: 0;
font-weight: 500;
letter-spacing: 3px;
}
.palette-identity{
display: flex;
justify-content: space-around;
}
.palette-name{
font-size: 1.1rem;
font-weight: 400;
}
.palette-emoji{
display: block;
font-size: 1rem;
}
.palette-copyright{
margin:0;
padding-bottom: 5px;
}
How my styles are applying to the footer component from Palette.css, which is not even linked with the footer.js, and also no matter wherever I import my footer component from footer.js and used it, it's always applying styles from Palette.css. My application is pretty large, I cannot post all the code.
Example
just think of that I make a new file app.css and linked it with only App.js and writes all the styles of the application in app.css, then all the components take styles from here.
I believe you'll be able to find your answer here: React CSS - how to apply CSS to specific pages only
The key element from the above link is that "Create React App bundles all your css files into one so all the styles will be available everywhere in you app (on every rendered component). Be aware that CRA is a Single-Page Application (SPA) so you can't think in "pages" but rather in "rendered component" in the DOM."

binding style into child component in vue

I have a child component. I want to bind inline style into that component. I want to pass these style properties( height: 200px; overflow-y: scroll).
I have tried by passing like this:
<Childcomponent style="height: 200px; overflow-y: scroll;" /> but not working.
Then i have tried like this:
<Childcomponent :style="{'height': '200px'; 'overflow-y': 'scroll'}" /> it is also not working.
How to bind inline style to this child component?
Yo can do following:
<div style="height: 200px; overflow-y: scroll;">
<Childcomponent />
</div>
If you want it to be done in your way, you have to create prop in your component, pass styles into it and then apply those on tag inside of your component.
Like that:
In Childcomponent file add
prop {
myStyles: String;
...
}
Those styles you will use in tag you want (I believe, in root one).
Then you can pass styles from parent in this way:
<Childcomponent my-styles="height: 200px; overflow-y: scroll;"/>

Vuejs template inheritance

How can I use template inheritance (Like what jade has, extends file.jade and then the blocks with the same name would be overwritten)?
I know that I can do everything with composition, but for components like footer and header which appear on every single page except one or two (e.g.login page) I must write them on every single component. In my app I have a two level navigation and it seems painful to repeat them on every one of those child components :(
I know that I can use jade and then inherit a jade file within my components, but it seems wrong because I would have some jade and some Vue files, is there any other way to do this?
// Component.vue
<template lang="jade">
extends ./StandardLayout
block content
router-view
</template>
// StandardLayout.Vue
<template lang="jade">
div
navbar
div.container
div.spacer
div.row
block content
<template>
What I've settled for, is a layouts folder filled with jade layouts and I use them to extend my components. I used vue-cli with webpack template.
In the most general case if you have to repeat the same HTML over and over, one option you could use is <partial>s.
<partial name="header"></partial>
<div>My content content</div>
<partial name="footer"></partial>
Where you declare partials as
Vue.partial('header', '<h3>This is the title: {{title}}</h3>')
Vue.partial('footer', '<footer>Mini footer</footer>')
However if you are building a Single Page Application the strategy you could follow is to simply have a header and a footer around your <router-view>, here is a jsfiddle that demonstrates how to do.
https://jsfiddle.net/gurghet/vdqutw2y/
<header><h1>
My title: {{title}}
</h1></header>
<p>
<a v-link="{ path: '/foo' }">Go to Foo</a>
<a v-link="{ path: '/bar' }">Go to Bar</a>
</p>
<router-view></router-view>
<footer>Such footer, many links, wow!</footer>
If you know Chinses, please look it
// Base Component
<template>
<div class="base-thing special-class">
<Button />
</div>
</template>
<script>
import Button from './ButtonClick'
export default {
components: { Button }
}
</script>
// Inheriting Component
<script>
import BaseComponent from './BaseComponent'
import Button from './OtherButton'
export default {
extends: BaseComponent
components: {
Button
}
}
</script>
The Button of Child Component will be replaced OtherButton. We can do something in the OtherButton

Using flexbox with angular 2 components

I want to update visual side(grid, colors) of my angular 2 application. Old layout was build with bootstrap 4, which I don't really need anymore. I decided to go for plain css3, and build grid with flexbox. I made a preview of this grid on codepen.
However implementation in project is hard and I am now stuck. Let's consider an example:
import {Component} from 'angular2/angular2';
#Component({
selector: 'some-component',
template: `
<aside class="col-4 main-aside"></aside>
<section class="main-section center"></section>
`
})
export class SomeComponent { }
If I bootstrap this component within, for example .container I may get this result:
<body>
<!-- .container is flex parent -->
<div class="container">
<some-component>
<!-- .main-aside and .main-section should be flex children -->
<aside class="main-aside"></aside>
<section class="main-section center"></section>
</some-component>
</div>
</body>
As you can see the flex chain parent -> child is broken because of component "selector" between them. I menaged to fix this by adding styles: display: flex; width: 100%; to component selector from chrome dev tools, however I don't know how to make this work from code perspective nor is it the best way to do so.
I would really appreciate any help, because I have no idea how to fix this with the exception of not using flexbox.
I am using angular 2.0.0-alpha.44
And yes, I am aware of angular's alpha state.
I fixed this issue by adding styles to component. For example:
:host {
display: flex;
}
:host {} was the key.
:host selector solves the problem but you end using it very often in many components.
I used instead the following global CSS:
.row > * {
display: flex;
flex-basis: 100%;
}
The angular team released their own flex-layout package, so you don't need to write it by your self anylonger:
https://github.com/angular/flex-layout

Categories

Resources