一个简易的手机端todo

**vuex的操作**
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

import VuexPersist from "vuex-persist";

const vuexLocal = new VuexPersist({
    storage: window.sessionStorage,
})

export default new Vuex.Store({
    state: {
        list: [], //接收文本框的值
    },
    mutations: {
        //添加的操作
        addlist(state, name) {
            state.list.push(name);
        },
        // 改变值
        addchange(state, index) {
            console.log(state.list[index])
            let { checked } = state.list[index];
            if (checked == true) {
                state.list[index].numsb = 2;
            } else {
                state.list[index].numsb = 1;
            }
        },
        addname(state, index) {
            state.list[index].numsb = 3;
        },
        del(state, k) {
            state.list.splice(k, 1)
        },
        isedit(state, index) {
            state.list[index].isEdit = !state.list[index].isEdit
        }
    },
    actions: {

    },
    getters: {
        gnum(state) {
            let obj = {
                ondo: 0,
                done: 0,
                cancel: 0,
            };
            state.list.forEach(item => {
                switch (item.numsb) {
                    case 1:
                        obj.ondo++;
                        break;
                    case 2:
                        obj.done++;
                        break;
                    case 3:
                        obj.cancel++;
                        break;
                }
            });
            return obj;
        }
    },
    plugins: [vuexLocal.plugin],
})



**vue组件内的样式以及操作**

<template>
  <div>
    <!-- 头部区域 -->
    <van-nav-bar title="三个状态来回跳">
      <template #right>
        <van-icon size="25" color="#fff" name="like-o" @click="show = true" />
      </template>
    </van-nav-bar>
    <!-- 头部区域 -->
    <!-- 文本添加区域 -->
    <van-row>
      <van-col span="20">
        <van-field
          v-model="textlist"
          rows="2"
          autosize
          type="textarea"
          maxlength="50"
          placeholder="输入你想干的事"
          show-word-limit
        />
      </van-col>
      <van-col span="4">
        <van-button color="#7232dd" @click="addlist">添加</van-button>
      </van-col>
    </van-row>
    <!-- 文本添加区域 -->
    <!-- tab标签切换 -->
    <van-tabs v-model="numsb" type="card" @click="changeTab">
      <van-tab title="未完成" name="1" :badge="$store.getters.gnum.ondo">
      </van-tab>
      <van-tab title="已完成" name="2" :badge="$store.getters.gnum.done">
      </van-tab>
      <van-tab title="回收站" name="3" :badge="$store.getters.gnum.cancel">
      </van-tab>
    </van-tabs>
    <!-- tab标签切换 -->
    <!-- 内容显示区域 -->
    <!-- 操作state添加入list渲染到页面 -->
    <div v-for="(item, index) in $store.state.list" :key="index">
      <!-- 未完成 -->
      <van-row v-if="item.numsb == numsb">
        <van-col span="6">
          <van-checkbox
            v-model="item.checked"
            shape="square"
            @click="change(index)"
          ></van-checkbox>
        </van-col>
        <van-col span="14">
          <span @click="isedit(index)" v-if="item.isEdit == false">{{
            item.textlist
          }}</span>
          <input
            type="text"
            v-model="item.textlist"
            v-show="item.isEdit"
            @blur="isedit(index)"
            v-focus
          />
        </van-col>
        <van-col span="4">
          <van-button
            plain
            hairline
            type="primary"
            @click="addname(index)"
            v-if="item.numsb == 1"
            >标为已读</van-button
          >
          <div v-if="item.numsb == 2">{{ item.time | fromData }}</div>
          <van-button
            plain
            hairline
            type="primary"
            v-if="item.numsb == 3"
            @click="del(index)"
            >删除</van-button
          >
        </van-col>
      </van-row>
    </div>
    <!-- 内容显示区域 -->
    <!-- 遮罩层 -->
    <van-overlay :show="show" @click="show = false">
      <div class="wrapper">
        <div class="block" />
      </div>
    </van-overlay>
    <!-- 遮罩层 -->
  </div>
</template>

<script>
import { mapMutations } from "vuex";
export default {
  // 组件名称
  name: "demo",
  // 组件参数 接收来自父组件的数据
  props: [],
  // 局部注册的组件
  components: {},

  directives: {
    focus: {
      inserted(el, bi) {
        el.focus();
      },
    },
  },

  // 组件状态值
  data() {
    return {
      textlist: "", //文本框的值
      numsb: 1,
      show: false,
      value: "",
    };
  },
  // 计算属性
  computed: {},
  // 侦听器
  watch: {},
  // 组件方法
  methods: {
    ...mapMutations(["addname", "del", "isedit"]),
    addlist() {
      let obj = {
        textlist: this.textlist,
        checked: false, //复选框是否选中
        numsb: this.numsb, //切换的状态
        isEdit: false, //
        time: new Date().getTime(), //当前时间戳
      };
      this.$store.commit("addlist", obj);
      this.$toast.success(
        "????????"
      );
      this.textlist = "";
    },
    // 头部切换
    changeTab(name, title) {
      console.log(name, title);
    },
    change(index) {
      console.log(index);
      this.$store.commit("addchange", index);
    },
  },
  // 过滤器
  filters: {
    fromData(val) {
      // 年也日
      let year = new Date(val).getFullYear(); //年
      let month = new Date(val).getMonth() + 1; //月
      let ydata = new Date(val).getDate(); //日
      return `${year}-${month.toString()}-${ydata.toString()}`;
    },
  },

};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<!--使用了scoped属性之后,父组件的style样式将不会渗透到子组件中,-->
<!--然而子组件的根节点元素会同时被设置了scoped的父css样式和设置了scoped的子css样式影响,-->
<!--这么设计的目的是父组件可以对子组件根元素进行布局。-->
<style lang="scss" scoped>
.van-nav-bar {
  background: rgb(109, 243, 51);
}
.van-row {
  margin-top: 10px;
  line-height: 50px;
}
.van-checkbox {
  margin-top: 10px;
  margin-left: 5px;
}
.wrapper {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
}

.block {
  width: 120px;
  height: 120px;
  background-color: #fff;
}
</style>
前端页面: ``` <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>手机号验证登录</title> </head> <body> <h1>手机号验证登录</h1> <form> <label for="phone">手机号:</label> <input type="text" id="phone" name="phone"><br><br> <label for="code">验证码:</label> <input type="text" id="code" name="code"><br><br> <button id="sendCodeBtn">发送验证码</button> <button id="loginBtn">登录</button> </form> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <script> $(function() { // 发送验证码按钮点击事件 $('#sendCodeBtn').on('click', function() { var phone = $('#phone').val(); if (phone === '') { alert('请输入手机号'); return; } $.ajax({ url: '/sendCode', type: 'POST', data: {phone: phone}, success: function(data) { if (data.code === 200) { alert('验证码已发送,请注意查收'); } else { alert('发送失败,请稍后重试'); } } }); }); // 登录按钮点击事件 $('#loginBtn').on('click', function() { var phone = $('#phone').val(); var code = $('#code').val(); if (phone === '' || code === '') { alert('请输入手机号和验证码'); return; } $.ajax({ url: '/login', type: 'POST', data: {phone: phone, code: code}, success: function(data) { if (data.code === 200) { alert('登录成功'); } else { alert('登录失败,请检查手机号和验证码是否正确'); } } }); }); }); </script> </body> </html> ``` 后端代码: ``` const express = require('express'); const bodyParser = require('body-parser'); const app = express(); app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json()); // 发送验证码接口 app.post('/sendCode', function(req, res) { var phone = req.body.phone; // TODO:调用第三方短信平台发送验证码 // 返回结果 res.json({code: 200, message: '验证码已发送'}); }); // 登录接口 app.post('/login', function(req, res) { var phone = req.body.phone; var code = req.body.code; // TODO:验证手机号和验证码是否匹配 // 返回结果 if (match) { res.json({code: 200, message: '登录成功'}); } else { res.json({code: 400, message: '手机号或验证码不正确'}); } }); app.listen(3000, function() { console.log('App listening on port 3000'); }); ``` 说明: 1. 前端页面使用表单的方式提交手机号和验证码。 2. 发送验证码按钮点击事件会向后端发送一个 POST 请求,传递手机号。 3. 后端接收到请求后,调用第三方短信平台发送验证码,并返回结果。 4. 登录按钮点击事件会向后端发送一个 POST 请求,传递手机号和验证码。 5. 后端接收到请求后,验证手机号和验证码是否匹配,并返回结果。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值