uniapp学习3,简易记事本

html 复制代码
<template>
  <view class="wrap">
    <!-- 顶部 -->
    <view class="header">
      <text class="title">简易记事本</text>
    </view>

    <!-- 搜索 -->
    <view class="search-box">
      <input v-model="keyword" placeholder="搜索笔记..." @input="doSearch" />
    </view>

    <!-- 列表 -->
    <view class="list">
      <view class="item" v-for="(item, idx) in showList" :key="idx">
        <view class="content" @click="toEdit(item)">
          <text class="txt">{{ item.title }}</text>
          <text class="time">{{ item.time }}</text>
        </view>
        <view class="del" @click="delNote(idx)">删除</view>
      </view>

      <view class="empty" v-if="showList.length === 0">
        暂无笔记,点击右下角新增
      </view>
    </view>

    <!-- 悬浮新增按钮 -->
    <view class="add-float-btn" @click="toEdit">
      <text class="add-icon">+</text>
    </view>

    <!-- 编辑弹窗 -->
    <view class="modal" v-show="showModal">
      <view class="card">
        <view class="modal-head">
          <text>{{ currentItem.idx > -1 ? '编辑笔记' : '新增笔记' }}</text>
          <view @click="closeModal">×</view>
        </view>
        <textarea v-model="form.title" placeholder="请输入内容" class="area"></textarea>
        <view class="btns">
          <button @click="closeModal">取消</button>
          <button @click="saveNote">保存</button>
        </view>
      </view>
    </view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      noteList: [],
      showList: [],
      keyword: '',
      showModal: false,
      form: { title: '' },
      currentItem: { idx: -1 }
    }
  },
  onLoad() {
    this.getList()
  },
  methods: {
    // 读取本地
    getList() {
      let list = uni.getStorageSync('noteList') || []
      this.noteList = list
      this.showList = list
    },
    // 保存本地
    setList(list) {
      this.noteList = list
      this.showList = list
      uni.setStorageSync('noteList', list)
    },
    // 搜索
    doSearch() {
      let k = this.keyword.trim()
      if (!k) {
        this.showList = this.noteList
        return
      }
      this.showList = this.noteList.filter(item => {
        return item.title.includes(k)
      })
    },
    // 打开编辑
    toEdit(item) {
      if (item) {
        this.currentItem = item
        this.form.title = item.title
      } else {
        this.currentItem = { idx: -1 }
        this.form.title = ''
      }
      this.showModal = true
    },
    // 关闭
    closeModal() {
      this.showModal = false
      this.form.title = ''
    },
    // 保存
    saveNote() {
      let title = this.form.title.trim()
      if (!title) return uni.showToast({ title: '请输入内容', icon: 'none' })

      let time = new Date().toLocaleString()
      let list = JSON.parse(JSON.stringify(this.noteList))

      if (this.currentItem.idx > -1) {
        // 编辑
        list[this.currentItem.idx] = { title, time }
      } else {
        // 新增
        list.unshift({ title, time })
      }

      this.setList(list)
      this.closeModal()
      uni.showToast({ title: '保存成功' })
    },
    // 删除
    delNote(idx) {
      uni.showModal({
        title: '提示',
        content: '确定删除该笔记?',
        success: res => {
          if (res.confirm) {
            let list = JSON.parse(JSON.stringify(this.noteList))
            list.splice(idx, 1)
            this.setList(list)
            uni.showToast({ title: '删除成功' })
          }
        }
      })
    }
  }
}
</script>

<style scoped>
.wrap {
  padding: 20rpx;
  background: #f7f8fa;
  min-height: 100vh;
}
.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20rpx;
}
.title {
  font-size: 38rpx;
  font-weight: bold;
}
/* 悬浮圆形新增按钮 */
.add-float-btn {
  position: fixed;
  right: 40rpx;
  bottom: 40rpx;
  width: 100rpx;
  height: 100rpx;
  border-radius: 50%;
  background-color: #42b983;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 8rpx 16rpx rgba(66, 185, 131, 0.3);
  z-index: 99;
}

.add-icon {
  font-size: 50rpx;
  color: #fff;
  font-weight: bold;
  line-height: 1;
}
.search-box {
  background: #fff;
  border-radius: 12rpx;
  padding: 20rpx;
  margin-bottom: 20rpx;
}
.search-box input {
  font-size: 28rpx;
}
.list {
  background: #fff;
  border-radius: 12rpx;
  overflow: hidden;
}
.item {
  display: flex;
  padding: 30rpx;
  border-bottom: 1rpx solid #eee;
}
.content {
  flex: 1;
}
.txt {
  font-size: 30rpx;
  display: block;
  margin-bottom: 10rpx;
}
.time {
  font-size: 24rpx;
  color: #999;
}
.del {
  color: #ff4d4f;
  font-size: 26rpx;
  align-self: center;
  padding: 10rpx;
}
.empty {
  padding: 60rpx;
  text-align: center;
  color: #999;
}
.modal {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
}
.card {
  width: 80%;
  background: #fff;
  border-radius: 20rpx;
  overflow: hidden;
}
.modal-head {
  padding: 30rpx;
  display: flex;
  justify-content: space-between;
  font-size: 32rpx;
  border-bottom: 1rpx solid #eee;
}
.area {
  padding: 30rpx;
  min-height: 300rpx;
  font-size: 30rpx;
}
.btns {
  display: flex;
  padding: 20rpx;
  justify-content: flex-end;
  gap: 20rpx;
}
.btns button {
  padding: 15rpx 30rpx;
  border-radius: 10rpx;
  font-size: 28rpx;
}
.btns button:first-child {
  background: #f5f5f5;
}
.btns button:last-child {
  background: #42b983;
  color: #fff;
}
</style>
相关推荐
小弥儿9 小时前
GitHub今日热榜 | 2026-09-18:腾讯双项目上榜
学习·开源
知识分享小能手11 小时前
深度学习学习教程,从入门到精通,深度生成模型 —— 知识点详解与代码实现(20)
人工智能·深度学习·学习
m4Rk_12 小时前
【论文阅读】Agent 记忆机制(74):CompassMem——从相似度检索走向事件图上的记忆导航
论文阅读·人工智能·学习·开源·github
小李不想当小白12 小时前
DMA直接存储器存取(STM32标准库学习笔记)
笔记·stm32·单片机·嵌入式硬件·学习·分享
2601_9499506314 小时前
练题簿在线练题全流程:从资料导入到模拟考试与错题复盘
学习·考研·小程序·刷题·小程序推荐
别动我齐刘海14 小时前
ROS2 Jazzy + C++ 实战路线——基础学习2
c++·人工智能·vscode·python·学习·机器学习·机器人
水云桐程序员16 小时前
量子力学概论,量子力学概念总结
笔记·科技·学习·量子计算
白远山17 小时前
上海24小时自助健身房系统软件开发实战指南:从需求到部署
java·架构·uni-app·需求分析
三克的油18 小时前
java-学习1
java·开发语言·学习
j7~18 小时前
【C++微服务项目开发脚手架】(接口篇一)gflags + gtest + spdlog 接口学习笔记
c++·学习·gtest·项目开发·spdlog·gflags·c++项目微服务开发脚手架