数据模型

mvvm是数据驱动之,数据模型占了严重性的地位,所以,在举办首页最后使之todo列表组件的时节,先暂时在客户端应用数据模型举行开。而既然已经想到了这个多少要经过互从服务端获取,所以是模型直接放入vuex中,数据模型的代码上平等章早已分析过,所以这边一贯复制过来:

indexTodos:[
    {
        month:0,              //月份
        default:1,            //正在显示的月份
        todos:[{
            createTime:new Date(),   //记录时间
            item:'',                 //标题
            content:'',              //内容
            weather:0,               //天气
            mood:0,                  //心情
            bookmark:0,              //标记
            groupid:0,               //所属组
        }]
    }
]

此处用了少于个数组,即月份组,每个月是一个件,而月外为,记事也是一个频繁组,每个记事起就是一个起。

引用vuex

现实到页面中怎么用也?也就是说,页面怎么使vuex库中的价值为?

此间运用computed关键字,在vue中computed关键字的意思是实时统计,或者说监控值的变更,具体到代码中,首先得我们要之vuex组件,这里要状态:

import { mapState } from 'vuex'

下一场运computed来引用组件中的价:

computed: mapState({
        groupId: state=>state.groupId,
        items:state=>state.indexTodos
}),

如此,Index.vue就可以像是用data节点那样,通过this引用这片个价值了。

组件化

这边要思想一下,head有三独item,每个item对应的panel都需要以情节有显得,那么,该怎么决定具体到每个panel的亮或者加载呢?首先pass掉的终将是开三独一律head和foot的页,这样的良明确不相符单页的要求,第二只吃pass掉的当是当这页成立三独div,然后经tabitem来控制div的潜伏呈现了,那么,第三种植办法应该是次种之升级版本,创制三独零件,通过tabitem来采纳不同之零部件加载。

这里我们先创制一个components,用来放我们所欲的零件。

第一,我们起码得六个零部件,也即是针对应tabitem的老三单,分别吗:

  • DiaryPanel.vue
    记录项(为严防和日记记录组相混淆,这里统一改吗记录,标题为点滴,略微文青些)
  • Calendar.vue 日历项
  • Mine.vue 我的项

横组件文件都创建,那么大家事先以他们一股脑的在Index页面中引用。

import DiaryPanelComponents from '../components/DiaryPanel.vue'
import CalendarComponents from '../components/Calendar.vue'
import MineComponents from '../components/Mine.vue'

坐好后,紧接着就是要指向它们举行登记:

components:{
        DiaryPanelComponents,
        CalendarComponents,
        MineComponents
},

此刻,就好同html标签一样接纳了。

<div id="contentPanel">
    <transition   name="custom-classes-transition"
    enter-active-class="animated bounceInLeft"
    leave-active-class="animated fadeOut"
    :duration="{ enter: 700, leave: 200 }"
    >
        <DiaryPanelComponents></DiaryPanelComponents>
    </transition>
</div>

而是,我们想,这样的是页面只可以用DiaryPanelComponents及时一个组件,其他零件怎么处置,假诺以三单零件一股脑的全写在那div节点受到,控制显示隐藏,岂不是以回到了老路上?

哼于vue提供了动态绑定组件的意义,我们当data数据模型中新增一个表示组件名称的属性currentView代表即高居显示状态的零件:

data () {
    return {
        currentView:'DiaryPanelComponents',
        ...
    }
},

下一场修改组件有的沙盘html:

<div id="contentPanel">
    <transition   name="custom-classes-transition"
    enter-active-class="animated bounceInLeft"
    leave-active-class="animated fadeOut"
    :duration="{ enter: 700, leave: 200 }"
    >
        <component v-bind:is="currentView">
        </component>
    </transition>
</div>

然,tab的item采用操作,就改成了可是主旨的之字符串赋值操作:

tabChange:function(event){
    ...
    var componentName = ''
    switch (event) {
        case 'tab1':
        componentName = 'DiaryPanelComponents'
        break
        case 'tab2':
        componentName = 'CalendarComponents'
        break
        case 'tab3':
        componentName = 'MineComponents'
        break
    }
    this.currentView = componentName
}

组件嵌套

首页现在着力只有打一个调度功能,具体的始末交给了组件来完成,上边打开DiaryPanel.vue,对这些组件举办付出。

解析一下这组件,这个组同样分为两部分,头部一个当作标题的月,下边循环展现一个此月具备的记录项。

而是管付出什么人部分,大家都急需事先由vuex大校数据取出来:

import { mapState } from 'vuex'

export default {
    computed: mapState({
        indexTodos: state=>state.indexTodos,
    })
}

余下的就是好简短了,先将展现的局部代码写了,这里用了museui的组件sub-header:

<div  v-for="item in indexTodos" >
    <mu-sub-header class="day_title">{{ item.month }}</mu-sub-header>
    <DiaryListComponents></DiaryListComponents>
</div>

然后按照实际情状修改css样式:

.day_title{
    font-size: 50px; 
    line-height: 55px;
    font-family: 'Microsoft YaHei',arial,tahoma,\5b8b\4f53,sans-serif;
    font-weight: 500;
    color: #5e35b1;
    text-align: center;
    padding: 0px;
}

连通下去就循环突显记录列表了,想转原型中,这么些todo放到了一个面板块内,而面板块或者相比复杂的,并且每个月还如动用,所以,大家呢将他提炼到一个零件中,嗯,就给DiaryList,从此处也得以看来,vue的机件是永葆嵌套的。接下来在components文件夹内成立DiaryList文件。

同时,由于用户会滑动页面,也就是说,那么些组件内所用之价值,即todo数组,是同父组件联系紧密的,所以要经参数的办法,将叔伯组件循环得来的价值传送到子组件中,vue中传值也杀方便,在标签引用的地点绑定一下就实施了:

<DiaryListComponents v-bind:todos="item.todos"></DiaryListComponents>

然后子组件获取更简便易行:

DiaryList.vue:

export default {
    props:["todos"]
}

诸如此类尽管可平昔以todos变量。

假定面板使用museui的pager控件便好了,还起带阴影效果,并且是于循环体内,使用todos变量的pager代码如下;

<mu-paper class="diaryitem" :zDepth="2" v-for="(item) in todos" >
</mu-paper>

过滤器

连片下去便指向斯组件的支出了。观望一下夫片的情:

率先四周都暴发只框,所以用一个父级的mu-content-block包裹转,然后看内容,是一个左中右的结构,刚好museui有只布局表格,就径直动用了,布局表格的权重,暂时就20-6-20咔嚓,最后布局有代码如下:

<mu-paper class="diaryitem" :zDepth="2" v-for="(item) in todos" >
    <mu-content-block>
        <mu-row gutter>
           <mu-col width="20">
           </mu-col>
            <mu-col width="60">
            </mu-col>
            <mu-col width="20" style="text-align:right">
            </mu-col>
        </mu-row>
    </mu-content-block>
</mu-paper>

剩余的情,假使先不考虑体制的话,最简单易行应该就是标题和内容了,直接输入就哼:

<mu-col width="60">
    <div class="item_time">12:34</div>
    <div class="item_title">{{ item.item }}</div>
    <div class="item_content">{{item.content}}</div>
</mu-col>

css的如出一辙会见于圆满,接下便日了,其实时间则实际了如此多,可是现实到了数项达到,实际上仅生一个,就是createtime,接下要召开的便是哪些提取呈现的题目了,这时候vue提供的过滤器就登台了,上边为日期呢条例介绍一下过滤器的故法.

过滤器其实就是是一个因此filter标记的平常js的法门,然后我们事先叫他回来一个原则性数字的写法:

filters: {
    getDay(time) {
        return 3;
    }
}

调用方法为:

{{ item.createTime | getDay }}

其中item.create提姆(Tim)e对承诺模型中之值与过滤器方法的参数,getDay很分明,就是咱过滤器的不二法门了。有了这多少个,完成过滤器就不行粗略了:

getDay(time) {
    var date = new Date(time);
    return  date.getDate(); 
}

这时候页面上就回只展现日期值的。

紧接下去咱们想到,不只是日期需要,其他的要之还有好多,比如月份,时间非凡,而且每当可预见的地点,比如新增记录页,tag的列表页等,所以是效应有必不可少提取复用一下,关于日期操作的js方法网上有那些,就不以讲述,这么些当工具类,通服务端代码一样,成立一个util文件夹,然后就叫Date.js文件,最后之代码如下:

export function formatDate(time, fmt) {
    var date = new Date(time);

    if (/(y+)/.test(fmt)) {
        fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
    }
    let o = {
        'M+': date.getMonth() + 1,
        'd+': date.getDate(),
        'h+': date.getHours(),
        'm+': date.getMinutes(),
        's+': date.getSeconds(),
        'w+':getWeek(date)
    };
    for (let k in o) {
        if (new RegExp(`(${k})`).test(fmt)) {
            let str = o[k] + '';
            fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? str : padLeftZero(str));
        }
    }
    return fmt;
};

function padLeftZero(str) {
    return ('00' + str).substr(str.length);
}
function getDay(time){
    return formatDate(time,"dd");
}

function getWeek(time){
    var weekName=['星期日','星期一','星期二','星期三','星期四','星期五','星期六']
    return weekName[time.getDay()];
}
function getTime(time){
    return formatDate("hh-mm-dd");
}

接下来DirayList组件内引入,并做到剩余的几个过滤器方法:

<script>
    import { formatDate } from '../utils/date.js';
    export default {
        props:["todos"],
        filters: {
            getDay(time) {
                return  formatDate(time,"dd");
            },
            getWeek(time) {
                return  formatDate(time,"w");
            },
            getTime(time) {
                return  formatDate(time,"hh:mm");
            }
        }
    }
</script>

末,是右手边的老五个icon图标,这三单db中储存的是int型,而页面显示得一个String的name,所以,通date中之week一样,分别用int作为数组的下标,这里让出三单极端简便的样式:

mood.js

export function mood(num) {
    var moodValue=["mood",""]
    if(num==null)
        num=0;
    return moodValue[num];
}

weather.js

export function weather(num) {
    var weatherValue=["wb_sunny",""]
    if(num==null)
        num=0;
    return weatherValue[num];
}

bookmark.js

export function bookmark(num) {
    var bookmarkValue=["bookmark_border","bookmark"]
    if(num==null)
        num=0;
    return bookmarkValue[num];
}

最终标签内之代码如下:

<mu-paper class="diaryitem" :zDepth="2" v-for="(item) in todos" >
    <mu-content-block>
        <mu-row gutter>
           <mu-col width="20">
            <div class="item_day">{{ item.createTime | getDay }}</div>
            <div class="item_week">{{ item.createTime | getWeek }}</div>
           </mu-col>
            <mu-col width="60">
                <div class="item_time">{{ item.createTime | getTime }}</div>
                <div class="item_title">{{ item.item }}</div>
                <div class="item_content">{{item.content}}</div>
            </mu-col>
            <mu-col width="25" style="text-align:right">
                <mu-icon :value=" item.mood | getMoodValue  " :size="16"/>
                <mu-icon :value=" item.weather | getWeatherValue  " :size="16"/>
                <mu-icon :value=" item.bookmark | getBookmarkValue  " :size="16"/>
            </mu-col>
        </mu-row>
    </mu-content-block>
</mu-paper>

js代码如下:

import { formatDate } from '../utils/date.js';
import { mood } from '../utils/mood.js';
import { weather } from '../utils/weather.js';
import { bookmark } from '../utils/bookmark.js';
export default {
    props:["todos"],
    filters: {
        getDay(time) {

             var date = new Date(time);
             console.log(date)
            return  date.getDate();
            //return  formatDate(time,"dd");
        },
        getWeek(time) {
            return  formatDate(time,"w");
        },
        getTime(time) {
            return  formatDate(time,"hh:mm");
        },
        getMoodValue(num){
            return mood(num);
        },
        getWeatherValue(num){
            return weather(num);
        },
        getBookmarkValue(num){
            return bookmark(num);
        }
    }
}

css代码略,请自行查看源码

这时候跑起,效果使图:

于当下底界面莱克,基本上符合原型的要求。

服务端数据

剩下的情节就是概括了,只要解决多少来自之问题不怕知晓了,我们在贴一下要求的数量格式:

indexTodos:[
    {
        month:0,              //月份
        default:1,            //正在显示的月份
        todos:[{
            createTime:new Date(),   //记录时间
            item:'',                 //标题
            content:'',              //内容
            weather:0,               //天气
            mood:0,                  //心情
            bookmark:0,              //标记
            groupid:0,               //所属组
        }]
    }
]

而且,还用一个itemnumber,所以回来劳动端的java代码,一步一步之就这api效率。

第一,为了与原来的代码区分,新创一个ApiTodoController控制器,里边新增一个action,apiIndex,这么些action除了token外,还待一个月作为参数,这些啊特别爱领悟。然后我们得按照月查询todo列表,在前头还涉及过,由于分六只组,需要安装一个默认组,首页展现默认组的todo,所以,服务层的法门名也不怕出去了,getTodosByDefaultGroup,参数有少单,用户Id(由token获取)和月(参数传递)。

实际上依照服务层的格局名,他的伪代码就都出去了,按照的《代码大全里》的法子,用声明注释写出来:

  • 因用户id查询这用户的默认记录组
  • 询问这组是月的具有记录

注简单,代码当然为便大概了:

public List<Todo> getTodoByDefaultGroup(int userId,int month) {
    TodoGroup todoGroup=todoGroupRepository.findByIsDefaultAndUserId(1,userId);
    DateBetween between=getDate(month);
    List<Todo>  todos= todoRepository.getByGroupIdAndCreateTimeBetween(todoGroup.getId(),between.getFirstDate(),between.getEndDate());
    return todos;
}

repository层内只有方法名从未方法体,所以查看调用就可知顾全体内容,不在讲述。

DateBetween类从名字就能够看出来,表示一个日子区间,具体到此代码中,表示的凡者月之1如泣如诉到是月的最终一龙,即31哀号(五月份),他的代码如下:

class DateBetween{
    private Date firstDate;
    private Date endDate;
    //get set
}

getDate就是得参数月的前奏与终止日期,代码如下:

private DateBetween getDate( int month ){
    DateBetween between=new DateBetween();
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
    Calendar firstCalender =  Calendar.getInstance();
    // 获取前月的第一天
    firstCalender = Calendar.getInstance();
    firstCalender.add(Calendar.MONTH, 0);
    firstCalender.set(Calendar.DAY_OF_MONTH, 1);
    between.setFirstDate(firstCalender.getTime());
    // 获取前月的最后一天
    Calendar endCalender =   Calendar.getInstance();
    endCalender.add(Calendar.MONTH, 1);
    endCalender.set(Calendar.DAY_OF_MONTH, 0);
    between.setEndDate(endCalender.getTime());
    return  between;
}

诚如有些啰嗦,先这样回头再逐渐重构吧,这些法子惟有这类用,是private的。

组装json##

接通下回去Controller,这里没什么好说的,jackson仓库能一向将Map和类转成为Json对象,所以一直把前端需要之多少经过map组装起就吓了,直接贴代码:

@RequestMapping(value = "/api/index",method = RequestMethod.POST)
public Object apiIndex(HttpServletRequest request,@RequestBody Map map){
    //获取首页数据
    String userId=request.getAttribute("tokenId").toString();
    Integer month=Integer.parseInt( map.get("month").toString());
    List<Map<String,Object>> items=new ArrayList<Map<String,Object>>();
    for (int i=0;i<1;i++) {
        List<Todo> todos = todoService.getTodoByDefaultGroup(Integer.parseInt(userId),month);
        //数据结构扩充接口
        Map<String, Object> data = new HashMap<String, Object>();
        data.put("month",month);
        data.put("todos",todos);
        data.put("default",1);
        items.add(data);
    }
    Map<String,Object> resutl=new HashMap<String,Object>();
    resutl.put("items",items);
    resutl.put("itemnumber",items.size());
    return result(resutl);
}

瞩目是for循环,现在就走相同软,这是为将来优化功效,两回性再次回到多单月要留给的代码,现在就算一向当其是一个梯次结构就可.

顶最近停止的代码:

前端vue
后端java

谢谢阅览

相关文章

网站地图xml地图