Vue项目 - 单文件组件和Vue中的路由

推荐: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驱动的时候,下面这些缺点将变得非常明显:

  1. 全局定义 (Global definitions) :强制要求每个component中的命名不得重复。
  2. 字符串模板 (String templates) :缺乏语法高亮,在HTML有多行的时候,需要用到丑陋的\
  3. 不支持 CSS (No CSS support) :意味着当HTML和JavaScript组件化时,CSS明显被遗漏。
  4. 没有构建步骤 (No build step) :限制只能使用HTML和ES5 JavaScript,而不能使用预处理器,如Pug (formerly Jade)Babel

文件扩展名为 .vuesingle-file components (单文件组件) 为以上所有问题提供了解决方法,并且还可以使用webpackBrowserify等构建工具。

上一篇博客介绍了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: routerApp: App就可以写成routerApp

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中的路由就介绍到这里。

写博客是博主记录自己的学习过程,如果有错误,请指正,谢谢!

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ITKaven

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值