昨天开始学习vue中的路由,在看到Vue中的路由时,路由作为网络管理中还算高深的词汇用在网页的前端开发中,感觉很奇怪。
开始接触vue中的路由时,以为同样需要高深的知识体系或者技能才能掌握。
事实上不是这样的。
在网络管理中,以前路由器和交换机是有明显区别的,比如网络设备分路由器、交换机,路由器专职做不同网段间的数据包转发,现在这个界线模糊了,很多交换机实现了路由功能,可以看尤雨溪懂网络,他在写Vue中的路由时借助了这一概念。
简单地说,vue中的路由就是截取网页中的地址跳转,按照开发者在路由设定中的规则进行来进行网页跳转。
通过路由配置,可以定义不同 URL 地址与对应组件之间的对应(映射)关系,以实现页面间的无刷新跳转和动态加载组件,在 Vue 应用中可以实现单页面应用(SPA)的效果,这样网页端的应用就有更流畅、更友好的用户体验。
一、使用vue创建项目
去年二月份写了《创建基于Vue2.0开发项目的两种方式》,没有真正动手去写代码,这次要实践写代码,并理解程序的运行原理和逻辑。
做简单修改:
1、APP.vue
<template>
<div id="app2">
<span>这是测试</span>
<Header></Header>
<PSP :person="{ name:'学生1',age:19 }"></PSP>
</div>
</template>
<script>
import Header from './view/header'
import PSP from './view/psp'
export default {
name: 'App',
components: {
Header,
PSP
}
}
</script>
<style>
#app2 {
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>
2、header.vue
<template>
<div>
<span class="header">这是头部</span>
</div>
</template>
<script>
export default {
name:'Header'
}
</script>
<style scoped>
.header{
color: brown;
}
</style>
3、psp.vue
<template>
<div>
<span>{{ person.name }}--{{ person.age }}</span>
</div>
</template>
<script>
export default {
name:'PSP',
props:{
person:{
type:Object,
require:true
}
}
}
</script>
运行结果:
1、运行npm run serve和运行npm run build后程序运行逻辑不同,npm run build后程序入口文件index.html内嵌入了后续运行所需要的代码,那么就可以作为发行文件的入口,而npm run serve后程序依然由vue的应用服务接管。
3、网页应用的入口由应用服务指定,程序入口文件为index.html,在运行npm run serve后index.html内并没有嵌入js文件。
4、在启动时由应用服务进行绑定工作,先运行main.js进行对象绑定,先绑定app.vue中的App,注册到index.html的app中。
5、App.vue中引入了header.vue和psp.vue。
6、App.vue中使用了Header和PSP,要在export中注明,否则其他程序在执行App.vue文件中的组件时就报错。
7、注意,Header一定要首字符大写,如果因为header与系统内部的定义冲突。
8、在传参时注意,如果定义变量是字符,那么规范的写法是”‘这是传入的字符’“。
9、简单理解:npm run serve运行后,先运行main.js,进行app.vue的渲染(引入组件并进行渲染),完成所有准备后程序定位到index.html。
二、简单路由试验
虽然vue中的路由仅仅借助了网络中的路由概念,原理不复杂就只是做数据转发,但是容易出现的错误点也挺多的。
学习一下vue中的实际路由。
1、main.js文件内容:
import Vue from 'vue'
import App from './App.vue'
import router from './router/myrouter.js'
Vue.config.productionTip = false
new Vue({
render: h => h(App),
router
}).$mount('#app')
2、App.vue文件内容:
<template>
<div id="app">
<div>
<span><router-link :to="{ name:'MySearch',params: { name:'John',id: '123' } }">搜索</router-link></span> <a href="https://www.baidu.com">百度</a> <span @click="GoToMyTable" exact>表格</span>
</div>
<router-view style="border: 9px solid #d70008;"></router-view>
</div>
</template>
<script>
export default {
methods:{
GoToMyTable(){
this.$router.push( { name:'MyTable',params:{ name:'SDF',id:'29',age:13 } } );
}
}
}
</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;
border: 9px solid #333333;
}
</style>
3、路由文件myrouter.js内容:
import Vue from 'vue'
import Router from 'vue-router'
import MySearch from '../views/MySearch.vue'
import MyTable from '../views/MyTable.vue'
import MyHome from '../views/Home.vue'
Vue.use(Router)
//定义路由组件的信息
const routes=[
{
path:'/',
name:'MyHome',
component:MyHome
},
{
path:'/MySearch',
name:'MySearch',
component:MySearch,
props: true
},
{
path:'/MyTable',
name:'MyTable',
component:MyTable,
props: true
}
]
//实例化路由组件
const router=new Router({
mode:'history',
routes
})
export default router
4、Home.vue文件内容:
<template>
<div>
<h1>主页面</h1>
<Home :msg="'标题'"></Home>
</div>
</template>
<script>
import Home from '../components/HelloWorld.vue'
export default {
name:'MyHome',
props:{
msg:{
type:String
}
},
components:{
Home
}
}
</script>
5、HelloWorld.vue文件内容:
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<ul>
<li>112</li>
<li>234</li>
</ul>
</div>
</template>
<script>
export default {
name: 'MyHome',
props: {
msg: String
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
6、MySearch.vue文件内容:
<template>
<div>
<h1>这是搜索页</h1>
<DisplayPara :ParaObj="MyPara"></DisplayPara>
</div>
</template>
<script>
import DisplayPara from '../components/DisplayPara.vue';
export default {
name:"MySearch",
components:{
DisplayPara
},
data(){
return {
MyPara:{}
}
},
created() {
if (this.$route.params) {
this.MyPara = this.$route.params;
}
}
}
</script>
7、MyTable.vue文件内容:
<template>
<div>
<h1>这是表格页</h1>
<DisplayPara :ParaObj="MyPara"></DisplayPara>
</div>
</template>
<script>
import DisplayPara from '../components/DisplayPara.vue';
export default {
name:"MyTable",
components:{
DisplayPara
},
data(){
return {
MyPara:{}
}
},
created() {
if (this.$route.params) {
console.log(this.$route.params);
this.MyPara = this.$route.params;
}
}
}
</script>
8、DisplayPara.vue文件内容:
<template>
<div>
<h2>参数显示</h2>
<div v-for="(value,key) in ParaObj" :key="key">
<p> {{ key }} -- {{value}}</p>
</div>
</div>
</template>
<script>
export default {
props:{
ParaObj:{
type:Object,
default:()=>({})
}
}
}
</script>
显示结果:
1、主页面:
2、点击“搜索”出现页面:
3、点击“表格”出现页面:
注意点:
1、通过这个试验,清楚地看出index.html、App.vue、main.js之间的关系,以及组件之间的联系。
2、通过router-link和click方式触发路由并进行参数传递,这里的参数传递为对象,我没有使用递归来显示对象的所有,只是显示了根节点的参数名与参数值,其他的都是简单类型更加清楚明了。
3、上面的试验可以看出,vue设计是为了网页端应用的单页面展示,这样良好的无刷用户体验。
4、App.vue中至少应该有一个router-view,当然也可以有多个router-view,这样可以具体指定内容渲染到具体的router-view。
5、在路由器中的数据转发,寻路需要很多复杂的算法,vue中的路由也可以进行数据包的截取、分析处理再转发。
vue中的路由还有很多内容需要进一步的学习。