业务主要功能

  • 获取所有的数据库列表

  • 点击某一个数据库列表的时候,右侧分页展示数据

  • 点击右侧某一条数据的时候,现实数据详情


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

  • 前段开发没有工程化(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') // 现在,应用已经启动了!

其实代码还没重构完。。

利用vue-router和compoment重构代码--踩坑(一)的更多相关文章

  1. router路由去掉#!的踩坑记

    项目中在研究去掉router#!的过程中的踩坑过程.

  2. 使用Windows下的git工具往github上传代码 踩坑记录

    使用Windows下的git工具往github上传代码 踩坑记录 背景 由于以前接触的项目都是通过svn进行版本控制,现在公司项目使用git,加上自己平时有一个练手小项目,趁着周末试着把项目上传到自己 ...

  3. vue.js利用vue.router创建前端路由

    node.js方式: 利用node.js安装vue-router模块 cnpm install vue-router 安装完成后我们引入这个模板! 下载vue-router利用script引入方式: ...

  4. VUE使用微信JDK(附踩坑记录)

    VUE使用微信分享SDK(附踩坑记录) 微信分享官方文档 安装JS-SDK npm i -S weixin-jsapi 引入包 ES5 写法 const wx = require('weixin-js ...

  5. vue+axios访问本地json数据踩坑点

    当我们想在vue项目中模拟后台接口访问json数据时,我们发现无论如何也访问不到本地的json数据. 注意:1.在vue-cli项目中,我们静态资源只能放在static文件夹中,axios使用get请 ...

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

    上传文件是每个前端开发者都会遇到的问题,在之前实习期做了一个上传文件的功能,当时没有彻底搞明白问题所在,现在重新复盘下. 1.使用formData来上传文件,没有使用axios上传文件,之前在学校有做 ...

  7. 在Cent OS云服务器上部署基于TP5后端代码踩坑记录_艾孜尔江撰

    推荐使用镜像安装Cent OS系统,或者在纯净安装完成之后在完成Apache+MySQL+PHP的时候不要每个单独安装,因为这样会出一些三者之间版本不配的问题,网上各种说法都有,查起来也非常困难,版本 ...

  8. 抛弃vue-webpack-template,踩坑Vue-Cli创建vue项目

    官方指导网站https://cli.vuejs.org/ 一.全局安装@vue/cli //本人包管理工具使用yarn yarn global add @vue/cli 安装完成 二.创建vue项目 ...

  9. vue.js 踩坑第一步 利用vue-cli vue-router搭建一个带有底部导航栏移动前端项目

    vue.js学习 踩坑第一步 1.首先安装vue-cli脚手架 不多赘述,主要参考WiseWrong 的 Vue 爬坑之路(一)-- 使用 vue-cli 搭建项目 2.项目呈现效果 项目呈现网址:w ...

随机推荐

  1. Unity访问Access数据库

    首先,准备工作: 创建一个Access 数据库,命名AccessTest.accdb,添加一些数据用于测试 准备System.Data.dll与System.EnterpriseServices.dl ...

  2. Java 开源Wiki:XWiki

    XWiki是一个由Java编写的基于LGPL协议发布的开源wiki和应用平台.之前只接触过MediaWiki,但是MediaWiki是用PHP写的,一直想找找看有没有熟悉的JAVA语言的Wiki系统. ...

  3. Python3.4 + Django1.7.7 搭建简单的表单并提交

    后面还有一个问题,是我把txt生成了,但是网页没有返回我还不知道,现在怎么直接返回txt并且展示出来txt 的内容,希望大牛不吝赐教 首先有一个问题 django1.7之前,这样用: HttpResp ...

  4. 使用MTL库求解最小二乘解

    最小二乘计算最优解不管是哪个行业肯定都用到的非常多.对于遥感图像处理中,尤其是对图像进行校正处理,关于控制点的几种校正模型中,都用到最小二乘来计算模型的系数.比如几何多项式,或者通过GCP求解RPC系 ...

  5. Linux系统的shell是什么

    shell是用户和Linux操作系统之间的接口.Linux中有多种shell,其中缺省使用的是Bash.本章讲述了shell的工作原理,shell的种类,shell的一般操作及Bash的特性. 什么是 ...

  6. android studio添加project libs库步骤

    在Eclipse中选择要导出的项目,然后依次选择菜单 file->export->Android->Generate Gradle build files. 之后依次点击next到f ...

  7. Remove Google Play Games libraries on iOS (Unity3D开发之二十一)

    猴子原创,欢迎转载.转载请注明: 转载自Cocos2Der-CSDN,谢谢! 原文地址: http://blog.csdn.net/cocos2der/article/details/48313653 ...

  8. CRF资料

    与最大熵模型相似,条件随机场(Conditional random fields,CRFs)是一种机器学习模型,在自然语言处理的许多领域(如词性标注.中文分词.命名实体识别等)都有比较好的应用效果.条 ...

  9. HBase 二级索引与Join

    二级索引与索引Join是Online业务系统要求存储引擎提供的基本特性.RDBMS支持得比较好,NOSQL阵营也在摸索着符合自身特点的最佳解决方案. 这篇文章会以HBase做为对象来探讨如何基于Hba ...

  10. IOS中UITextView(多行文本框)控件的简单用法

    1.创建并初始化 UITextView文本视图相比与UITextField直观的区别就是UITextView可以输入多行文字并且可以滚动显示浏览全文.UITextField的用处多,UITextVie ...