Vuejs, которого вы, возможно, не знаете — компонент с одним файлом

Vue.js
Vuejs, которого вы, возможно, не знаете — компонент с одним файлом

by yugasun from yugasun.com/post/there-ma…Эта статья может быть воспроизведена полностью, но должны быть сохранены первоначальный автор и источник.

Зачем нужны однофайловые компоненты

В предыдущих примерах мы прошлиVue.componentилиcomponentsАтрибуты используются для определения компонентов.Этот метод хорош во многих небольших и средних проектах, но в сложных проектах очень очевидны следующие недостатки:

шаблон строки: Отсутствие выделения делает написание хлопотным, особенно когда HTML состоит из нескольких строк.Хотя шаблон можно записать в html файле, это слишком навязчиво и не способствует развязке и разделению компонентов.CSS не поддерживается: означает, что CSS явно не учитывается, когда HTML и JavaScript состоят из компонентов.нет шагов сборки: ограничивается HTML и ES5 JavaScript, а не препроцессорами.

Расширение, предоставляемое Vuejs,.vueизкомпонент одного файлаРешения предоставляются для всех вышеперечисленных проблем.

Знакомство с однофайловыми компонентами

или использоватьЕсли вы хотите делать хорошую работу, вы должны сначала заточить свои инструментыисходный код в , вsrcСоздано в каталогеhello.vueфайл со следующим содержимым:

<template>
  <h2>{{ msg }}</h2>
</template>
<script>
export default {
  data () {
    return {
      msg: 'Hello Vue.js 单文件组件~'
    }
  }
}
</script>
<style>
h2 {
  color: green;
}
</style>

Затем используйте его в app.js:

// ES6 引入模块语法
import Vue from 'vue';
import hello from './hello.vue';

new Vue({
  el: "#app",
  template: '<hello/>',
  components: {
    hello
  }
});

В настоящее время проект не может быть запущен, потому что.vueФайл webpack не может быть ничем другим, он должен соответствоватьvue-loaderразобраться с этим, и осторожные друзья узнаютhello.vueВ настоящее время используется синтаксис ES6, и требуется соответствующее преобразование синтаксиса.loaderПреобразование ES6 в синтаксис ES5, совместимый с основными браузерами, здесь вам нужно использовать официально рекомендованныйbabelИнструменты.先安装需要的loader:

# hello.vue 文件中使用了 css,所以需要 css-loader 来处理,vue-loader 会自动调用
npm install vue-loader css-loader babel-loader babel-core babel-preset-env --save-dev

Некоторые люди сомневаются в том, что просто используютbabel-loaderЗачем вам нужно устанавливать так много инструментов сзади, потому что многие инструменты независимы,loaderПросто для моста, используемого веб-пакетом, и здесьbabel-coreа такжеbabel-preset-envЭто ядро ​​внедрения ES6 в ES5.

Давайте изменимwebpack.config.jsКонфигурация выглядит следующим образом:

module.exports = {
  // ...
  module: {
    // 这里用来配置处理不同后缀文件所使用的loader
    rules: [
      {
        test: /.vue$/,
        loader: 'vue-loader'
      },
      {
        test: /.js$/,
        loader: 'babel-loader'
      }
    ]
  }
}

Для настройки babel нам также нужно просто создать его в корневом каталоге проекта..babelrcфайл для настройки пресетов Babel и других связанных плагинов следующим образом:

{
  "presets": [ "env" ]
}

Но хотя все настроено, проект все равно сообщит об ошибке, и будет сообщено о следующей ошибке:

ERROR in ./src/hello.vue
Module build failed: Error: Cannot find module 'vue-template-compiler'

Некоторые люди недовольны.Очевидно, что они установили зависимости по официальной инструкции и правильно их настроили.Почему они до сих пор сообщают об ошибках? Не бойтесь ошибок, сначала прочитайте в чем ошибка, ее легко найти, т.к.Cannot find module 'vue-template-compiler',Это потому чтоvue-loaderобработка.vueфайл, вам также нужно зависеть отvue-template-compilerинструменты для обработки.

В начале я не знал, почему официалы прямо не сказали пользователям, что эту зависимость нужно установить.vue-loaderпросто пойми этоpackage.jsonфайл будетvue-template-compilerа такжеcss-loaderтак какpeerDependencies,а такжеpeerDependenciesВо время установки он не будет установлен автоматически (npm@3.0+), будут выданы только соответствующие предупреждения, поэтому его необходимо установить вручную, конечно, в.vueЕсли вам нужно написать CSS в файл, вы также должны использоватьcss-loader, это тожеpeerDependenciesсередина. Связанное обсуждение: https://github.com/vuejs/vue-loader/issues/1158

Знайте проблему, просто установите ее напрямую:

npm install vue-template-compiler css-loader --save-dev

Запустите проект еще раз, наш контент появится на странице, и об ошибке не будет сообщено, хорошо, все готово~

Используйте препроцессор

мы научились.vueЯ написал css в , а что, если я использую препроцессор sass? Сначала установите модули, упомянутые в предыдущей статье:

npm install sass-loader node-sass --save-dev

Настройка занимает всего два шага:

  1. Исправлятьwebpack.config.jsсерединаvue-loaderнастроить
  module.exports = {
    // ...
    module: {
      // 这里用来配置处理不同后缀文件所使用的loader
      rules: [
        {
          test: /.vue$/,
          loader: 'vue-loader',
          options: {
            loaders: {
              // 这里也可以使用连写方式,但是不利于自定义话参数配置
              // scss: 'vue-style-loader!css-loader!sass-loader'
              scss: [
                {
                  loader: 'vue-style-loader'
                },
                {
                  loader: 'css-loader'
                },
                {
                  loader: 'sass-loader'
                }
              ]
            }
          }
        },
        // ...
      ]
    }
  }

  1. Дать.vueв файлеstyleметка, добавитьlang="scss"Атрибуты.

После настройки вы можете.vueфайл, с удовольствием пишуsassграмматика тоже.

Загрузить файл глобальных настроек

В фактической разработке мы пишемsassфайл, глобальные переменные scss часто извлекаются и помещаются в отдельный файл, но в этом есть проблема, каждый компонент, который необходимо использовать, должен быть вручную@import './styles/_var.scss'Пришел, очень недружелюбно. плагинsass-resources-loaderОчень хорошо, чтобы помочь нам решить эту проблему, сначала установите его:

npm install sass-resources-loader --save-dev

затем изменитьwebpack.config.jsв файлеvue-loaderСвязанная конфигурация:

  // ...
  {
    test: /.vue$/,
    loader: 'vue-loader',
    options: {
      loaders: {
        scss: [
          {
            loader: 'vue-style-loader'
          },
          {
            loader: 'css-loader'
          },
          {
            loader: 'sass-loader'
          },
          // 看这里,看这里,看这里
          {
            loader: 'sass-resources-loader',
            options: {
              // 这里的resources 属性是个数组,可以放多个想全局引用的文件
              resources: [resolve('./src/styles/_var.scss')]
            }
          }
        ]
      }
    }
  }
  // ...

Настройка завершена, давайте проверим ее еще раз.

существуетsrcСоздается отдельно в каталогеhello1.vueа такжеhello2.vueдокумент:

<!-- hello1.vue -->
<template>
  <h1>{{ msg }}</h1>
</template>
<script>
export default {
  name: 'hello1',
  data () {
    return {
      msg: 'Hello Vue.js 单文件组件~'
    }
  }
}
</script>
<style lang="scss">
h1 {
  color: $green;
}
</style>

<!-- hello2.vue -->
<template>
  <h1>{{ msg }}</h1>
</template>
<script>
export default {
  name: 'hello2',
  data () {
    return {
      msg: 'Hello Vue.js 单文件组件~'
    }
  }
}
</script>
<style lang="scss">
h1 {
  color: $red;
}
</style>

затем создайтеstylesкаталог и создайте в нем новый файл для хранения глобальных переменных_var.scss:

$green: rgb(41, 209, 41);
$red: rgb(177, 28, 28);

Далее, вapp.jsОн привел два компонента:

import Vue from 'vue';
import hello1 from './hello1.vue';
import hello2 from './hello2.vue';

new Vue({
  el: "#app",
  template: '<div><hello1/><hello2/></div>',
  components: {
    hello1,
    hello2
  }
});

Просто перезапустите проект.

Ограниченный стиль

Очень удобная функция для нас предусмотрена в однофайловой составляющей, то есть когдаstyleдобавить тегиscopedсвойство, стили внутри тега будут применяться только к элементам в текущем компоненте.

Следуя приведенному выше примеру, после запуска вы обнаружите, чтоhello1.vueсерединаh1Цвет не тот, что я хочу$greenцвет, но поhello2.vueСтили в переопределяются. Итак, вhello1.vueа такжеhello2.vueизstyleдобавить на ярлыкscopedсвойства следующим образом:

<!-- hello1.vue -->
<style lang="scss" scoped>
h1 {
  color: $green;
}
</style>

<!-- hello2.vue -->
<style lang="scss" scoped>
h1 {
  color: $red;
}
</style>

В результате наших двухh1Цвета меток отображаются нормально.

пользовательский блок

При написании некоторых компонентов с открытым исходным кодом иногда нам нужно поддерживать несколько компонентов и описания компонентов одновременно, но каждая модификация должна быть изменена одновременно..vueа также.mdфайл, довольно громоздкий..vueдокументпользовательский языковой блокфункцию, которая позволяет намmarkdownОписание также написано на.vueфайл, а затем извлеките его раздел описания отдельно в соответствующий.mdфайл, так что документация и функциональность компонента могут поддерживаться одновременно.

Например, мы будемhello1.vueФайл изменен следующим образом:

<docs>
  # 标题
    这是标题内容,[仓库地址](https://github.com/yugasun/You-May-Not-Know-Vuejs)
  ## 子标题
    这是子标题内容
</docs>
<template>
  <h1>{{ msg }}</h1>
</template>
<script>
export default {
  name: 'hello1',
  data () {
    return {
      msg: 'Hello Vue.js 单文件组件~'
    }
  }
}
</script>
<style lang="scss" scoped>
h1 {
  color: $green;
}
</style>

затем изменитьwebpack.config.jsКонфигурация:

const path = require('path');
// 引入相关插件
const ExtractTextPlugin = require('extract-text-webpack-plugin');

function resolve(dir) {
  return path.resolve(__dirname, dir);
}

module.exports = {
  // 入口文件
  entry: './src/app.js',
  // 编译输出文件
  output: {
    path: resolve('./'),
    filename: 'build.js'
  },
  resolve: {
    alias: {
      // 因为我们这里用的是 require 引入方式,所以应该使用vue.common.js/vue.js/vue.min.js
      'vue$': 'vue/dist/vue.common.js'
    }
  },
  devServer: {
    // 这里定义 webpack-dev-server 开启的web服务的根目录
    contentBase: resolve('./')
  },
  module: {
    // 这里用来配置处理不同后缀文件所使用的loader
    rules: [
      {
        test: /.vue$/,
        loader: 'vue-loader',
        options: {
          loaders: {
            scss: [
              {
                loader: 'vue-style-loader'
              },
              {
                loader: 'css-loader'
              },
              {
                loader: 'sass-loader'
              },
              {
                loader: 'sass-resources-loader',
                options: {
                  resources: [resolve('./src/styles/_var.scss')]
                }
              }
            ],
            docs: ExtractTextPlugin.extract('raw-loader')
          }
        }
      },
      {
        test: /.js$/,
        loader: 'babel-loader'
      }
    ]
  },
  plugins: [
    new ExtractTextPlugin('docs.md')
  ]
}

используется здесьextract-text-webpack-pluginэкспортtextплагины иraw-loader, и установить их отдельно.

затем запустите команду сборкиnpm run build, когда операция завершится, корневой каталог сгенерируетdocs.mdфайл, это документация, которую мы хотим написать.

Суммировать

окомпонент одного файлапрямо здесь, на самом делеvue-loaderобработка.vueФайл, есть много мощных функций, здесь мы просто покажем вам, как использовать в общих проектах, и объясним соответствующие принципы использования, больше функций, рекомендуется прочитатьофициальная документация vue-loader.

Исходный код здесь

Тематический каталог

You-May-Not-Know-Vuejs