Включение стилей в компоненте-наследнике

Есть компонент App.vue. Внутри него объявлен стиль scss:

.roboto-text {
    font-family: Roboto;
    font-style: normal;
    font-weight: 500;
}

Разметка:

<template>
  <v-app>
      <div>
        <Head/>
      </div>
  </v-app>
</template>

Есть компонент Head.vue. Я хочу сделать extened этого стиля внутри него:

<style scoped lang="scss">

    .user-info {
        padding-top: 0;
        @extened .roboto-text;
    }
</style>

Этот стиль не экстендится. Почему?

Ошибка:

SassError: The target selector was not found.
Use "@extend .roboto-text !optional" to avoid this error.
    ╷
106 │     @extend .roboto-text;
    │     ^^^^^^^^^^^^^^^^^^^^
    ╵
  /home/eurvanov/vuejs/adeo-dataplatform-dictionaries/src/components/Menu.vue 106:5  root stylesheet

 @ ./node_modules/vue-style-loader??ref--8-oneOf-1-0!./node_modules/css-loader/dist/cjs.js??ref--8-oneOf-1-1!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/src??ref--8-oneOf-1-2!./node_modules/sass-loader/dist/cjs.js??ref--8-oneOf-1-3!./node_modules/vuetify-loader/lib/loader.js??ref--18-0!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/components/Menu.vue?vue&type=style&index=0&id=9bcc0be2&scoped=true&lang=scss& 4:14-518 14:3-18:5 15:22-526
 @ ./src/components/Menu.vue?vue&type=style&index=0&id=9bcc0be2&scoped=true&lang=scss&
 @ ./src/components/Menu.vue
 @ ./node_modules/cache-loader/dist/cjs.js??ref--12-0!./node_modules/babel-loader/lib!./node_modules/vuetify-loader/lib/loader.js??ref--18-0!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/App.vue?vue&type=script&lang=js&
 @ ./src/App.vue?vue&type=script&lang=js&
 @ ./src/App.vue
 @ ./src/main.js
 @ multi (webpack)-dev-server/client?http://192.168.1.68:8080&sockPath=/sockjs-node (webpack)/hot/dev-server.js ./src/main.js```


Ответы (1 шт):

Автор решения: Vasiliy Rusin

Общий ответ на вопрос.

В Vue на данный момент нет достаточно удобного способа наследовать стили. Самым простым обходным решением является использование миксинов. Создайте отдельный .scss файл. Поместите туда стили из .roboto-text, импортируйте этот файл и через @include добавляйте стили.

mixins.scss

@mixin roboto-text {
    font-family: Roboto;
    font-style: normal;
    font-weight: 500;
}

Parent.vue

<style scoped lang="scss">
    @import "mixins.scss";

    .some-class {
        @include roboto-text;
    }
</style>

Child.vue

<style scoped lang="scss">
    @import "mixins.scss";

    .other-class {
        @include roboto-text;
    }
</style>

mixins.scss можно импортировать глобально. Это скорее всего будет масимально не очевидно для вашей IDE но вы сможете использовать миксины не импортируя их.

Для этого нужно создать vue.config.js файл.

// vue.config.js
module.exports = {
  css: {
    loaderOptions: {
      // передать параметры для sass-loader
      sass: {
        // @/ алиас для src/
        // строка ниже будет интерпритированна как `src/variables.scss`
        // при сборке проекта, вначале эта строка будет добавлена во 
        // все style в SFC (Single File Component). А затем скомпилированна SCSS.
        data: `@import "@/mixins.scss";`
      }
    }
  }
}

Источник: gist.github.com

Мнение конкретно по Вашему случаю.

Для глобальных настроек (например основной шрифт). Можно поместить в не scoped стили в App.vue.

<style lang="scss">
    // стили которые будут доступны во всем проекте.
</style>

<style scoped lang="scss">
    // стили которые будут доступны только внутри данного компонента.
</style>
→ Ссылка