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
Настройка занимает всего два шага:
- Исправлять
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'
}
]
}
}
},
// ...
]
}
}
- Дать
.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.