简介
以前文件的组织是以.HTML、.js以及.css/less/scss这些文件进行垂直分割的,而Vue中我们以组件为单位构造,因此,最好的方式是把这些不同的类型的文件与组件相关的部分,围绕组件组合成一个文件即.vue文件,我称其为水平分割。另外,在<template>
中写模板也比原来的字符串形式的模板方便的多。
在webpack里面要加载*.vue文件,需要下面两个包
$npm install vue-loader vue-template-compiler
webpack添加Loader配置
{
test: /.vue$/,
use: [
'vue-loader'
]
}
......
resolve: {
extensions: ['.js', '.vue'],
alias: {
'Vue': 'vue/dist/vue.js'
}
}
webpack的resolve
选项,用来配置解析import
、require
中的路径的细节,extensions
就是在某文件没写扩展名时,默认的寻找扩展名。如import App from './App'
中,没有App.js
就找App.vue
。alias
是给路径起个别名,方便一点,如import Vue from 'Vue'
即表示import Vue from 'vue/dist/vue.js'
然后就可以编写代码了
<!--App.vue-->
<template>
<div id="app">
<h1 class="text-color">{{heading}}</h1>
</div>
</template>
<script>
export default {
data(){
return {heading:'My Todo App!'}
}
}
</script>
<style>
.text-color {
color:#009A61
}
</style>
//index.js
import Vue from 'Vue'
import App from './App'
new Vue({
el: '#app-1',
template: '<App/>',
components: { App },
//render: h => h(App)
})
<!--index.html-->
<body>
<div id="app-1"></div>
</body>
文件App.vue
即所谓的单文件组件,我们看到了模板、样式和JS是如何水平分割的。
还有要注意的是,页面原始的<div id="app-1"></div>
将会被组件替换掉。
模板写在如下内容中:
<template>
</template>
JS写在如下内容中:
<script>
export default {
//options
}
</script>
css写在如下内容中:
<style>
</style>
我们在index.js中引用这个App.vue文件组件,这里让它作为实例#app-1
的子组件引入,也可以使用渲染函数使用它。
一个例子
这里是官网上一个单文件多层组件的示例。App2.vue
在子组件BaseInputText.vue中,有如下代码
<template>
<input type="text" class="input" :value="value" v-on="eventDict">
</template>
<script>
export default {
props: {
value: {
type: String,
default: ""
}
},
computed: {
eventDict() {
var self = this;
//如果下层组件还有自定义事件触发,那么都保存在$listeners中,这里没有下层组件
return Object.assign({}, this.$listeners, {
input: function(event) {
self.$emit("input", event.target.value);
}
});
}
}
};
</script>
这里在无参的v-on
中绑定了一个事件对象,该对象中除了有必须的input
事件,并与this.$listeners
合并,this.$listeners
包含了该子组件的所有下层组件(如果有的话)中的自定义事件。
就像示例中所做的那样,属性和方法都集中在上层的组件中,这里是TodoList.vue组件,通过Props下发数据到子组件。