由于现在很多vue项目都是基于ES6开发的,而我学vue的时候大多是看vue官网的API,是基于ES5的,所以对于刚接触项目的我来说要转变为项目的模块化写法确实有些挑战。因此,我打算先做一个基于ES5的vue小demo,再把这个demo写成基于ES6的,算是一个过渡吧!这个demo有一些代码借用于keepfool大神的《Vue.js——vue-router 60分钟快速入门》在此先解释一下,尊重原创!建议vue-rouer的相关知识可以跟着链接学习。
一、项目效果图
二、代码编写过程
1.功能一
首先我们要实现的功能一是点击play按钮,然后出现下面的Home和About,然后点击Home和About按钮分别会出现对应的信息。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Demo</title>
<link rel="stylesheet" href="bootstrap.min.css">
</head>
<body>
<div id="app">
<div class="container">
<div class="jumbotron">
<h1>A Demo!</h1>
<p>Let's play a demo</p>
<p><a class="btn btn-primary btn-lg" href="#" role="button" v-on:click="show">play</a></p>
</div>
</div>
<div class="container" v-show="isShow"><!--isShow为true则显示,其实就是控制display的值-->
<div class="row">
<div class="col-md-2 col-md-offset-2">
<div class="list-group">
<a class="list-group-item" v-link="{path:'/home'}">Home</a><!--在a元素上使用v-link指令跳转到指定路径-->
<a class="list-group-item" v-link="{path:'/about'}">About</a>
</div>
</div>
<div class="col-md-6">
<div class="panel">
<div class="panel-body">
<router-view></router-view><!--渲染出匹配的组件-->
</div>
</div>
</div>
</div>
</div>
</div>
<template id="home">
<div>
<h1>Home</h1>
<p>{{msg1}}</p>
</div>
</template>
<template id="about">
<div>
<h1>About</h1>
<p>{{msg2}}</p>
</div>
</template>
</body>
<script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.min.js"></script>
<script src="bootstrap.min.js"></script>
<script src="vue.min.js"></script><!--版本2.4.0-->
<script src="vue-router.js"></script><!--版本2.7.0-->
<script type="text/javascript">
var vm=new Vue({
el:'#app',
data:{
isShow: false
},
methods:{
show:function(){
this.isShow=true;
}
}
})
var Home=Vue.extend({ //创建组件
template:'#home',
data:function(){
return{
msg1:'This is Home page!'
}
}
})
var About=Vue.extend({
template:'#about',
data:function(){
return{
msg2:'This is About page!'
}
}
})
var router=new VueRouter(); //创建router
router.map({ //映射路由
'/home':{
component:Home
},
'/about':{
component:About
}
})
var App=Vue.extend({}) //启动路由
router.start(App,'#app')
</script>
</html>
这段代码这么写有没有问题?废话这么问十有八九是有问题的。我们来运行一下,然后看看控制台说些什么。
大概意思就是说matched是未定义的文本,读取不了,而router.map不是一个函数。为什么会出现这种情况?很简单,这是因为vue.js和vue-router.js的版本问题。vue router 2.0 没有map这个方法了,那我们改vue-router.js为0.7.13版本不就好了吗?为什么还扯到vue.js的版本上了?我们改一下vue-router.js的版本再运行一下看看行不行。
好吧!现在至少有一些效果出来了,但是还是有错误,我们来一一解决。现在是component未定义,VueRouter未定义了,这个问题修改一下vue.js的版本就好了,这里我们采用1.0.25的版本,再运行一下试试看。
这次一开始出现的界面是没有Home和About两个按钮的,需要点击完play按钮才会出现,这个达到我们的目的,现在的问题是Home和About按钮还是点击不了。我们看看控制台怎么说的。
<router-view>标签和v-link只能在router可用的应用中使用。就是说你当前应用的路由管理尚未生效。使用了 vue-router 就不需要实例化根组件了,route.start 会帮你实例化根组件。new Vue 是不需要的,否则其中的路由标签不能被识别。我们会源代码一看,诶!还真的一开始就var vm=new Vue()了。那我们暂且把它删掉吧!等一下再弄。看看效果怎么样。我们删掉v-on,v-show和var vm=new Vue()部分。
ok,可以显示了,但是play也就没用了。其实一开始我就陷入了一个误区,我一直想用v-on和v-show来实现Home和About显示的这个功能,却忘了可以用路由实现,不过虽然一波三折,但是在解决问题的过程中,还是让我这个初学者学到不不少东西。我们现在全部用路由来实现。
2.全路由实现功能一
我们修改一下代码,如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Demo</title>
<link rel="stylesheet" href="bootstrap.min.css">
</head>
<body>
<div id="app">
<div class="container">
<div class="jumbotron">
<h1>A Demo!</h1>
<p>Let's play a demo</p>
<p><a class="btn btn-primary btn-lg" href="#" role="button" v-link="{path:'/play'}">play</a></p>
</div>
</div>
<router-view></router-view>
</div>
<template id="play">
<div class="container">
<div class="row">
<div class="col-md-2 col-md-offset-2">
<div class="list-group">
<a class="list-group-item" v-link="{path:'/play/home'}">Home</a>
<a class="list-group-item" v-link="{path:'/play/about'}">About</a>
</div>
</div>
<div class="col-md-6">
<div class="panel">
<div class="panel-body">
<router-view></router-view>
</div>
</div>
</div>
</div>
</div>
</template>
<template id="home">
<div>
<h1>Home</h1>
<p>{{msg1}}</p>
</div>
</template>
<template id="about">
<div>
<h1>About</h1>
<p>{{msg2}}</p>
</div>
</template>
</body>
<script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.min.js"></script>
<script src="bootstrap.min.js"></script>
<script src="vue.min.js"></script>
<script src="vue-router.js"></script>
<script type="text/javascript">
var Play=Vue.extend({
template:'#play'
})
var Home=Vue.extend({
template:'#home',
data:function(){
return{
msg1:'This is Home page!'
}
}
})
var About=Vue.extend({
template:'#about',
data:function(){
return{
msg2:'This is About page!'
}
}
})
var router=new VueRouter();
router.map({
'/play':{
component:Play,
subRoutes: {//定义子路由
'/home':{
component:Home
},
'/about':{
component:About
}
}
}
})
var App=Vue.extend({})
router.start(App,'#app')
</script>
</html>
效果正是我们想要的,点击play出现Home和About,点击Home和About出现相应的信息。
我们可以嵌套多个路由,多加一些功能,这样用ES6来开发这个Demo才更有挑战性一点。
3.功能进阶
我们在Home组件里面增加一个获取当前日期的功能
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Demo</title>
<link rel="stylesheet" href="bootstrap.min.css">
</head>
<body>
<div id="app">
<div class="container">
<div class="jumbotron">
<h1>A Demo!</h1>
<p>Let's play a demo</p>
<p><a class="btn btn-primary btn-lg" href="#" role="button" v-link="{path:'/play'}">play</a></p>
</div>
</div>
<router-view></router-view>
</div>
<template id="play">
<div class="container">
<div class="row">
<div class="col-md-2 col-md-offset-2">
<div class="list-group">
<a class="list-group-item" v-link="{path:'/play/home'}">Home</a>
<a class="list-group-item" v-link="{path:'/play/about'}">About</a>
</div>
</div>
<div class="col-md-6">
<div class="panel">
<div class="panel-body">
<router-view></router-view>
</div>
</div>
</div>
</div>
</div>
</template>
<template id="home">
<div>
<h1>Home</h1>
<p>{{msg1}}<a class="btn" v-link="{path:'/play/home/time'}">获取当前日期</a></p>
</div>
<router-view></router-view>
</template>
<template id="time">
<table class="table table-striped">
<tr>
<td>年份</td>
<td>月份</td>
<td>日</td>
</tr>
<tr v-for="t in dates">
<td>{{t.year}}</td>
<td>{{t.month}}</td>
<td>{{t.day}}</td>
</tr>
</table>
</template>
<template id="about">
<div>
<h1>About</h1>
<p>{{msg2}}</p>
</div>
</template>
</body>
<script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.min.js"></script>
<script src="bootstrap.min.js"></script>
<script src="vue.min.js"></script>
<script src="vue-router.js"></script>
<script type="text/javascript">
var Play=Vue.extend({
template:'#play'
})
var Home=Vue.extend({
template:'#home',
data:function(){
return{
msg1:'This is Home page!'
}
}
})
var Time=Vue.extend({
template:'#time',
data:function(){
var D = new Date();
return{
dates:[{
year:D.getFullYear(),
month:D.getMonth()+1,
day:D.getDate()
}]
}
}
})
var About=Vue.extend({
template:'#about',
data:function(){
return{
msg2:'This is About page!'
}
}
})
var router=new VueRouter();
router.map({
'/play':{
component:Play,
subRoutes: {
'/home':{
component:Home,
subRoutes:{
'/time':{
component:Time
}
}
},
'/about':{
component:About
}
}
}
})
var App=Vue.extend({})
router.start(App,'#app')
</script>
</html>
效果如下
点击“获取当前日期”可以出现下面的表格。
之前我的做法是想在var Time=Vue.extend里面定义methods获取时间,然后在“获取当前日期”的<a>标签里面添加v-on调用函数,但是很遗憾,不是父子组件无法直接沟通!各为高手如果有什么高招欢迎指教。
三、结语
这个基于ES5的vue小demo就先写到这里,下一篇《一个基于ES6+webpack的vue小demo》,我们将看看如何用ES6实现这个demo而且把它当做一个项目打包起来。