推薦: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
- 字元串模闆
:缺乏文法高亮,在HTML有多行的時候,需要用到醜陋的(String templates)
。\
- 不支援 CSS
:意味着當HTML和JavaScript元件化時,CSS明顯被遺漏。(No CSS support)
- 沒有建構步驟
:限制隻能使用HTML和ES5 JavaScript,而不能使用預處理器,如(No build step)
和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
元件,對應于下面的文字和連結。