转载

vue项目实战

看了一个礼拜的 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 ,如下图:

vue项目实战

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 项目

用微信扫一扫打开:

vue项目实战
原文  https://segmentfault.com/a/1190000008209734
正文到此结束
Loading...