2018年第29周-疾速地在老项目中运用vue的履历

原有项目运用vue的痛点

前端手艺的生长可谓一日千里,更有甚者,在deno开源项目的issue中发“求不要更新了,老子学不动了”,这消息传遍中国的手艺圈子,有人说这是中国人的羞辱。这里我就不批评优劣。但可见,前端生长的速率异常惊人。
但“存期近合理”,黑格尔的这句话,在手艺领域越发是。能够生长的手艺,肯定更人们带来方便。扩展处理题目的局限,或者是进步处理需求的速率等等。
但是关于背景职员,面临遗留下来的背景体系,并没有完整前后端星散,也有公司只要背景职员,前后端都干。那末题目来了,上述这类情况下怎样进步效力呢。引入Angular、React、Vue是能处理效力题目,得益于其MVVM手艺将视图UI和营业逻辑离开等四大特征:

  1. 低耦合。视图(View)能够自力于Model变化和修正,一个ViewModel能够绑定到差别的”View”上,当View变化的时刻Model能够稳定,当Model变化的时刻View也能够稳定。
  2. 可重用性。你能够把一些视图逻辑放在一个ViewModel内里,让许多view重用这段视图逻辑。
  3. 自力开辟。开辟职员能够专注于营业逻辑和数据的开辟(ViewModel)。
  4. 可测试。界面夙来是比较难于测试的,而如今测试能够针对ViewModel来写。

上述特征是否是笼统,前端职员都以为前端手艺生长之快,后端职员就更难打仗和体味。vue官网的例子更是以webpack等模块化例子来解说,如许以来,假如想运用vue的优点罢了,还要去相识webpack、AMD等等,这让后端职员再三地望而生畏。
除了手艺栈的限定,项目时候也是个门坎,虽然我以为前端许多头脑都是源自于后端的头脑,如模块化,mvc,构建手艺等,但学起来照样要时候呢。老板并不会给时候开辟职员去把全部前端推倒了重干。推倒重干也不切实际,一本钱高,二风险大(如能不能完成,或能不能赶在市场时机眼前完成)。所以渐进地转变是比较稳妥的(保守主义)。

所以这里分享下我在老项目疾速运用vue的履历。

vue履历

在原有有项目的html页面里,引入vue的依靠


<!-- Vue.js v2.5.16 -->
<script src="/js/vue/vue.min.js"></script>

<!-- vue-resource v1.5.1 用于ajax要求-->
<script src="/js/vue/vue-resource.min.js"></script>

本例子是一个增加用户表单的提交,就只要运用几个属性 v-model,v-for和v-on:click,以及{{}}占位符
此时html代码只需修正以下(专注于展现):

<div class="form-horizontal" method="post" id="userFrom">
                        <div class="form-group">
                            <input type="text" class="form-control" id="name" placeholder="请输入用户账号"  v-model="name" >
                        </div>
                        <div class="form-group">
                            <input type="password" class="form-control" id="name" placeholder="请输入用户暗码"  v-model="name" >
                        </div>
                        <div class="form-group">
                            <button type="button" class="btn btn-success"  data-toggle="modal" data-target="#myModal">挑选角色</button>
                            <table class="table table-hover" >
                                <thead>
                                <tr>
                                    <th>操纵</th>
                                    <th>角色ID</th>
                                    <th>角色称号</th> 
                                </tr>
                                </thead>
                                <tbody>

                                <tr v-for="(item,index)  in nodeList">
                                    <td>
                                        <button type="button" class="btn btn-danger" v-on:click="remove($event,index)">移除</button>
                                    </td>
                                    <th scope="row">{{ item.id }}</th>
                                    <td>{{ item.name }}</td> 
                                </tr>
                                
                                </tbody>
                            </table>
                        </div>
                        <div class="form-group">
                            <textarea   placeholder="请输入备注"  name="remark" id="remark"  v-model="remark"></textarea>
                        </div>
                        <div class="form-group">
                            <div class="col-xs-2">
                                <button class="btn btn-primary btn-block btn-flat" v-on:click="createUser">增加</button>
                            </div>
                        </div>
</div>


                     <!-- 弹出框,挑选角色,上面的挑选角色按钮则弹出以下对话框,这个是boostra手艺的领域,但不影响vue的运用 -->
                    <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
                        <div class="modal-dialog">
                            <div class="modal-content">
                                <div class="modal-header">
                                    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">
                                        &times;
                                    </button>
                                    <h4 class="modal-title" id="myModalLabel">
                                        挑选角色
                                    </h4>
                                </div>
                                <div class="modal-body">
                                    <table class="table table-hover" id="toChooseTable">
                                        <thead>
                                        <tr>
                                            <th>操纵</th>
                                            <th>角色ID</th>
                                            <th>角色称号</th>
                                        </tr>
                                        </thead>
                                        <tbody>
                                            <tr v-for="(item,index) in toChooseList">
                                                <td>
                                                    <button type="button" class="btn btn-danger" v-on:click="choose($event,index)">挑选</button>
                                                </td>
                                                <th scope="row">{{ item.id }}</th>
                                                <td>{{ item.name }}</td>
                                            </tr>
                                        </tbody>
                                    </table>
                                </div>
                                <div class="modal-footer">
                                    <button type="button" class="btn btn-default" data-dismiss="modal">封闭
                                    </button>
                                </div>
                            </div><!-- /.modal-content -->
                        </div><!-- /.modal -->
                    </div>

script代码修正(专注于数据及其操纵)


<script > 
    //提交表单中的数据及操纵
    var userFrom = new Vue({
        el: '#userFrom',
        data: {
            name:'',
            password:'',
            remark:'',
            roleList: [],
            apiUrl: '/user/add'
        },
        // 在 `methods` 对象中定义要领
        methods: {
            remove: function (event,index) {
                //移除角色
                //1.将未被挑选的角色数据放回弹出框内
                pushToChooseList(this.roleList[index]);
                
                //2.在已挑选的角色table里移除这个角色数据
                this.roleList.splice(index,1);
            },
            createUser: function() {
                var params = {
                    name:this.name,
                    password:this.password,
                    remark:this.remark,
                    roleList:[]
                };

                for(var i=0;i<this.roleList.length;i++){
                    var role={};
                       role.id = this.roleList[i].id;
                    role.name = this.roleList[i].name; 
                    params.roleList.push(node);
                }

                this.$http.post(this.apiUrl,JSON.stringify(params),{
                    emulateJSON:false
                }).then(function(response){
                    // response.data中猎取ResponseData实体
                    console.log(response);
                },function(response){
                    // 发作毛病
                    console.log(response);
                });
            }
        }
    })
    
    //弹出框数据及操纵
     var toChooseTable = new Vue({
        el: '#toChooseTable',
        data: {
            toChooseList: [
            ],
            apiUrl: '/role/list'
        },
        // 在 `methods` 对象中定义要领
        methods: {
             loadData: function() {
                 //加载角色数据
                this.$http.post(this.apiUrl, {}).then(function (response) {
                    var result = response.data;
                    for (var i = 0; i < result.data.length; i++) {
                        var role = {};
                        role.id = result.data[i].id; 
                        role.name = result.data[i].name; 
                        toChooseTable.toChooseList.push(node);
                    }

                }, function () {
                    console.log('failed');
                });
            },
            choose: function (event,index) 
                //挑选角色
                //1.将挑选的角色数据放入被选中的table里
                pushChoosedList(this.toChooseList[index]); 
                //2.移除已被挑选的弹出框的角色数据
                this.toChooseList.splice(index,1);
            }
        }
    })
    //加载角色数据
    toChooseTable.loadData();
    
    
    function pushChoosedList(data) {
        for(j = 0,len=userForm.roleList.length; j < len; j++) {
            if(userForm.roleList[j].id==data.id){ 
                return;
            }
        }
        userForm.roleList.push(data);
    }

    function pushToChooseList(data) {
        for(j = 0,len=toChooseTable.toChooseList.length; j < len; j++) {
            if(toChooseTable.toChooseList[j].id==data.id){ 
                return;
            }
        }
        toChooseTable.toChooseList.push(data);
    }
 
</script>

上述例子很好的展现视图层和数据层的星散,视图和数据层都是零丁离开写的,不知道你能不能从中体味到效力的进步。之前这类弹出框选中数据,在table列表中展现,但是要写很多js代码,需手工建立tr标签,然后再append进table标签等,还要遍历定位标签,横竖写个页面都老半天。有了vue,这效力几乎大大的进步了。

element-ui履历

上述例子中,我们体味到视图层和数据层的星散,但还不是很明白模块化复用,以下就举个模块化复用优点的例子,就是运用element-ui的列表及分页。

引入element-ui
在上述vue基础上,引入:


    <!-- 引入款式 -->
    <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
    <!-- 引入组件库_element-ui@2.4.4@element-ui,官网不供应直接下载,需用cnpm i element-ui -S下载,然后复制lib目次 -->
    <script src="https://unpkg.com/element-ui/lib/index.js"></script>

只需要引入element-ui的table组件和分页组件,即可到达复用
修正html代码:

                <div class="ibox-content" id="content">

                    <!-- table组件 参考:http://element-cn.eleme.io/#/zh-CN/component/table-->
                    <el-table
                            :data="tableData"
                            style="width: 100%">
                        <el-table-column
                                label="日期"
                                width="180">
                            <template slot-scope="scope">
                                <i class="el-icon-time"></i>
                                <span style="margin-left: 10px">{{ scope.row.date }}</span>
                            </template>
                        </el-table-column>
                        <el-table-column
                                label="姓名"
                                width="180">
                            <template slot-scope="scope">
                                <el-popover trigger="hover" placement="top">
                                    <p>姓名: {{ scope.row.name }}</p>
                                    <p>住址: {{ scope.row.address }}</p>
                                    <div slot="reference" class="name-wrapper">
                                        <el-tag size="medium">{{ scope.row.name }}</el-tag>
                                    </div>
                                </el-popover>
                            </template>
                        </el-table-column>
                        <el-table-column label="操纵">
                            <template slot-scope="scope">
                                <el-button
                                        size="mini"
                                        @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
                                <el-button
                                        size="mini"
                                        type="danger"
                                        @click="handleDelete(scope.$index, scope.row)">删除</el-button>
                            </template>
                        </el-table-column>
                    </el-table>

                    <!-- 分页组件-->
                    <div align="center">
                        <el-pagination
                                @size-change="handleSizeChange"
                                @current-change="handleCurrentChange"
                                :current-page="page"
                                :page-sizes="[10, 20, 30, 40]"
                                :page-size="rows"
                                layout="total, sizes, prev, pager, next, jumper"
                                :total="totalRecord">
                        </el-pagination>
                    </div>
                </div>

修正script代码


<script >
    /*<![CDATA[*/
    var content = new Vue({
        el: '#content',
        data: {
            tableData: [{
                date: '2016-05-02',
                name: '王小虎',
                address: '上海市普陀区金沙江路 1518 弄'
            }, {
                date: '2016-05-04',
                name: '王小虎',
                address: '上海市普陀区金沙江路 1517 弄'
            }, {
                date: '2016-05-01',
                name: '王小虎',
                address: '上海市普陀区金沙江路 1519 弄'
            }, {
                date: '2016-05-03',
                name: '王小虎',
                address: '上海市普陀区金沙江路 1516 弄'
            }],
            url:'/user/list',
            //搜刮前提
            criteria: '',
            //下拉菜单选项
            select: '',
            //默许每页数据量
            rows: 10, 
            //当前页码
            page: 1,
            //查询的页码
            start: 1,
            //默许数据总数
            totalRecord: 1000
        },
        // 在 `methods` 对象中定义要领
        methods: {
            loadData: function(criteria, pageNum, pageSize){
                this.$http.post(this.url,{criteria:criteria, page:pageNum, rows:pageSize},{emulateJSON:true}).then(function(res){
                    var page = res.data; 
                    this.tableData = page.data;
                    this.totalRecord = page.totalRecord;
                },function(){
                    console.log('failed');
                });
            },
            handleEdit: function (index, row) {
                console.log(index, row);
            },
            handleDelete: function (index, row) {
                console.log(index, row);
            },
            //每页显现数据量变动
            handleSizeChange: function(val) {
                this.rows = val;
                this.loadData(this.criteria, this.page, this.rows);
            },

            //页码变动
            handleCurrentChange: function(val) {
                this.page = val;
                this.loadData(this.criteria, this.page, this.rows);
            }
        }
    })
    //加载数据
    content.loadData(content.criteria, content.page, content.rows);
    /*]]>*/
</script>

虽然没有运用webpack更完全的模块化。但上述的列子,也够给老项目带来复用的效力提拔,背景职员不必花时候去调款式。

    原文作者:黄小数
    原文地址: https://segmentfault.com/a/1190000015722712
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞