Extends in vue.js component to use parent style - vue.js

I've a third party component that I'm extending - while I want to reuse template and style section, I need to alter the behaviour of it. So, the content of my vue file looks something like this:
<script>
import Foo from 'foo';
export default {
name: 'Bar',
extends: Foo
}
</script>
Unfortunately, while template section of Foo is reused in my Bar the same doesn't happen for the style section - I've to copy it in its entirety from Foo otherwise no styles will be applied.
How can I reuse parents style section?

When you define a Vue component, you have an optional section, where you can either place inline CSS or import an external file. By default, when creating a component (for the sake of argument call it any-component.vue) I will include the following section:
<style scoped>
#import ‘./any-component.css’
</style>
The scoped parameter prevents the CSS propagating elsewhere in the DOM, so the styling is only applied to the component itself and does not corrupt other components. But depending on your needs you can remove it.
So this gives you two solutions: there is nothing to stop you either importing a CSS file into the parent without the scoped qualifier; lor, importing the same CSS file into multiple components (when you want a consistent look and feel). With a view to avoiding unintended consequences, I would opt for the latter.
Hope that helps.

Related

Vue including global styles without repeating the styles for each component

I have an app and would like to include some global styles that I can use anywhere in the app like this:
.btn {
...
}
In webpack I already have this for _variables.scss to include things like $my-color: $fff and that is wired up like this in my loaderOptions:
{
additionalData: `#import "#/styles/_variables.scss";`
}
Obviously for some global styles I could do the same thing, however, this will cause my styles like .btn to load as many times as components that I have.
Logically it would seem best to just go into my root Vue component and add global <style lang="scss"></style>.
However, I am upgrading a legacy jQuery app and it is being piecemealed and instead of one root app component, I have several roots for parts that have been converted to Vue. I don't have a central place to load these styles.
For instance I have searchBar and checkout apps that are instantiated using Vue.extend (so they are all part of the same instance). There aren't just two apps, there are quite a few. If I include the global styles in the root of any of them it... feels... icky...
Is there any way around this or should I set the global styles in a random app with a TODO to refactor once everything is ported over?
Ideally I would do the same thing I'm doing with the _variables.scss but having the styles duplicated for each component is a non starter for me.
In this scenario you do not need to worry about how webpacks CSS loaders are working.
You can simply go into your main.js and import '#/styles/globals.scss' to load the styles globally.

Exclude Bootstrap styling from certain routes in Vue.js

I have a single-page vue 2 app made with the cli-tool. Most of my routes use Bootswatch (Bootstrap) styling. But one shouldn't at all. This is only a problem because the Bootstrap affects the body and html styles and generally messes with the other styling. The route shouldn't use Bootstrap gets affected even when I #import the Bootstrap in a scoped <style> only to the routes that should use it. This happends if I first visit the Bootsrap routes and then to the isolated one. How should I go about doing this so that one of my routes is completely isolated when it comes to styling? If it's impossible or very impractical, suggest other ways of doing this. If this weren't a single-page-app this would be easy. But I'd prefer it be one.
I succeeded in encapsulating bootstrap import within a class called 'bootstrap-inside' and assigning it to the #app (Index route for example) div that is supposed to be styled with Bootstrap.
.bootstrap-inside {
#import '~bootstrap/scss/bootstrap.scss';
}
From now on, if you want to use bootstrap, you just have to use .bootstrap-inside in your component/view/layout.
I would suggest creating a view layout for your no-bootstrap pages and set your route to extends that layout (i can give you the solution for this too if you want).
I can mention this answer of another thread about limiting the scope of bootstrap styling in case you go through unexpected bootstrap behavior.
The easiest solution I know for this is to manually reset every css property for a given selector.
You could add an id / class to the root element of your page, and explicitly reset all css properties for all its childs. It would override the default bootstrap styles, but not remplacing its classes though.
Here's a class that would reset every css property: reset css for a div #15901030
It's not super convenient but it should work!

Disable Spartacus component styles

The documentation states that that component styles can be skipped
Skipping Specific Component Styles
Component styles are optional, because they are pulled in from the style library. Therefore, you might want to disable some standard component styles entirely. To disable standard component styles, you can add the component selectors to the $skipComponentStyles list. The following is an example that demonstrates skipping two standard components from the style library:
$skipComponentStyles: (cx-product-carousel, cx-searchbox);
$skipComponentStyles: (cx-product-carousel, cx-searchbox);
Skipping specific component styles might be beneficial if you need to create styles from scratch and do not want to override specific style rules coming from the Spartacus style library.
Where should this be done? I can't get that from the documentation. My first guess should be the global style.scss but for example the following does not work:
#import '~#spartacus/styles/index';
$skipComponentStyles: (header, cx-media, cx-banner, cx-category-navigation);
You're almost right, you just need to swap the 2 lines. The sass variable will be used inside the import of the Spartacus styles, otherwise the variable defaults to an empty var. so, the following will work:
$skipComponentStyles: (header, cx-media, cx-banner, cx-category-navigation);
#import '~#spartacus/styles/index';

Add SCSS file to VueJS app, but not each component

I have the feeling I'm thinking way too much into this, but I cannot find what I'm looking for in this pattern.
I have a VueJS app with several components and it all works. I'm using style-resources-loader to pull in my global variables and mixins and such into each component. This works as intended.
module.exports = {
pluginOptions: {
'style-resources-loader': {
preProcessor: 'scss',
patterns: [
path.resolve(__dirname, './src/styles/variables.scss'),
path.resolve(__dirname, './src/styles/text-mixins.scss'),
path.resolve(__dirname, './src/styles/interactive-mixins.scss'),
],
}
},
}
I also have an app-level style sheet. Resets, general layouts, etc. These are not things I want pulled into the SCSS processing of each component - just something I want output in the final CSS for the application.
Everything I find when looking for "how to add SCSS file to Vue" is all about the resource loader for the component processing. I cannot include the global styles in this way and then rely on de-duping to remove the extraneous ones - the imported global styles are being scoped by the built-in component scoping, which is causing bloat and is just generally a bad pattern.
I also don't want a separate Webpack build and CSS file as the end product if I can avoid it.
I can put this inside say the root level App style block, but that's not a great place to work with page-level CSS. It would be ideal to have this a/a set of SCSS files separate from components, but part of the Vue App's SCSS compiling.
Update
Had a big block of stuff here, not sure how it got in that state but that is not the case now and I cannot recreate it.
Throw them in your entrypoint.
Literally include the scss within the start. Like this in your app.ts or app.js :
import Vue from 'vue'
import Buefy from 'buefy'
import 'buefy/dist/buefy.css' <-- like this
Vue.use(Buefy)
If your webpack is setup correctly, e.g. Vue cli, then it doesn't care how the scss is found. It will just inject it globally. Vue components are also global unless you specify scoped scss.
Example from https://buefy.org/documentation/start/

Aurelia: Deriving a component from another and reusing HTML

In Aurelia, how do I derive a component from another component reusing the HTML view from the source component?
I have a component BarGraph that renders simple bar graphs. This component has files bar-graph.js and bar-graph.html. I want to derive a set of components from BarGraph. Each *BarGraph class will have custom logic, but all of the derived components will have the same HTML as the original component. I want to store the HTML for the components in one file and reuse it in each *BarGraph class.
You can use #useView. For example:
import {useView} from 'aurelia-framework';
#useView('./bar-graph.html')
export class AnotherBarGraph {
// Your logic here
}
Documentation here
EDIT: Extending custom element using inheritance is currently not supported. An important point is "Inheritance of Bindables doesn't work". See this issue.