看了一个礼拜的 vue.js ,不得不说,入门是很容易的,学习曲线也相对平缓。数据的双向绑定也另开发顺畅,特别是一些交互比较复杂的项目。
来简单说一下利用 vue-cli 脚手架
进行项目开发,我个人的一些实战总结吧,项目是基于 vue2.0
做开发的。
一、项目编译的webpack配置简介:
vue-cli 脚手架项目的目录 build 下有 3个基础配置文件:
webpack.base.conf.js
webpack.dev.conf.js
webpack.prod.conf.js ,
用来构建 运行时项目,和构建发布时项目
1、webpack.base.conf.js
基础配置文件
module: {
loaders: [
{
test: /\.vue$/,
loader: 'vue'
},
{
test: /\.js$/,
loader: 'babel',
include: projectRoot,
exclude: /node_modules/
},
{
test: /\.json$/,
loader: 'json'
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url',
query: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url',
query: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
}
]
},
module 下面的配置其中需要说明的一点是 配置中有对 10000b 的图片大小进行base64转换,折算一下就是 9.765625kb
,所以项目中对一下小的 icon 不必做图片精灵处理。
在 webpack.base.conf.js 文件的结尾处还有这么一段配置:
vue: {
loaders: utils.cssLoaders({ sourceMap: useCssSourceMap }),
postcss: [
require('autoprefixer')({
browsers: ['last 2 versions']
})
]
}
为什么单独拿出来说呢,因为在项目开发的时候遇到一点小坑 , autoprefixer
一个浏览器自动兼容插件,browsers: ['last 2 versions']
意思是只对主流浏览器的最新两个版本(其实也就是不做兼容了,现代最新的浏览器基本都不需要兼容了呀),所以我在写一个 css3 动画
的时候就发现较低版本的Android设备居然不运行。
配置如下就好了:意思是 对 主流浏览器的最新五个版本和对Android4.0以上
的版本做兼容
vue: {
loaders: utils.cssLoaders({ sourceMap: useCssSourceMap }),
postcss: [
require('autoprefixer')({
browsers: ['last 5 versions', 'Android >= 4.0']
})
]
}
2、webpack.dev.conf.js
当我们在项目运行 npm run dev
就会执行这个脚本进行项目构建,值得一提的是配置文件中有个html-webpack-plugin
插件,用于热刷新浏览器,当你编辑完 .vue文件
,command+s
保存一下浏览器就会自动刷新了。
3、webpack.prod.conf.js
当我们要上线项目可以用 npm run build
对咱们的项目进行构建,webpack 会帮我们压缩css 和js文件,并加上哈希值,还有生成对应文件的 SourceMap 文件
,因为压缩后的css或js文件你没办法看,调试的时候出了错误可以利用SourceMap
来查看代码对应的位置。 那我项目确保没bug了怎么把SourceMap
关掉呢,毕竟线上项目是不想让别人看到具体源代码的。
那就找到 项目中config文件夹
下 index.js
文件对应下的配置:
module.exports = {
build: {
//...
productionSourceMap: false,
将 productionSourceMap
置为 false
再次 npm run build
一样就不会构建出 .map 文件
了
二、项目实战开发
希望你在看这篇博文的时候是有点 vue 基础的,对 vue开发有所了解,本篇文章不会介绍 vue 的基础内容,
因为 [vue.js官网][1] 已经很简单详细了。 本篇会讲一些实战开发的整体架构,和开发当中的一些实用的
知识点和技巧
1、全局 data
虽然 vue 是对数据双向绑定,如何管理好你的数据就需要多费点心思考虑一下了,不然到实际项目中,独立出独立的组件,而组件之间又存在数据或交互,那么数据传递将会异常的繁琐。
这里我建议 在 App.vue (或超父组件) 里维护一套 全局 data
,如下图:
2、父组件给子组件传递数据
父组件 appVue.vue
<template>
<div id="appVue">
<page1 v-bind:infodata="infodata"></page1>
</div>
</template>
<script type="text/ecmascript-6">
import page1 from './components/page1/page1';
export default {
name: 'appVue',
data(){
return {
infodata:{
‘name’:’曾田生’,
‘age’:'24'
}
}
},
components: {
page1
}
}
</script>
<style lang="scss">
</style>
子组件 page1
<template>
<div id="page1">
<p>{{infodata.name}}</p>
<p>{{infodata.age}}</p>
</div>
</template>
<script type="text/ecmascript-6">
export default {
props: {
infodata: {
type: Object,
default: function () {
return{
‘name’:’xxx’,
‘age’:'111'
}
}
}
}
}
</script>
<style lang="scss">
</style>
父组件 通过 v-bind
将组件的 data 数据
绑定在子组件上,子组件再利用 props对象
接收父组件传递过来的值,接着就可以像组件的 data 数据一样尽情的使用了。
3、props watch
有这么一个场景是:子组件拿到了父组件给过来的值,但随着用户对父组件的操作,数据要反馈到子组件上,
那么这个场景就可以使用 vue 的 watch对象
<template>
<div id="page1">
<p>{{infodata.name}}</p>
<p>{{infodata.age}}</p>
</div>
</template>
<script type="text/ecmascript-6">
export default {
props: {
infodata: {
type: Object,
default: function () {
return{
‘name’:’xxx’,
‘age’:'111'
}
}
}
},
watch:{
’infodata’:function(){
console.log('infodata 数据变化会触发我这个方法的执行' );
}
}
}
</script>
<style lang="scss">
</style>
利用 watch
对象 来监听 props对象中 infodata属性的变化 ,当然了,也可以用来监听 组件中 data数据的变化
4、父组件调用子组件的方法
有时候咱们需要在父组件里调用子组件的方法,利用强大的 vue 也是很容易做到的
父组件:
给子组件上注册引用信息 ref="page1"
,拿到改引用信息 this.$refs.page1
,其实也就是获取子组件的意思, 接着调用子组件的方法 this.$refs.page1.handleParentClick()
; handleParentClick
是方法名,
可以自定,只要子组件也有对应的方法名即可。
<template>
<div id="appVue">
<div class='ddiv' @click="divClick" ></div>
<page1 ref="page1" :infodata="infodata"></page1>
</div>
</template>
<script type="text/ecmascript-6">
import page1 from './components/page1/page1';
export default {
name: 'appVue',
data(){
return {
infodata:{
‘name’:’曾田生’,
‘age’:'24'
}
}
},
methods:{
divClick:function(){
//调用子组件 page1 的 handleParentClick 方法
this.$refs.page1.handleParentClick();
}
},
components: {
page1
}
}
</script>
<style lang="scss">
</style>
子组件:
子组件在 methods 对象里声明 被父组件调用的方法 handleParentClick
<template>
<div id="page1">
<p>{{infodata.name}}</p>
<p>{{infodata.age}}</p>
</div>
</template>
<script type="text/ecmascript-6">
export default {
props: {
infodata: {
type: Object,
default: function () {
return{
‘name’:’xxx’,
‘age’:'111'
}
}
}
},
watch:{
’infodata’:function(){
console.log('infodata 数据变化会触发我这个方法的执行' );
}
},
methods:{
handleParentClick: function () {
console.log('父组件唤起了该方法的执行' );
}
}
}
</script>
<style lang="scss">
</style>
5、子组件给父组件回传数据
上面第4点讲了父组件可以调用子组件的方法,但是 子组件是不能调用父组件的方法的,为了保护父组件
数据不被污染或破坏。但 vue 也用了一套方法 来将子组件的数据回传给父组件。
组件除了可以给 div 加上 `v-on:click = 'doSomething'` 来对 div监听点击事件外,父组件还可以
用 `v-on:name='listenChild' `来监听子组件传递给父组件的数据。
父组件:
父组件可以在使用子组件的地方直接用 v-on
来监听子组件触发的事件。
<template>
<div id="appVue">
<div class='ddiv' @click="divClick" ></div>
<page1 v-on:page-to-appvue='listenChild' ref="page1" :infodata="infodata"></page1>
</div>
</template>
<script type="text/ecmascript-6">
import page1 from './components/page1/page1';
export default {
name: 'appVue',
data(){
return {
infodata:{
‘name’:’曾田生’,
‘age’:'24'
}
}
},
methods:{
listenChild: function (msg) {
console.log('监听子组件传递过来的数据'+msg+‘并触发改方法的执行’ );
},
divClick:function(){
//调用子组件 page1 的 handleParentClick 方法
this.$refs.page1.handleParentClick();
}
},
components: {
page1
}
}
</script>
<style lang="scss">
</style>
子组件:
使用 $emit(eventName)
触发事件
<template>
<div id="page1">
<div @click="divClick" ></div>
<p>{{infodata.name}}</p>
<p>{{infodata.age}}</p>
</div>
</template>
<script type="text/ecmascript-6">
export default {
props: {
infodata: {
type: Object,
default: function () {
return{
‘name’:’xxx’,
‘age’:'111'
}
}
}
},
watch:{
’infodata’:function(){
console.log('infodata 数据变化会触发我这个方法的执行' );
}
},
methods:{
divClick:function(){
// 给父组件发送消息
this.$emit('page-to-appvue',{‘name’:’xxx’,‘age’:'111'});
},
handleParentClick: function () {
console.log('父组件唤起了该方法的执行' );
}
}
}
</script>
<style lang="scss">
</style>
三、nodejs 模拟线上数据调试
做前端开发一般不会只做静态页面,特别是使用 vue 框架的时候,一般是具有复杂点的数据交互你才选择它。
那就免不了需后台数据的调试,咱们可以先写好接口,再模拟一下后台数据,到时候前后端数据联调
就会轻松多了
1、开发中的调试
在项目的跟目录下模拟一份json数据:
data.json
{
"userData": {
"id": 1,
"openid": "oC_mwjjqkqwsjm9Yvoq-Zk06Nntsws",
"nickname": "曾田生",
"sex": 1,
"language": "zh_CN",
"city": "Zhangzhou",
"province": "Fujian",
"country": "China",
"headimgurl": "http://wx.qlogo.cn/mmopen/H5nYy4sS0Dt1ChHtmOHwfTX86TjV1b28afBSIDsDoMVttaO213SlZUsmNGAX9h73mtJJvEcruOibbM0tSia6AfBgrqP4ibaXMJyTa/0",
"privilege": "",
"unionid": "oEexiuGFcp_4a1oPSsKLkMS938Tlg",
"goTo": "23,43,12,34,34",
"wantTo": "34",
"createTime": 1483002136000
}
}
当咱们执行 npm run dev
的时候会执行项目 build 目录下的 dev-server.js
的这个 server文件
,
咱们就在这个文件里头配置一些路由,模拟一些供页面访问的接口。
往 dev-server.js
脚本插入如下代码, 模拟监听来自 客户端的请求
var express = require('express')
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
// 获取模拟数据
var appData = require('../data.json');
var userData = appData.userData;
// get请求
app.get('/process_get', function (req, res) {
// 输出 JSON 格式
var response = {
err:0,
data:userData
};
res.end(JSON.stringify(response));
})
// post 请求
app.post('/getUserData', function (req,res) {
var response = {
err:0,
data:userData
};
res.end(JSON.stringify(response));
});
在客户端组件里发起请求:
<template>
<div id="appVue">
<div class='ddiv' @click="divClick" ></div>
<page1 v-on:page-to-appvue='listenChild' ref="page1" :infodata="infodata"></page1>
</div>
</template>
<script type="text/ecmascript-6">
import VueResource from 'vue-resource';
// 全局注册 ,将组件添加到 vue 里面
Vue.use(VueResource);
import page1 from './components/page1/page1';
export default {
name: 'appVue',
data(){
return {
infodata:{
‘name’:’曾田生’,
‘age’:'24'
}
}
},
created(){
// 客户端 post 请求
this.$http.post('/getUserData', {'openid': urlFrom.openid}).then((response) => {
var resData = JSON.parse(response.body);
if (resData.err === 0) {
// 请求成功,返回数据
} else {
console.log('---------ERR-----------');
}
});
// 客户端 get 请求
this.$http.get('/getUserData').then((response) => {
response = response.body;
}
});
}
methods:{
listenChild: function (msg) {
console.log('监听子组件传递过来的数据'+msg+‘并触发改方法的执行’ );
},
divClick:function(){
//调用子组件 page1 的 handleParentClick 方法
this.$refs.page1.handleParentClick();
}
},
components: {
page1
}
}
</script>
<style lang="scss">
</style>
2、线上发布项目的的调试
这里我用的是 node.js
来做后端开发 ,在项目的根目录建个 server.js
文件 :
var express = require('express');
var app = express();
var routar = express.Router();
// get请求
routar.get('/getUserData', function (req, res) {
// 输出 JSON 格式
var response = {
err:0,
data:userData
};
res.end(JSON.stringify(response));
})
// post 请求
routar.post('/getUserData', function (req,res) {
var response = {
err:0,
data:userData
};
res.end(JSON.stringify(response));
});
app.use(routar);
var server = app.listen(8888, function () {
var host = server.address().address;
var port = server.address().port;
console.log("应用实例,访问地址为 http://%s:%s", host, port)
})
npm run build
咱们的项目 ,会打包编译完 .vue
文件 ,在项目的跟目录下回生成 dist 文件夹
,里面的
资源就是咱们要发布到线上的脚步和网页文件。
执行 node server.js
即可启动该执行文件,至此,前后端项目都编译启动完成,可以做线上调试了。
总结
本篇稍微讲了一下利用 vue-cli 脚手架进行前端项目开发的大概流程,知识点讲的有粗有细,大家可以对大体流程有所了解,对细节知识点不妨去 google 百度 深入学习。
vue 项目
用微信扫一扫打开:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。