推荐:Vue汇总
Vue项目 - 单文件组件和Vue中的路由
什么是单文件组件
在之前的博客中,博主使用Vue.component
来定义全局组件,紧接着用new Vue({ el: '#container '})
在每个页面内指定一个挂载点。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>组件</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="div">
<component v-bind:is="currentComponent">kaven</component>
<button @click="click">切换</button>
</div>
</body>
</html>
<script>
Vue.component("slot-welcome" , {
template: `
<div>
<p>welcome </p>
<slot></slot>
</div>
`
});
Vue.component("slot-hello" , {
template: `
<div>
<p>hello </p>
<slot></slot>
</div>
`
});
var vue = new Vue({
el: '#div',
data: {
currentComponent: 'slot-hello'
},
methods: {
click(){
if(this.currentComponent === 'slot-hello'){
this.currentComponent = 'slot-welcome'
}
else{
this.currentComponent = 'slot-hello'
}
}
}
})
</script>
这种方式在很多中小规模的项目中运作的很好,在这些项目里JavaScript只被用来加强特定的视图。但当在更复杂的项目中,或者你的前端完全由JavaScript驱动的时候,下面这些缺点将变得非常明显:
- 全局定义
(Global definitions)
:强制要求每个component
中的命名不得重复。 - 字符串模板
(String templates)
:缺乏语法高亮,在HTML有多行的时候,需要用到丑陋的\
。 - 不支持 CSS
(No CSS support)
:意味着当HTML和JavaScript组件化时,CSS明显被遗漏。 - 没有构建步骤
(No build step)
:限制只能使用HTML和ES5 JavaScript,而不能使用预处理器,如Pug (formerly Jade)
和Babel
。
文件扩展名为 .vue
的single-file components
(单文件组件) 为以上所有问题提供了解决方法,并且还可以使用webpack
或Browserify
等构建工具。
上一篇博客介绍了Vue项目的文件组成部分:Vue项目 - 项目文件介绍。
其中就有根组件App.vue
:
<template>
<div id="app">
<img src="./assets/logo.png">
<router-view/>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
还有放置自定义组件的包components
中的HelloWorld.vue
:
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<h2>Essential Links</h2>
<ul>
<li>
<a
href="https://vuejs.org"
target="_blank"
>
Core Docs
</a>
</li>
<li>
<a
href="https://forum.vuejs.org"
target="_blank"
>
Forum
</a>
</li>
<li>
<a
href="https://chat.vuejs.org"
target="_blank"
>
Community Chat
</a>
</li>
<li>
<a
href="https://twitter.com/vuejs"
target="_blank"
>
Twitter
</a>
</li>
<br>
<li>
<a
href="http://vuejs-templates.github.io/webpack/"
target="_blank"
>
Docs for This Template
</a>
</li>
</ul>
<h2>Ecosystem</h2>
<ul>
<li>
<a
href="http://router.vuejs.org/"
target="_blank"
>
vue-router
</a>
</li>
<li>
<a
href="http://vuex.vuejs.org/"
target="_blank"
>
vuex
</a>
</li>
<li>
<a
href="http://vue-loader.vuejs.org/"
target="_blank"
>
vue-loader
</a>
</li>
<li>
<a
href="https://github.com/vuejs/awesome-vue"
target="_blank"
>
awesome-vue
</a>
</li>
</ul>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data () {
return {
msg: 'Welcome to Your Vue.js App'
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1, h2 {
font-weight: normal;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
这些都是单文件组件。
现在,大家应该都知道什么是单文件组件了,其实就是在单个文件中定义一个组件,这样对于组件的复用、修改都很方便;一个重要的事情值得注意,关注点分离不等于文件类型分离。在现代UI开发中,我们已经发现相比于把代码库分离成三个大的层次(HTML、CSS、Javascript)并将其相互交织起来,把它们划分为松散耦合的组件再将其组合起来更合理一些。在一个组件里,其模板、逻辑和样式是内部耦合的,并且把它们搭配在一起实际上使得组件更加内聚且更可维护。
创建一个Vue项目后,当运行这个Vue项目时,基本上都会出现如下图所示页面。
那么为什么运行Vue项目,首页是上图所示页面呢?这就要涉及到Vue中的路由了。
首页index.html
:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>project</title>
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
很明显首页中id="app"
的div
标签被入口文件main.js
中定义的组件挂载了。
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
而入口文件main.js
中定义的组件使用了根组件(App),并且定义模板template
为<App/>
,所以<div id="app"></div>
就相当于<App/>
;并且入口文件main.js
中还引入了router
,当引入router
后,Vue项目会自动加载文件夹router
下的文件index.js
,该文件定义了路由规则。ES6语法,当键和值相同时,如router: router
、App: App
就可以写成router
、App
。
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'HelloWorld',
component: HelloWorld
}
]
})
可以知道当路径为'/'
时,使用路由后,会被路由到HelloWorld
组件。
而路由是在哪里触发的呢?其实是根组件中的<router-view/>
标签,因此这部分区域路由到了HelloWorld
组件。
<template>
<div id="app">
<img src="./assets/logo.png">
<router-view/>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
所以<img src="./assets/logo.png">
对应于Vue的图片。
而<router-view/>
标签会路由到HelloWorld
组件,对应于下面的文字和链接。
单文件组件和Vue中的路由就介绍到这里。
写博客是博主记录自己的学习过程,如果有错误,请指正,谢谢!