How to remove component styles for unmouned components?
Asked Answered
B

2

7

The problem: component styles keeped when component was unmounted.

In this example, I unmount(and destroy) Unused component, but styles from this component still affect on page.

Background: I'm trying to adapt existed vue codebase for SPA(with vue-router). This problem happens when component for was changed, but styles from previous component affect on new. I want to solve it without changes in styles(e.g. creating wrappers).

At the current moment I see only one posible way: change styles. But I want to have something like this (I have not tested it yet). When component mounted it add styles, when unmounted it remove styles.

Barny answered 9/7, 2019 at 10:40 Comment(3)
So when the component is there, you do want it to affect styles outside of the component itself right? Or do you only want the styles to be affected within the component?Etom
"So when the component is there, you do want it to affect styles outside of the component itself right" - rightBarny
I think i can try to use manualInject: github.com/vuejs/vue-style-loader#optionsBarny
B
2

Updated answer for style loader version v1.0.0

They added special option injectType:

injectType

Type: String Default: styleTag

Allows to setup how styles will be injected into the DOM.

Possible values:

styleTag singletonStyleTag lazyStyleTag lazySingletonStyleTag linkTag

Original answer before v1.0.0 release

Finally i started to use style-loader/useable instead of vue-style-loader for specific files. I added extra one rule('useable-styles') for scss loader. Here part of my webpack config:

export default {
  module: {
    scss: {
      test: /\.scss$/,
      oneOf: {
        'useable-styles': {
          test: /AppHomepage\.scss$/,// pattern for useable styles
          use: {
            'style-loader': {
              loader: 'style-loader/useable',
              options: {
                sourceMap: false,
              },
            },
            'css-loader': { /*...*/ },
            'resolve-url-loader': { /*...*/},
            'sass-loader': { /*...*/},
          },
        },
        'vue-modules': { /*...*/},
        vue: { /*...*/},
        normal: { /*...*/},
      },
    },
  },
};

Then I load styles in JS, like this:

import styles from './AppHomepage.scss';

// @vue/component
export default {
  name: 'app-homepage',
  beforeCreate() {
    styles.use();
  },
  destroyed() {
    styles.unuse();
  },
};

And call styles.use(); or styles.unuse(); when it needed and it works.

It is not ideal solution, but it will work as temporary solution and wait for refactoring.

Barny answered 9/7, 2019 at 12:43 Comment(2)
So which option should I choose in style loader version v1.0.0?Additive
just use this loader loader: 'style-loader/useable',Barny
M
2

The accepted answer is now out of date. to use the new style-loader API, something like this via injectType:

{   
  test: /\.theme\.(sa|sc)ss$/,
  use: [
    {
      loader: 'style-loader',
      options: {attributes: {id: 'theme-sheet'}, injectType: 'lazySingletonStyleTag'}
    },
    {loader: 'css-loader'},
    {loader: 'sass-loader'}
  ]
}

docs: https://github.com/webpack-contrib/style-loader#lazysingletonstyletag

the style.use(); / style.unuse() remains the same.

Murdoch answered 11/11, 2019 at 15:5 Comment(1)
Thank you, i see that in 1.0.0 release they added new feature: injectType which will solve original issue. Will update my comment above.Barny

© 2022 - 2024 — McMap. All rights reserved.