单文件组件
简介
以前文件的组织是以.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下发数据到子组件。