利用vue-router和compoment重构代码--踩坑

业务主要功能

  • 获取所有的数据库列表
  • 点击某一个数据库列表的时候,右侧分页展示数据
  • 点击右侧某一条数据的时候,现实数据详情

以下是之前的页面,存在以下问题:

  • 前段开发没有工程化(webpack)
  • 主要功能耦合,列表,详情,(检索,重构的是为了加功能方便)
  • 左侧的数据库链接是直接跳页的,分页的链接是跳页的,右侧点击的详情页却是vue-resource加载的
  • 代码结构混乱,之前为了快速实现功能。所有代码写在一个文件上。难读。

功能效果图

数据列表页效果




数据详情效果




代码重构思路

  • 前段模块化开发,用webpack,参考我
  • 利用compoment组件化,组件化原则:组件只需要告诉别自己什么状态,状态自治。组件不要去要求别的组件做什么
  • 因为用vue就要体验spa,根据页面功能,利用vue-router配置页面路由

重构开始

  1. 因为功能少,所以就略过了 前段模块化开发,用webpack,参考我这篇
  2. 因为之前所有代码都是写在一个文件的,现在为了代码清晰易读易扩展,将前段js代码拆分为三个文件

compoments.js对应抽离的组件

router.js配置路由文件

show_database.js vue实例

  1. 分别将页面抽成6个组件

itemsNumber--显示数据条数

databaseLists--左侧数据库列表

itemsLists--右侧数据列表

pagination --底部的分页

itemDetail --详情页

listCompoment --vue-router用到的组件包含itemsListspagination

  1. 页面路由暂时分成列表/core/:core和详情/detail/:id两个路由,以后还有个检索页的路由

因为数据列表和详情的数据是独立接口获取的,这样分符合功能

(想了很久,没想到更好地想法,第一次接触vue-router,一边文档,一边coding)


重构中---踩坑--填坑

一、填坑工具

二、遇到的那些坑

  • vue-router文档中的一些功能只有在新版本中才有效,一开始怕3.0太冒进了,就选了个2.0,一段时间后发现一些功能死活不成功如:router.push等。细看文档。原来是新版本特有的。所以以后看选版本要对着文档选,实在不行就选择最新的大版本,如3.0
  • vue-router中如何给组件传props?细看文档向路由组件传递 props搞定
  • vue-router中如何监听路由组件中的事件?因为路由组件listCompoment获取到数据库列表中需要向外发送找到的数据
            //发送找到的数据
            this.$emit(‘num-found‘,this.numFound);

    我记得在官方文档通过事件向父级组件发送消息

    v-on:num-found在组件上监听是官方文档的做法。但是路由组件怎么绑定事件呢?$emit的事件是可以用$on来接受的?;然而试了不可以;

折腾了很久,直接电话老同学,得知可以直接在router-view中绑定事件监听

router-view(v-on:num-found=‘getnumFound‘)
  • 如果是触发事件是包含大写的却不能成功

    this.$emit(:‘numFound‘,this.numFound);

    v-on:numFound

  • 。。。。。。未完待续

贴代码

  • templates/views/show_database/show_database.pug

    extends ../../layouts/default
    include ../../mixins/footer-js
    include ../../mixins/search_components
    block css
        link(rel="stylesheet", href="/styles/document/document_search.css")
        style.
            .result_static {
                padding: 15px 0;
                margin-bottom: 20px;
                border: #BDE8F2 1px solid;
                background-color: #EFF6FA;
                text-align: center;
                font-size: 14px;
            }
            .result_static strong {
                color: #F30;
                font-size: 18px;
                font-weight: normal;
                padding: 0 5px;
            }
            .show_database_item{
                border-bottom: 1px solid #e5e6e7;
                margin-top: 15px;
                padding-bottom: 5px;
            }
            .show_database_item h4{
                color: #259;
                box-sizing: border-box;
                font-size: 14px;
                font-weight: bold;
                letter-spacing: 1px;
                line-height: 16px;
                text-align: left;
            }
            .show_database_item p{
                font-weight: normal;
                text-align: left;
                word-break: break-all;
                color: #222;
                letter-spacing: 1px;
                font-size: 13px;
            }
    block content
        script(type=‘text/x-template‘,id=‘items_number‘)
            div.result_static 找到相关数据
                strong(v-text=‘number || 0‘)
                | 条
        script(type=‘text/x-template‘,id=‘database_lists‘)
            .list-group
                a.list-group-item(v-on:click=‘jumpNew(core.core._id,50,0)‘,href=‘javascript:void(0);‘,v-for="(core,index) in cores",v-bind:key="index", v-bind:class="{‘active‘:core.core._id==currentId}",v-text="core.core.alias || core.core.name")
        script(type=‘text/x-template‘,id=‘items_lists‘)
            div
                .col-xs-12(v-for="(item,index) in data",v-bind:key="index")
                    div.show_database_item
                        h4 {{ parseInt(start)+(index+1)}}、
                            a(href=‘javascript:void(0);‘,v-on:click.prevent="showDetail(item.id)",v-text="item.name || item.Title || item.title || item.productname")
                        p {{item | content}}
        script(type=‘text/x-template‘,id=‘item_detail‘)
            .col-xs-12.col-sm-8.col-md-9(v-if="isShowDetail")
                .row
                    .col-xs-12
                        h5(v-on:click="backFn")
                            a(href=‘javascript:void(0);‘) <<返回
                    .col-xs-12
                        table.table.table-bordered.table-striped(v-if="tableData.length")
                            tbody
                                tr(v-for="(item,index) in tableData",v-bind:key="index")
                                    td.text-center(v-text="item.name")
                                    td(v-text="item.value")
        script(type=‘text/x-template‘,id=‘pagination‘)
            div.text-center
                nav(aria-label="Page navigation")
                    ul.pagination
                        li(v-for="item in pagesList",v-bind:class="{‘active‘:item.show}")
                            a(v-bind:href="‘‘+item.link")
                                span(v-text="item.label")
        script(type=‘text/x-template‘,id=‘items_search‘)
        script(type=‘text/x-template‘,id=‘list_compoment‘)
            .col-xs-12.col-sm-8.col-md-9
                .row
                    items-lists(v-bind:data=‘data‘,v-bind:show-detail=‘showDetail‘,v-bind:start=‘start‘)
                    pagination(v-bind:pages-list=‘pagesList‘)
    
        .row#app
            //- .patent-search-div.row
                if normalInfo && normalInfo.title
                    div.patent-info.col-sm-3.text-center !{normalInfo.title}
                else
                    div.patent-info.col-sm-3.text-center 检索
                .patent-search-main.col-sm-9
                    //检索框
                    +searchBox(normalInfo,keyword)
            .col-xs-12.col-sm-4.col-md-3
                items-number(v-bind:number=‘numFound‘)
                database-lists(v-bind:cores=‘cores‘,v-bind:current-id=‘currentId‘,v-bind:jump-new=‘jumpNew‘)
            //- .col-xs-12.col-sm-8.col-md-9(v-if="!isShowDetail")
                .row
                    items-lists(v-bind:data=‘data‘,v-bind:show-detail=‘showDetail‘,v-bind:start=‘start‘)
                    pagination(v-bind:pages-list=‘pagesList‘)
            //- item-detail(v-bind:is-show-detail=‘isShowDetail‘,v-bind:table-data=‘tableData‘,v-bind:back-fn=‘closeDetail‘)
            router-view(v-on:num-found=‘getnumFound‘)
    block page-js
        script(src="https://cdn.bootcss.com/vue/2.5.16/vue.js")
        script(src="https://cdn.bootcss.com/vue-resource/1.5.0/vue-resource.js")
        script(src="https://cdn.bootcss.com/vue-router/3.0.0/vue-router.js")
        //- script(src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js")
        //- script(src="https://cdn.bootcss.com/vue-resource/1.5.0/vue-resource.min.js")
        //- script(src="https://cdn.bootcss.com/vue-router/3.0.0/vue-router.min.js")
        script(src="/js/show_database/compoments.js")
        script(src="/js/show_database/router.js")
        script(src="/js/show_database/show_database.js")
  • public/js/show_database/show_database.js
    var vm = new Vue({
        el:‘#app‘,
        data:{
            name:‘show_database‘,
            cores:[],
            currentId:‘‘,
            currentCore:‘‘,
            data:[],
            numFound:0,
            start:0,
            rows:50,
            pagesList:[],
            tableId:‘‘,
            isShowDetail:false,
            detailData:{},
            tableData:[]
        },
        created:function () {
            this.$on(‘num-found‘,function (num) {
                console.log(num);
            })
        },
        mounted:function  () {
            console.log(this.$router.params);
    
            // if (this.$router.params.core) {
            //     this.currentId = this.$router.params.core;
            // }
            // if (this.$router.query.rows) {
            //     this.rows = this.$router.query.rows;
            // }
    
            // if (this.$router.query.start) {
            //     this.start = this.$router.query.rows
            // }
    
            if (location.search) {
                var search = location.search.slice(1,location.search.length);
                var l = search.split(‘&&‘);
                for (var index = 0; index < l.length; index++) {
                    var  element = l[index];
                    var ll = element.split(‘=‘);
                    if (ll.length&&ll[0]&&ll[1]&&ll[0]==‘start‘) {
                        this.start = ll[1];
                        console.log(ll[1]);
    
                    }
                    if (ll.length&&ll[0]&&ll[1]&&ll[0]==‘rows‘) {
                        this.rows = ll[1];
                        console.log(ll[1]);
    
                    }
                    if (ll.length&&ll[0]&&ll[1]&&ll[0]==‘id‘) {
                        this.currentId = ll[1];
                        console.log(ll[1]);
    
                    }
                }
            }
            //获取所有的数据库,过滤后返回
            this.$http.get(‘/api/core‘)
            .then(function (response) {
                if (response&&response.body.result) {
                    this.cores = response.body.result.filter(function (core) {
                        if (core.core.core&&core.core.core.indexOf(‘newscore‘)>-1) {
                            return false;
                        }
                        return core.core.core;
                    })
                    if (!this.currentId&&this.cores.length) {
                        this.currentId = this.cores[0].core._id || ‘‘;
                        this.tableId = this.cores[0].core._id || ‘‘;
                        // this.getDatabaseData(this.currentId);
                        this.$router.push({ name: ‘core‘, params: {
                            core: this.currentId,
                            rows:this.rows,
                            start:this.start
                        },
                        query: {
                            rows: this.rows,
                            start:this.start
                         }
                    })
                    }
                    var id = this.currentId;
                    var tableId,currentCore;
                    this.cores.filter(function (core) {
                        if (core.core._id == id) {
                            tableId = core.core._id
                            currentCore = core;
                        }
                        return false;
                    });
                    if (tableId) {
                        this.tableId = tableId;
                    }
                    if (currentCore) {
                        this.currentCore = currentCore;
                    }
                }
            }).catch(function (err) {
                console.log(err);
            });
    
            if (this.currentId) {
                // this.getDatabaseData(this.currentId);
                console.log(this.currentId,‘dfdfdsfsdfsdf‘);
    
                this.$router.push({ name: ‘core‘, params: {
                    core: this.currentId,
                    rows:this.rows,
                    start:this.start
                },
                query: {
                    rows: this.rows,
                    start:this.start
                 }
            })
            }
        },
        methods:{
    
            //获取数据
            // getDatabaseData(id){
            //     var id = id || this.currentId;
            //     this.currentId = id;
            //     var url = ‘/api/collection/search/‘+id+‘?start=‘+this.start+‘&&rows=‘+this.rows;
            //     this.$http.get(url)
            //     .then(function (response) {
            //         console.log(response);
            //         this.data = response.body.result.docs;
            //         this.numFound = response.body.result.numFound;
            //         this.pagesList = getPageList(this.numFound,this.rows,this.start,‘/show_database?id=‘+this.currentId)
            //     }).catch(function (err) {
            //         console.log(err);
            //     });
            // },
            // 展示详情
    
            //监听num-found事件
            getnumFound(num){
                this.numFound = num;
            },
            showDetail(id,evt){
    
                if (!id || !this.tableId) {
                    return ;
                }
                var url = ‘/api/collection/search/‘+this.tableId+‘/‘+id;
                this.$http.get(url).then(function (response) {
    
                    if (response.body.success) {
                        this.detailData = response.body.result;
                        this.isShowDetail = true;
                    }else{
                        alert(response.body.message)
                    }
                }).catch(function (err) {
                    console.log(err);
    
                });
            },
            closeDetail(){
                this.isShowDetail = false;
            },
            //TODO 重构
            jumpNew(core,rows,start){
                this.currentId = core;
                this.$router.push({ name: ‘core‘, params: {
                    core: core,
                    rows:rows,
                    start:start
                },
                query: {
                    rows: rows,
                    start:start
                 }
                })
            }
    
        },
        watch:{
            detailData:function (nv,ov) {
                console.log(nv,ov);
    
                if (nv) {
                    var arr = [];
                    for (var key in nv) {
                        if (nv.hasOwnProperty(key)) {
                            var e = nv[key];
                            var obj = {
                                name:‘‘,
                                value:‘‘
                            };
                            obj.value= e;
                            //获取中文名称
                            if (this.currentCore&&this.currentCore.schema&&this.currentCore.schema.length) {
                                obj.name =  getAlias(this.currentCore.schema,key)
                            }
                            arr.push(obj);
                        }
                    }
                    this.tableData = arr;
                }
            }
        },
        components:{
            ‘items-number‘:itemsNumber,//结果数目显示
            ‘database-lists‘:databaseLists,//数据库列表展示
            ‘items-lists‘:itemsLists,//数据列表展示
            ‘pagination‘:pagination,//分页
            ‘item-detail‘:itemDetail,//详情
            ‘list-compoment‘:listCompoment
        },
        router:router
    })
  • public/js/show_database/compoments.js
    var itemsNumber = {
        template:‘#items_number‘,
        props:[‘number‘],
    };
    var databaseLists = {
        template:‘#database_lists‘,
        props:[‘cores‘,‘currentId‘,‘jumpNew‘],
    };
    var itemsLists = {
        template:‘#items_lists‘,
        props:[‘data‘,‘showDetail‘,‘start‘],
        filters:{
            content:function (value) {
                var ss = ‘‘;
                // console.log(value);
                if (!value) {
                    return ss;
                }
                if (typeof value ==‘string‘) {
                    return value;
                }
                if (typeof value ==‘object‘) {
                    for(var key in value){
                        //获取中文名称
                        var name = key;
                        if (vm.currentCore&&vm.currentCore.schema&&vm.currentCore.schema.length) {
                            name =  getAlias(vm.currentCore.schema,key)
                            // console.log(name);
    
                        }
                        if (value.hasOwnProperty(key) === true && key!=‘id‘){
                            var s = name+‘:‘+value[key]+‘;‘
                            ss+=s;
                        }
                    }
                }
                if(ss&&ss.length>200){
                    ss = ss.slice(0,200)+‘...‘
                }
                return ss;
            }
        }
    };
    var pagination = {
        template:‘#pagination‘,
        props:[‘pagesList‘]
    };
    
    var itemDetail = {
        template:‘#item_detail‘,
        props:[‘isShowDetail‘,‘tableData‘,‘backFn‘]
    }
    var listCompoment = {
        template:‘#list_compoment‘,
        // props:[‘data‘,‘showDetail‘,‘start‘,‘pagination‘],
        props:[‘core‘,‘rows‘,‘start‘],
        components:{
            ‘pagination‘:pagination,//分页
            ‘item-detail‘:itemDetail,//详情
            ‘items-lists‘:itemsLists
        },
        data:function () {
            return {
                data:[],
                showDetail:false,
                pagination:[],
                numFound:0,
                currentId:‘‘,
                pagesList:[]
            }
        },
        methods:{
            //获取数据
            getDatabaseData(id){
                var id = id || this.currentId;
                this.currentId = id;
                var url = ‘/api/collection/search/‘+id+‘?start=‘+this.start+‘&&rows=‘+this.rows;
                this.$http.get(url)
                .then(function (response) {
                    // console.log(response);
                    this.data = response.body.result.docs;
                    this.numFound = response.body.result.numFound;
                    //发送找到的数据
                    this.$emit(‘num-found‘,this.numFound);
                    this.pagesList = getPageList(this.numFound,this.rows,this.start,‘/show_database?id=‘+this.currentId)
                }).catch(function (err) {
                    console.log(err);
                });
            }
        },
        created:function () {
            console.log(this.$route.params)
            // console.log(this.core,this.rows,this.start)
            this.getDatabaseData(this.core);
        },
        watch:{
            ‘$route‘:function (to, from) {
                this.getDatabaseData(this.core);
                console.log(to,from);
    
            }
        }
    }
    function getAlias(schema,name) {
        if (!schema || !name || !schema.length) {
            return ‘‘;
        }
        var alias=name;
        for (var index = 0; index < schema.length; index++) {
            var e = schema[index];
            if (e.name && e.name == name && e.alias) {
                alias = e.alias;
                break;
            }
        }
        return alias;
    }
    function getPageList(total, rows, start, url) {
      var rtn = getPagesInfo(total, rows, start);
      var pages = rtn.pages;
      var _out = [];
      if (rtn.currentPage != 1) {
        _out.push({
          label: ‘上一页‘,
          link: url+‘&&start=‘+rows*(rtn.previous - 1)+‘&&rows=‘+rows
        //   link: toSearch(query, ‘start‘, (rtn.previous - 1) * rtn.rows)
        })
      }
      if (rtn.pages.indexOf(1) < 0) {
        _out.push({
          label: ‘首页‘,
          link: url
        //   link: toSearch(query, ‘start‘, 0)
        })
      }
      pages.map((p, i) => {
        _out.push({
          show: p == rtn.currentPage,
    
          link: p == ‘...‘ ? "" : url+‘&&start=‘+rows*(p-1)+‘&&rows=‘+rows,
        //   toSearch(query, ‘start‘, (p - 1) * rtn.rows),
        //   link: p == ‘...‘ ? "" : toSearch(query, ‘start‘, (p - 1) * rtn.rows),
          label: p
        })
      })
      if (rtn.pages.indexOf(rtn.totalPages) < 0) {
        _out.push({
          label: rtn.totalPages,
          link: url+‘&&start=‘+rows*(rtn.totalPages - 1)+‘&&rows=‘+rows,
        //   toSearch(query, ‘start‘, (rtn.totalPages - 1) * rtn.rows)
        //   link: toSearch(query, ‘start‘, (rtn.totalPages - 1) * rtn.rows)
        })
      }
      if (rtn.currentPage != rtn.totalPages) {
        _out.push({
          label: ‘下一页‘,
          link: url+‘&&start=‘+rows*(rtn.next - 1)+‘&&rows=‘+rows,
        //   toSearch(query, ‘start‘, (rtn.next - 1) * rtn.rows)
        //   link: toSearch(query, ‘start‘, (rtn.next - 1) * rtn.rows)
        })
      }
      return _out;
    }
    
    function getPagesInfo(total, rows, start) {
      total = parseInt(total);
      rows = parseInt(rows);
      start = parseInt(start);
      var totalPages = Math.ceil(total / rows);
      var currentPage = parseInt(start / rows) + 1;
      var pagaSize = rows;
      var rtn = {
        total: total,
        currentPage: currentPage,
        totalPages: totalPages,
        pages: [],
        previous: (currentPage > 1) ? (currentPage - 1) : false,
        next: (currentPage < totalPages) ? (currentPage + 1) : false,
        first: 0,
        last: totalPages * pagaSize,
        rows: pagaSize,
      };
      getPages(rtn, 10);
      console.log(rtn);
    
      return rtn;
    }
    
    function getPages (options, maxPages) {
        var surround = Math.floor(maxPages / 2);
        var firstPage = maxPages ? Math.max(1, options.currentPage - surround) : 1;
        var padRight = Math.max(((options.currentPage - surround) - 1) * -1, 0);
        var lastPage = maxPages ? Math.min(options.totalPages, options.currentPage + surround + padRight) : options.totalPages;
        var padLeft = Math.max(((options.currentPage + surround) - lastPage), 0);
        options.pages = [];
        firstPage = Math.max(Math.min(firstPage, firstPage - padLeft), 1);
        for (var i = firstPage; i <= lastPage; i++) {
            options.pages.push(i);
        }
        if (firstPage !== 1) {
            options.pages.shift();
            options.pages.unshift(‘...‘);
        }
        if (lastPage !== Number(options.totalPages)) {
            options.pages.pop();
            options.pages.push(‘...‘);
        }
    }
  • public/js/show_database/router.js
    // 0. 如果使用模块化机制编程,导入Vue和VueRouter,要调用 Vue.use(VueRouter)
    
    // 1. 定义(路由)组件。
    // 可以从其他文件 import 进来
    // var Foo = { template: ‘<div>foo-><router-link to="/bar">Go to Bar</router-link></div>‘ }
    // var Bar = { template: ‘<div>bar-><router-link to="/foo">Go to Foo</router-link></div>‘ }
    
    // 2. 定义路由
    // 每个路由应该映射一个组件。 其中"component" 可以是
    // 通过 Vue.extend() 创建的组件构造器,
    // 或者,只是一个组件配置对象。
    // 我们晚点再讨论嵌套路由。
    var routes = [
      {
          path: ‘/core/:core‘,
          component: listCompoment,
          name:‘core‘,
          props:function (route) {
            //   console.log(route,‘-----‘)
            //   routes.query.rows = route.params.rows;
            //   routes.query.start = route.params.start;
              return {
                  core:route.params.core,
                  rows:route.params.rows,
                  start:route.params.start
              }
          }
        }
        // ,
    //   {
    //       path: ‘/detail/:tableId/:itemId‘,
    //       component:itemDetail,
    //       name:‘detail‘,
    //       props:{
    //         isShowDetail:this.isShowDetail,
    //         tableData:this.tableData,
    //         backFn:this.closeDetail
    //       }
    //     }
    ]
    
    // 3. 创建 router 实例,然后传 `routes` 配置
    // 你还可以传别的配置参数, 不过先这么简单着吧。
    var router = new VueRouter({
      routes: routes,
      mode: ‘history‘,
      base:‘/show_database/‘
      //   routes // (缩写)相当于 routes: routes
    })
    
    // 4. 创建和挂载根实例。
    // 记得要通过 router 配置参数注入路由,
    // 从而让整个应用都有路由功能
    // var app = new Vue({
    
    // }).$mount(‘#app‘)
    
    // 现在,应用已经启动了!

其实代码还没重构完。。

原文地址:https://www.cnblogs.com/ivanlee-ee-233/p/9017076.html

时间: 2024-08-29 10:55:24

利用vue-router和compoment重构代码--踩坑的相关文章

关于vue+axios上传文件的踩坑分析

上传文件是每个前端开发者都会遇到的问题,在之前实习期做了一个上传文件的功能,当时没有彻底搞明白问题所在,现在重新复盘下. 1.使用formData来上传文件,没有使用axios上传文件,之前在学校有做过.生成一个formData对象 let formData = new FormData() formData.append('xxx', 'yyyyy') 通过dom操作获得input中file[0],然后append给formData对象,网上有详细的api 2.在使用axios之后发先我之前用

Vue项目踩坑记~

最近在写一个Vue的项目~踩了很多坑,下面总结一下出现的问题 1.空白页面,不提示报错,但是什么都没有 main.js const app = new Vue({ router }).$mount('#app') 错误原因:在创建vue实例对象时,没有添加render方法. 解决: const app = new Vue({ router, render: h => h(App) }).$mount('#app') 2."TypeError: Cannot read property 'g

一、Vue Router 的使用

什么是路由 路由是根据不同的url地址展示不同的内容或页面.可分为前端路由和后端路由. 后端路由:通过用户请求的url导航到具体的html页面:每跳转到不同的URL,都是重新访问服务端,然后服务端返回页面,页面也可以是服务端获取数据和模版组合,返回HTML,也可以是直接返回模版HTML,然后由前端再去请求数据,使用前端模版和数据进行组合,生成想要的HTML.(意味着,浏览器刷新页面.网速慢的话说不定屏幕全白再有新内容) 简单来说路由就是用来跟后端服务器进行交互的一种方式,通过不同的路径,来请求不

vue router 导入方式

vue router 的路由导入方式可用以下两种: 一:直接导入 import Hello from '@/components/Hello' @是在webpack.base.conf.js 配置: resolve: { extensions: ['.js', '.vue', '.json'], alias: { 'vue$': 'vue/dist/vue.esm.js', '@': resolve('src') } } 二 :路由懒加载方式 当打包构建应用时,Javascript包会变得非常大

利用Vue.js实现拼图游戏

之前写过一篇<基于Vue.js的表格分页组件>的文章,主要介绍了Vue组件的编写方法,有兴趣的可以访问这里进行阅读:http://www.cnblogs.com/luozhihao/p/5516065.html 前言 为了进一步让大家了解Vue.js的神奇魅力,了解Vue.js的一种以数据为驱动的理念,本文主要利用Vue实现了一个数字拼图游戏,其原理并不是很复杂,效果图如下: demo展示地址为:https://luozhihao.github.io/vue-puzzle/index.html

vue router 参数获取

vue router 参数获取通常是通过$route.query和$route.params方法这里将这两种方式通过代码展示出来: 路由代码: import Vue from 'vue' import Router from 'vue-router' import Home from './views/Home.vue' import UserAdd from './components/UserAdd' import UserList from './components/UserList'

vue 组件传值踩坑日记 1

今天在用平时很少用到的传值方式,是V2.4以后新加入属性$attrs $listener 以及inheritAttrs. 总结:这样形式的代码适合套娃模式的组件传递,却不适合兄弟组件的传值,那样的传值方式,需要创建一个事件总线,说白了就是新new一个空的vue,详见,我的第二篇日志<vue 组件传值踩坑日记 2> 废话不多说,直接上代码,大家可以边看注释边测试一下效果吧 <!DOCTYPE html> <html lang="en"> <hea

web前端利用vue.js实现品牌列表的添加,删除与筛选功能

实现效果图: 实现功能:web前端利用vue.js实现品牌列表的添加,删除与筛选功能 实现代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> &l

编程思想:巧用位运算重构代码

开篇 在一门编程语言中,往往会提供大量的运算符.按功能来分的话,有算术运算符.赋值运算符.关系运算符.逻辑运算符.位运算符等.这些对于大家来说都不陌生.但是,本期的主角『位运算』符相对而言是比较少去使用的.因为位运算符主要针对两个二进制数进行位运算. 巧用位运算能极大的精简代码和提高程序效率.所以,在一些优秀的开源代码中,经常能出现位运算.所以,把位运算这种思想迁移到业务代码里,有时候往往能起到柳暗花明般的重构. 位运算 在 JAVA 语言中,定义了诸多的位运算符,如下所示: 运算符 描述 &