用vue写todolist

样式是从SUI Mobile中下载获得

html部分

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <link rel="stylesheet" href="https://g.alicdn.com/msui/sm/0.6.2/css/sm.min.css">
    <link rel="stylesheet" href="./css/index.css">
</head>

<body>
    <div id="app">
        <!-- 这个结构就叫做sui布局外壳  layout -->
        <div class="page-group">
            <div class="page page-current todolist_page">
                <!-- 你的html代码 -->
                <Tab @change-input-flag="changeInputFlag"></Tab>
                <input @keyup.13="addItem" class="todolist_input" v-show="inputFlag" type="text" v-model="inputVal">
                <Wrapper :todos="newTodos" @changeflag="changeFlag" @check="check"></Wrapper>
                <mask-comp v-show="maskFlag" @click.native="closeMask" @remove="remove" :active-index="activeIndex"></mask-comp>
                <tab-bar @changetype="changeType" :tabbars="tabbars" :type="type"></tab-bar>
            </div>
        </div>
    </div>

    <template id="head">
    <div>
        <header class="bar bar-nav">
          <a class="icon icon-left pull-left"></a>
          <a class="icon icon-edit pull-right" @click = "changeInputFlag"></a>
          <h1 class="title"> todolist </h1>
        </header>
    </div>
  </template>

    <template id="content">
    <div class="todolist_content">

        <div class="card"
          v-for = "(item,index) in todos"
          :key = "item.id"
        >
          <div class="card-content">
            <div class="card-content-inner">
              <p> {{ item.task }} </p>
              <div class="todolist_btn_box pull-right">
                <button class="button button-success"
                  :class = "{'button-fill': item.flag }"
                  @click = "changeflag( index )"
                >
                  <i class="icon icon-check">  </i>
                </button>
                <button class="button button-danger"
                  @click = "removeItem( index )"
                >
                  <i class="icon icon-remove">  </i>
                </button>
              </div>
            </div>
          </div>
        </div>

    </div>
  </template>


    <template id="tabbar">
    <div>
      <footer>
        <ul class="todolist_list">
          <li class="circle "
            v-for = 'item in tabbars'
            :key = "item.id"
            :class = "['circle-' + item.class_name, type === item.text && 'circle-fill' ]"
            @click = "change( item.text )"
          >
            {{ item.text }}
          </li>
        </ul>
      </footer>
    </div>
  </template>


    <template id="mask">
    <div class="mask-box">
      <div class="mask-bg"></div>
      <div class="mask-content">
        <p> 您确定要离开吗? </p>
        <button 
          class="button button-warning button-fill pull-right"
          @click = "removeItem( activeIndex )"
        > 确定 </button>
      </div>
    </div>
  </template>

</body>
<script src="./lib/vue.js"></script>
<script src="./js/index.js"></script>

</html>

js部分

Vue.component('Tab',{
  template: '#head',
  methods: {
    changeInputFlag () {
      this.$emit('change-input-flag')
    }
  }
})

Vue.component('Wrapper',{
  template: '#content',
  props: ['todos'],
  methods: {
    changeflag ( index ) {
      this.$emit('changeflag',index)
    },
    removeItem ( index ) {
      this.$emit( 'check',index )
    }
  }
})


Vue.component('TabBar',{
  template: '#tabbar',
  props: ['tabbars','type'],
  methods: {
    change ( val ) {
      this.$emit('changetype', val )
    }
  }
})

Vue.component('MaskComp',{
  template: '#mask',
  methods: {
    removeItem ( index ) {
      this.$emit('remove',index)
    }
  },
  props: ['activeIndex'] // background-color backgroundColor
})

new Vue({
  el: '#app',
  data: {
    todos: [
      {
        id: 1,
        task: '任务一',
        flag: true
      },
      {
        id: 2,
        task: '任务二',
        flag: true
      }
    ],
    tabbars: [
      {
        id: 1,
        text: 'A',
        class_name: 'all'
      },
      {
        id: 2,
        text: 'F',
        class_name: 'finish'
      },
      {
        id: 3,
        text: 'U',
        class_name: 'unfinish'
      }
    ],
    type: 'A',
    inputFlag: false,
    inputVal: '',
    maskFlag: false,
    activeIndex: 0// 它是用来保存check后的index值,用于删除
  },
  methods: {
    changeType ( val ) {
      this.type = val
    },
    changeFlag ( index ) {
      this.todos[index].flag = !this.todos[index].flag
    },
    check ( index ) {
      //在点击删除前,我们先判断一下当前这个数据的flag是true,还是false,如果是true,直接删除,如果是false,那么出Mask
      if ( this.todos[ index ].flag  ) {
        //直接删除
        this.remove( index )
      } else {
        // 不能直接删除,弹出遮罩层 Mask
        this.activeIndex = index 
        this.maskFlag = true
      } 
    },
    remove ( index ) {
      // pop  shift splice 
      this.todos.splice( index, 1 )
    },
    changeInputFlag () {
      console.log('fdsafasd')
      this.inputFlag = !this.inputFlag
    },
    addItem () {
      this.todos.push({
        id: this.todos.length + 1, // 安全性要低
        task: this.inputVal,
        flag: true
      })
      this.inputVal = ''
      this.inputFlag = false
    },
    closeMask () {
      this.maskFlag = false
    },
  },
  computed: {
    // 1. 有逻辑处理  2. 类似全局变量一样使用
    newTodos () {
      switch ( this.type ) {
        case "A":
          return this.todos
          break;
        case "F": 
          //表示已经完成的任务    从一个数组中将flag = true 挑选出来
          return this.todos.filter( item => item.flag )
          break;
      
        case "U": 
          //表示已经完成的任务    从一个数组中将flag = true 挑选出来
          return this.todos.filter( item => !item.flag )
          break;
      
        default:
          break;
      }
    }
  }
})

下面是css样式

*{
  list-style: none;
  margin: 0;
  padding: 0;
}
html,body,#app{
  height: 100%;
}
.todolist_content{
  padding-top: 40px;
  flex: 1;
}
.todolist_btn_box{
  display: flex;
}
.todolist_btn_box button{
  margin-right: 10px;
}
.card-content-inner{
  overflow: hidden;
}

.todolist_input{
  margin-top: 50px;
  padding: 8px 10px;
}

.todolist_page{
  display: flex!important;
  flex-direction: column;
}

/* ----------------  使用OOCSS规则打造底部栏  --------------- */
.todolist_list{
  display: flex;
  justify-content: space-around;
}
.circle{
  /* 公共样式 */
  width: 80px;
  height: 80px;
  border: 1px solid #ccc;
  border-radius: 50%;
  text-align: center;
  line-height: 80px;
}

.circle.circle-all{
  border-color: green;
  color: green;
}
.circle.circle-all.circle-fill{
  background: green;
  color: white;
}


.circle.circle-finish{
  border-color: blueviolet;
  color: blueviolet;
}
.circle.circle-finish.circle-fill{
  background: blueviolet;
  color: white;
}


.circle.circle-unfinish{
  border-color: orange;
  color: orange;
}
.circle.circle-unfinish.circle-fill{
  background: orange;
  color: white;
}

/* -----------------------  mask层 布局 -------------------------------- */

.mask-box{
  position: fixed;
  left: 0;
  top:0;
  z-index: 99;
  
  width: 100%;height: 100%;

}
.mask-bg{
  position: absolute;
  left: 0;top: 0;
  background: rgba( 0,0,0,.5 );

  width: 100%;height: 100%;
}

.mask-content{
  position: absolute;
  left: 0; right: 0;
  top: 0; bottom: 0;

  margin: auto;

  width: 80%; height: 100px;

  background: white;

  border-radius: 10px;
  padding: 15px;

  overflow: hidden;
}
.mask-content p{
  margin: 0;
  margin-bottom: 8px;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值