vue2初学体验
16 Dec 2016继上次react
和angular1
学习体验之后,隔了四个月,最近有空就入门起了vue2
了,其实一开始有稍微看一下的,一开始给我感觉跟angular
有点像,而我感觉angular
总有那么点复杂感,于是就没继续看,等到vue2
出来了,既然有空就学习一下,给我感觉,还是比较轻快简便的一个框架,文档详尽,多到我还没看完,就看了语法那块就开始动手写demo了,也翻查了好些入门内容,遇到不少坑。
所用工具
在看完文档,写了几个demo之后,开始使用官方脚手架vue-cli
来写demo,加入vue-router
(路由)和vue-resource
(http请求库)。
说起脚手架,看到刚安装完vue-cli
,然后开始建立一个demo的时候,看生成的npm
包,好多啊,可怕。一种新手恐惧感就来了,还好一切按照运行起来正常。
我的demo就是在vue-cli
生成的demo上做改动的,demo提供了服务器的启动,看代码似乎用的是express
来承载。
再者,web下异步需要接口等,可以用‘mock-api’来模拟接口,方便,而且vue-cli
也提供了接口代理。
安装
vue-cli
脚手架的安装也不麻烦:全局安装,要求node版本>=4.x
$ npm install -g vue-cli
安装后执行命令:
$ vue init webpack demo
即在demo目录下生成项目。
(update) 只是生成了一个项目轮廓,项目中需要的依赖包,还需要在项目目录里执行 npm install(读取package.json的依赖包并下载到项目中,感谢评论提醒)
然后在demo目录下执行
$ npm run dev
即启动本地开发模式
vue-router | vue-resource
安装到demo目录中
$ npm install vue-router –save-dev
$ npm install vue-resource –save-dev
mock-api
安装方式:
npm install -g mock-api
使用方式:
比如建立一个目录api,在api里建立一个json文件,json文件内容为一个数组,例子:
[
{
"method": "get",
"url": "/api/bug/:id",
"response": {
"result":{
"id": "",
"title":"暴露代码",
"desc":"页面显示出了代码",
"level":"5",
"author":"hoverq",
"responser":"blong"
}
}
}
]
示例代码写了一个配置对象,意为get
请求/api/bug/id
时,响应内容则是response
对象的值,其中:id
可以实现url含诸如id之类的动态数字,而response内容里可以用``来执行js代码,如访问url上的id可以是this.params.id
写完配置文件,启动mock-api即可
$ mock-api serve api
启动时默认端口为10086,更多命令配置可以看github
配置
脚手架生成demo之后,基本可以进行开发,但对于接口部分的对应,需要改一下配置内容,由于vue-cli
本地开发模式启动了一个服务,而mock-api
又启动一个服务,双方接口交互势必属于跨域行为,vue-cli
对这方面也做了支持,在config
目录下index.js
, 本地开发的相关配置dev
如下:
dev: {
env: require('./dev.env'),
port: 8080,//本地开发启动服务的端口
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {//接口代理
'/api': {
target: 'http://localhost:10086',
changeOrigin: true,
pathRewrite: {
'^/api': '/api'
}
}
},
如上配置,proxyTable
为项目本地开发提供了代理接口,这里配置了当url为/api
时,请求代理到target
指向的域名去,changeOrigin
设置跨域。
这样,我们的vue项目在本地启动时,访问接口/api
就可以直接访问到mock-api
模拟的接口了 ,也就是http://localhost:8080/api
直接代理到http://localhost:10086/api
去。
业务编码
我这里demo实现一个简单的增改查,这里就随便弄了个bug管理列表
项目页面结构: 主页面承载 index.html, 入口js main.js, 模板组件 components/xxx.vue
index.html
主要负责页面布局内容设置,其body标签部分代码如下:
<body>
<div id="app">
<section class="column sidebar-left">
<h1>bug管理工具</h1>
<ul>
<li>
<router-link to="/bugs">Bug 列表</router-link>
</li>
<li>
<router-link to="/members">成员列表</router-link>
</li>
<li>
<router-link to="/projects">项目列表</router-link>
</li>
<li>
<router-link to="/addBug">有bug啦</router-link>
</li>
</ul>
</section>
<section class="column main">
<transition name="slide">
<router-view></router-view>
</transition>
</section>
</div>
</body>
router-link
标签为vue-router
组件,默认渲染成一个a
标签, router-view
则为路由匹配到的组件渲染目的地,transition
为过渡动画组件,需要配合加入样式以达到过渡效果。
入口 main.js
将各个路由模块页面设为独立的.vue
文件,而main.js
主要负责init初始化部分内容。代码很简单:
import Vue from 'vue'
import BugList from './components/BugList'
import ProjectList from './components/ProjectList'
import MemberList from './components/MemberList'
import BugItem from './components/BugItem'
import BugForm from './components/BugForm'
import VueResource from 'vue-resource'
import VueRouter from 'vue-router'
//组件注入
Vue.use(VueRouter);
Vue.use(VueResource);
//路由配置
const routes = [
{ path: '/bugs', component: BugList },
{ path: '/members', component: MemberList },
{
path:'/projects',
component: ProjectList
},
{
path:'/bug/:id',
component: BugItem
},
{
path:'/addbug',
component: BugForm
},
{
path:'/editbug/:id',
component: BugForm
},
{path:'*', redirect: '/bugs'}
]
//vueRouter设置
const router = new VueRouter({
routes // (缩写)相当于 routes: routes
})
// 记得要通过 router 配置参数注入路由,
// 从而让整个应用都有路由功能
const app = new Vue({
router
}).$mount('#app')
如上代码,即可在主页面配置好几个子页面的配置,对应的组件模板通过import
传入(es6语法)
业务页面组件
列表页组件代码:主要包括模板template 以及 脚本 script
<template>
<div class="bug-list div-for-slide table-list">
<table class="table table-striped table-bordered" style="text-align:left;">
<thead>
<tr>
<th>Bug标识</th>
<th>标题</th>
<th>发起者</th>
<th>处理者</th>
<th>所属项目</th>
<th>详情</th>
</tr>
</thead>
<tbody>
<tr v-for='bug in bugs'>
<td></td>
<td></td>
<td></td>
<td></td>
<td><router-link :to="'/bug/'+bug.id">Bugs</router-link></td>
<td><router-link :to="'/bug/'+bug.id">详情</router-link></td>
</tr>
</tbody>
</table>
<button @click.prevent="$router.push({path:'/addbug'})" class="btn btn-info">新增bug</button>
</div>
</template>
<script>
export default {
name: 'buglist',
data:function(){
return {
bugs:{
}
}
},
created:function(){
this.fetchData();
},
methods:{
fetchData:function(){
//vue-resource 在vm实例中注入了$http方法,可直接用
this.$http.get('/api/getBugs').then((response) => {
this.bugs = response.body.result.data;
}, (response) => {
console.log('error');
});
}
},
watch:{
'$route':'fetchData'
}
}
</script>
在index.html我们通过router-link标签来渲染出链接,也可以通过js来实现编程路由,vue-router
同样在vm内注入了$router
和$route
变量,前者为路由实例,可以通过调用$router.push({path:'/addbug'})
来实现跳转到/addbug
页面,跟点击 <router-link to="/addBug">有bug啦</router-link>
是等价的。 具体可以查看router文档, 后者提供当前路由的基本信息,如当url为/aa/:id
的形式,我们就可以通过$route.params.id
来得到id值。
这里说明一下,路由的数据异步获取,这点也在router文档有描述,这里用了导航加载后获取数据渲染的方式,通过created
和监听$route
来调用异步接口设置data数据以更新渲染页面。
初次体验给我感觉,vue2
的上手不算太难,代码量少,不过文档内容详尽,还是照着写写demo,有助于理解vue语法和结构,可能还不太适应新模式的开发方式,有些思维碰撞上,开发起来需要思考很多。有机会再深入一下其他官方组件,以实践应用开发。