Alexandr Vysotsky
Alexandr Vysotsky

Reputation: 1131

How to remove component styles for unmouned components?

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.

Upvotes: 7

Views: 3619

Answers (2)

Alexandr Vysotsky
Alexandr Vysotsky

Reputation: 1131

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.

Upvotes: 2

Dimitar Christoff
Dimitar Christoff

Reputation: 26165

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.

Upvotes: 2

Related Questions