What is the difference between module and scoped styles in Vue? - vue.js

What is the difference between <style module> and <style scoped> in Vue?
The official documentation (link1, link2) states only that scoped uses PostCSS transformation and module uses CSS Modules. But what is the real functional difference between the two?
(Note: If the PostCSS transformation they use is that plugin, it actually uses CSS Modules...)

They're both ways of handling scoped CSS and do pretty much the same thing. The way they handle it is a bit different though.
Scoped styles in Vue is just normal CSS but with some additional classes added scoping. It's similar to the shadow DOM in that it will scope things out to a component. The benefit of this approach is you carry on writing CSS how you usually do but you get some additional scoping if that's what you want.
CSS Modules is different in that it uses Webpack to compile unique class names based on the block and class. It's kind of automatically creating unique BEM classes. It has a lot of additional functionality above CSS (which you don't have to use).
CSS Modules is not a Vue specific thing so if you learnt that you could apply it to any build where you can import CSS Modules. However Vue CSS scoping is so simple that there isn't really anything additional to learn if you know CSS (a couple of selectors is all really).
CSS Modules classes will be built by webpack as .{component}__{className}__{randomHash}.
Scoped Vue CSS will be built by postcss as .{className}[data-v-{componentHash}]. The componentHash is applied to every element in that component.
Both methods are compiling CSS based on hashes and class names. Scoped CSS is also adding additional data attributes to the HTML for it's scoping. CSS Modules is using javascript a bit more to manage styles.
They're both doing pretty much the same thing though and for me the only real difference is how the classes are created. I guess CSS Modules should be more performant due to the lower specificity of all classes but it will really depend on the person writing the CSS. In my personal opinion I would stick with the simpler one (I'll leave you to decide which one that is)

Related

AsmComponentsModule does not have exported components

Our team needs to add custom code to the ASM module in order to make SSO login possible in our project, and we realised the AsmComponentsModule doesn't export its declared components. This made it difficult for us to reuse them, since we had to create our own custom module which is a copy of AsmComponentsModule, containing components that are simply extensions of the components declared on it.
This is problematic, since we also had to duplicate HTML and SCSS files. The problem would be even bigger if this module had even more components declared on it.
Is there a better way to do this? Or we should expect a future fix containing the exports array on this module?
PR Fix: https://github.com/SAP/spartacus/pull/15282
Will be released into 4.3.1 and 3.4.7 patches.

loading different scss file based on current language - nuxt

i'm trying to implement rtl/ltr in my nuxt application.
this is my project structure
|--assets
|--scss
|--**/*.scss
|--bundle.scss
|--bundle-rtl.scss
so styles are compiled into the bundle and bundle-rtl normally.
the problem is this .. how can i switch between theses two scss files without changing them manually within my nuxt.config (automatically change the scss file when the language is changed).
among these files is a mixin file with many mixins related to rtl and ltr switching so i need to use them in each vue file that i have. which is why i can't just compile them to css (with gulp or webpack for example) and include them in head.
aside from all of this, is this the best way to implement ltr/rtl in nuxt or is there a better way?
In my opinion, you should write modern CSS that takes this into account rather than having a duplicate. This will have the benefit to also be usable by other languages.
Check this awesome article: https://css-tricks.com/building-multi-directional-layouts/

Lazy-loaded overriden or custom CMS Components

I was trying to test Lazy-loaded CMS components on ongoing Spartacus project with version 2.1.4 and I wasn't able to properly display the components. Before I continue with further investigation, I just want to check couple of things:
is it possible to lazy-load components which we have overriden, for example BannerComponent, SearchBoxComponent...?
is it possible to apply lazy-load on custom CMS components ?
are there any limitations when this feature won't work? Maybe in combination with some other feature?
There are many OOTB Spartacus CMS components that we have overriden in our project, and I have defined lazy-load feature for couple of them like it is described here https://sap.github.io/spartacus-docs/customizing-cms-components/#lazy-loaded-cms-components-code-splitting inside modules for certain components, this is one example:
breadcrumb.module.ts example here
and after the build, chunks are there, visible from source tab also, but components aren't displayed and there are errors because of missing modules (such as CommonModule, RouterModule, basically for everything that we used in our custom implementation..) which are declared in corresponding module but for some reason aren't registered at all.
Any guesses what we should fix in order to check if this feature is working in our architecture?
I suggest to stick "CMS-driven lazy loading of feature modules" (as explained here: https://sap.github.io/spartacus-docs/lazy-loading-guide/) instead of lazy loading of separate components (using component: () => import()) as it's simpler to make it work.
The idea is to define CMS mapping inside the module, which then will be lazy loaded (with components, services, etc.) instead of lazy loading separate (and decoupled) components. Then, in the root application, we let Spartacus know, which feature module should be loaded, when we want to render specified component (example: https://sap.github.io/spartacus-docs/lazy-loading-guide/#configuration-of-lazy-loaded-modules)
Using component: () => import() will lazy load only component code (no module, unless defined in the same file), such a component will have access to global (root) services, etc. It's still useful in some cases, but a bit problematic to make it work in more than basic scenarios (but this will improve in Spartacus 3.x/4.0).
Regarding your questions:
is it possible to lazy-load components which we have overriden, for example BannerComponent, SearchBoxComponent...?
Yes. Briefly explained here: https://sap.github.io/spartacus-docs/lazy-loading-guide/#wrapping-library-code-in-a-lazy-loaded-module
is it possible to apply lazy-load on custom CMS components ?
Yes.
are there any limitations when this feature won't work? Maybe in combination with some other feature?
As explained above.

Vue.js components - handling translations within a component library from a consuming project without repetition

I fully expect this is a little niche, and I'm not sure if there's a solution, but I have an interesting situation.
We have a library of Vue components we use in our projects, from form fields to data tables. Some of these components need aria labels, buttons, labels, messages, and so on. Most of our projects will need translating into any number of languages, on the fly, often via user-selectable drop-down menus. Translation is handled by Vue i18n.
I have begun adding slots and props as required to allow this translation, but I realise it's going to be a lot of repetition to use the components, as it will be necessary to translate them each time they are used, some of which may be used hundreds of times in a large project.
The components are part of a library which has no knowledge of any current translation, and won't have access to the translated strings.
What I'm wondering is if anyone has an idea for how to essentially say 'here are some default slots and props for this component, which will override the defaults set in the component itself, but will apply every time I use this component in this project unless otherwise stated'.
I can't make these the defaults in the component itself, as what the default will be differs from user to user.
The only two thoughts I've had are:
Somehow passing the instance of the vue-i18n plugin to the components as they're used, allowing them to find their own translation strings.
Creating 'wrapper' components which are part of the current project, and thus do have access to translations, which can set a lot of these repetitive props and slots for us. This seems pretty reasonable, but doesn't solve where some components use others (e.g. our form components can be used by themselves, or initialised by a form builder, which then wouldn't know to use the 'middleware' components)
Am I missing an obvious solution?

Is leaving the <style> section out because I already imported all my styles in the App.vue file a bad practice?

I found the way that components are laid out very comfortable considering I use SASS with the 7-1 architecture for my styling. I thought I would be writing SASS directly in the component file but when I searched on Google how to use it with Vue I found out that I can just import main.scss in App.vue and never have to declare a <style></style> section in any other component.
My question is whether or not this is a good practice.
Its fine, its an architecture choice, some prefer a more centralized styling while other use the style tags with or without the scope feature.
Depends also on your needs if styles repeat themselves in many components it makes sense to centralize, whereas a highly specialized style you might want to consider putting in the tag although not a must.