清除输入框自动保存上次的记录值

本文介绍如何在网页表单中禁用浏览器的自动填充功能,通过设置input元素的autocomplete属性为off,可以避免输入框显示历史输入值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

当我们鼠标点击输入框会自动显示之前输入值 

如果我们不想显示之前的值,可以给input输入框添加  autocomplete="off" 属性

这次再点击输入框隐藏了

以下頁面代碼如下,當點擊父組件切換按鈕時,子組件的頁面仍能保持原來的頁面狀態,請以完整代碼展示: 父組件代碼(不更改): <template> <div class="app-container"> <!-- 顶部固定菜单 --> <div class="fixed-menu"> <!-- “医仙”按钮(当前页跳转) --> <button class="external-link" @click="openExternalLink"> 醫仙 </button> <!-- 动态组件切换按钮 --> <button @click="setCurrentView('mrviewer')" :class="{ active: currentView === 'mrviewer' }"> 醫案閱讀器 </button> <button @click="setCurrentView('mreditor')" :class="{ active: currentView === 'mreditor' }"> 醫案編輯器 </button> <button @click="setCurrentView('dncrud')" :class="{ active: currentView === 'dncrud' }"> 病態編輯器 </button> </div> <!-- 动态组件展示区域 --> <div class="content-wrapper"> <!-- 使用 keep-alive 缓存组件状态 --> <keep-alive :include="cachedComponents"> <component :is="currentViewComponent" :key="currentView" /> </keep-alive> </div> </div> </template> <script> import mrviewer from "./components/mrviewer.vue"; import mreditor from "./components/mreditor.vue"; import dncrud from "./components/dncrud.vue"; // 导入病态编辑器组件 export default { components: { mrviewer, mreditor, dncrud }, // 注册组件 data() { return { currentView: "mrviewer", // 需要缓存的组件列表 cachedComponents: ["mrviewer", "mreditor", "dncrud"] }; }, computed: { currentViewComponent() { return this.currentView; } }, methods: { // 设置当前视图并保存状态 setCurrentView(viewName) { // 保存当前组件状态(如果需要) if (this.currentViewComponent && this.currentViewComponent.beforeLeave) { this.currentViewComponent.beforeLeave(); } // 切换到新视图 this.currentView = viewName; // 保存当前视图到本地存储 localStorage.setItem("lastActiveView", viewName); }, openExternalLink() { // 保存当前状态(如果需要) if (this.currentViewComponent && this.currentViewComponent.beforeLeave) { this.currentViewComponent.beforeLeave(); } // 跳转到外部链接 window.location.href = "http://localhost:65358/"; }, // 恢复上次活动视图 restoreLastView() { const lastView = localStorage.getItem("lastActiveView"); if (lastView && this.cachedComponents.includes(lastView)) { this.currentView = lastView; } } }, mounted() { // 组件挂载时恢复上次视图 this.restoreLastView(); } }; </script> <style scoped> .app-container { display: flex; flex-direction: column; min-height: 100vh; } .fixed-menu { position: fixed; top: 0; left: 0; width: 100%; background: #2c3e50; padding: 10px; display: flex; gap: 10px; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); z-index: 100; } .fixed-menu button { padding: 8px 16px; border: none; border-radius: 4px; background: #3498db; color: white; cursor: pointer; transition: background 0.3s; } .fixed-menu button:hover { background: #2980b9; } .fixed-menu button.active { background: #e74c3c; font-weight: bold; } .fixed-menu button.external-link { background: #2ecc71; /* 绿色背景区分 */ } .fixed-menu button.external-link:hover { background: #27ae60; } .content-wrapper { flex: 1; margin-top: 60px; /* 增加顶部间距避免内容被顶部菜单遮挡 */ padding: 20px; background: #f5f5f5; height: calc(100vh - 80px); /* 确保内容区域高度适配 */ overflow-y: auto; /* 添加滚动条 */ } </style> 子組件代碼: <template> <div class="container"> <!-- 控制面板 --> <div class="control-panel"> <button @click="fetchData" class="refresh-btn">刷新數據</button> <input v-model="searchQuery" placeholder="搜索..." class="search-input" /> <div class="pagination-controls"> <span>每頁顯示:</span> <select v-model.number="pageSize" class="page-size-select"> <option value="1">1筆</option> <option value="4">4筆</option> <option value="10">10筆</option> </select> <button @click="prevPage" :disabled="currentPage === 1">上一页</button> <span>第</span> <!-- 实时跳转的页码输入框 --> <input type="number" v-model.number="inputPage" min="1" :max="totalPages" class="page-input" @input="handlePageInput"> <span>頁 / 共 {{ totalPages }} 頁</span> <button @click="nextPage" :disabled="currentPage === totalPages">下一頁</button> <span>醫案閱讀器</span> </div> </div> <!-- 主内容区域 --> <div class="content-area"> <!-- 水平排列的数据展示 --> <div class="horizontal-records" v-if="filteredData.length > 0"> <div v-for="(item, index) in paginatedData" :key="item.id" class="record-card"> <div class="record-header"> <h3>醫案 #{{ (currentPage - 1) * pageSize + index + 1 }}</h3> </div> <div class="record-body"> <!-- 使用v-for遍历处理后的字段对象 --> <div v-for="(value, key) in processFieldNames(item)" :key="key" class="record-field"> <div class="field-name">{{ key }}:</div> <div class="field-value"> <!-- 处理dntag字段的特殊显示 --> <div v-if="key === '病態名稱' && Array.isArray(value)" class="dntag-value"> {{ formatDntagValue(value) }} </div> <!-- 其他字段的正常显示 --> <div v-else-if="Array.isArray(value)" class="array-value"> <span v-for="(subItem, subIndex) in value" :key="subIndex"> <span v-html="formatValue(subItem, key)"></span><span v-if="subIndex < value.length - 1">;</span> </span> </div> <div v-else v-html="formatValue(value, key)"></div> </div> </div> </div> </div> </div> <div v-else class="no-data"> 沒有找到匹配的數據 </div> </div> </div> </template> <script> export default { data() { return { api1Data: [], api2Data: [], mergedData: [], currentPage: 1, pageSize: 1, searchQuery: '', sortKey: '', sortOrders: {}, inputPage: 1, // 页码输入框绑定的 // 字段名称映射表 fieldNames: { 'mrcase': '醫案全文', 'mrname': '醫案命名', 'mrposter': '醫案提交者', 'mrlasttime': '最後編輯時間', 'mreditnumber': '編輯次數', 'mrreadnumber': '閱讀次數', 'mrpriority': '重要性', 'dntag': '病態名稱' }, inputTimeout: null, // 用于输入防抖 dnNames: [] // 存储所有病态名称 }; }, computed: { filteredData() { const query = this.searchQuery.trim(); // 判斷是否為數字(即搜尋 ID) if (query && /^\d+$/.test(query)) { const idToSearch = parseInt(query, 10); return this.mergedData.filter(item => item.id === idToSearch); } // 一般搜索邏輯 if (!query) return this.mergedData; const lowerQuery = query.toLowerCase(); return this.mergedData.filter(item => { return Object.values(item).some(value => { if (value === null || value === undefined) return false; // 处理数组类型的 if (Array.isArray(value)) { return value.some(subValue => { if (typeof subValue === 'object' && subValue !== null) { return JSON.stringify(subValue).toLowerCase().includes(lowerQuery); } return String(subValue).toLowerCase().includes(lowerQuery); }); } // 处理对象类型的 if (typeof value === 'object' && value !== null) { return JSON.stringify(value).toLowerCase().includes(lowerQuery); } return String(value).toLowerCase().includes(lowerQuery); }); }); }, sortedData() { if (!this.sortKey) return this.filteredData; const order = this.sortOrders[this.sortKey] || 1; return [...this.filteredData].sort((a, b) => { const getValue = (obj) => { const val = obj[this.sortKey]; if (Array.isArray(val)) { return JSON.stringify(val); } return val; }; const aValue = getValue(a); const bValue = getValue(b); if (aValue === bValue) return 0; return aValue > bValue ? order : -order; }); }, paginatedData() { const start = (this.currentPage - 1) * Number(this.pageSize); const end = start + Number(this.pageSize); return this.sortedData.slice(start, end); }, totalPages() { return Math.ceil(this.filteredData.length / this.pageSize) || 1; } }, watch: { // 监控分页大小变化 pageSize() { // 重置到第一页 this.currentPage = 1; this.inputPage = 1; // 同步输入框 }, // 监控当前页码变化 currentPage(newVal) { // 同步输入框 this.inputPage = newVal; }, // 监控过滤数据变化 filteredData() { // 确保当前页码有效 if (this.currentPage > this.totalPages) { this.currentPage = Math.max(1, this.totalPages); } // 同步输入框 this.inputPage = this.currentPage; } }, methods: { async fetchData() { try { const api1Response = await fetch("MRInfo/?format=json"); this.api1Data = await api1Response.json(); const api2Response = await fetch("DNTag/?format=json"); this.api2Data = await api2Response.json(); // 提取所有dnname this.dnNames = this.api2Data.map(item => item.dnname).filter(name => name && name.trim()); // 按长度降序排序(确保长字符串优先匹配) this.dnNames.sort((a, b) => b.length - a.length); this.mergeData(); this.currentPage = 1; this.inputPage = 1; // 重置输入框 } catch (error) { console.error("獲取數據失敗:", error); alert("數據加載失敗,請稍後重試"); } }, mergeData() { this.mergedData = this.api1Data.map((item) => { const newItem = { ...item }; if (newItem.dntag && Array.isArray(newItem.dntag)) { newItem.dntag = newItem.dntag.map((tagId) => { const matchedItem = this.api2Data.find( (api2Item) => api2Item.id === tagId ); return matchedItem || { id: tagId, dnname: "未找到匹配的數據" }; }); } return newItem; }); this.sortOrders = {}; if (this.mergedData.length > 0) { Object.keys(this.mergedData[0]).forEach(key => { this.sortOrders[key] = 1; }); } }, // 处理字段名称映射 processFieldNames(item) { const result = {}; for (const key in item) { // 使用映射表转换字段名,如果没有映射则使用原字段名 const newKey = this.fieldNames[key] || key; result[newKey] = item[key]; } return result; }, // 高亮匹配文本的方法 highlightMatches(text) { if (!text || typeof text !== 'string' || this.dnNames.length === 0) { return text; } // 创建正则表达式(转义特殊字符) const pattern = new RegExp( this.dnNames .map(name => name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')) .join('|'), 'gi' ); // 替换匹配文本 return text.replace(pattern, match => `<span style="color: rgb(212, 107, 8); font-weight: bold;">${match}</span>` ); }, formatValue(value, fieldName) { if (value === null || value === undefined) return ''; // 医案全文字段特殊处理 if (fieldName === '醫案全文' && typeof value === 'string') { return this.highlightMatches(value); } // 其他字段保持原逻辑 if (typeof value === 'string' && value.startsWith('http')) { return `<a href="${value}" target="_blank">${value}</a>`; } return value; }, // 专门处理dntag字段的显示格式 formatDntagValue(dntagArray) { return dntagArray.map(tagObj => { // 只显示name属性,隐藏id等其他属性 return tagObj.dnname || tagObj.name || '未命名標籤'; }).join(';'); // 使用大写分号分隔 }, sortBy(key) { // 需要从中文名称映射回原始字段名进行排序 const originalKey = Object.keys(this.fieldNames).find( origKey => this.fieldNames[origKey] === key ) || key; this.sortKey = originalKey; this.sortOrders[originalKey] = this.sortOrders[originalKey] * -1; }, prevPage() { if (this.currentPage > 1) { this.currentPage--; } }, nextPage() { if (this.currentPage < this.totalPages) { this.currentPage++; } }, // 实时处理页码输入 handlePageInput() { // 清除之前的定时器 clearTimeout(this.inputTimeout); // 设置新的定时器(防抖处理) this.inputTimeout = setTimeout(() => { this.goToPage(); }, 300); // 300毫秒后执行 }, // 跳转到指定页码 goToPage() { // 处理空情况 if (this.inputPage === null || this.inputPage === undefined || this.inputPage === '') { this.inputPage = this.currentPage; return; } // 转换为整数 const page = parseInt(this.inputPage); // 处理非数字情况 if (isNaN(page)) { this.inputPage = this.currentPage; return; } // 确保页码在有效范围内 if (page < 1) { this.currentPage = 1; } else if (page > this.totalPages) { this.currentPage = this.totalPages; } else { this.currentPage = page; } // 同步输入框显示 this.inputPage = this.currentPage; } }, mounted() { this.fetchData(); } }; </script> <style scoped> .container { max-width: 1200px; margin: 0px; padding: 0px; } .control-panel { margin-bottom: 0px; display: flex; flex-wrap: wrap; gap: 10px; justify-content: flex-end; align-items: center; position: fixed; bottom: 0; left: 0; width: 100%; background-color: #ffd800ff; z-index: 999; padding: 10px 20px; box-sizing: border-box; } .content-area { position: fixed; top: 56px; bottom: 45px; /* 位于底部按钮上方 */ left: 0; width: 100%; background: white; padding: 1px; z-index: 100; overflow-y: auto; } .refresh-btn { padding: 4px; background-color: #4CAF50; color: white; border: none; border-radius: 4px; cursor: pointer; } .refresh-btn:hover { background-color: #45a049; } .search-input { padding: 8px; border: 1px solid #ddd; border-radius: 4px; flex-grow: 1; max-width: 300px; } .pagination-controls { display: flex; align-items: center; gap: 5px; } .page-size-select { padding: 4px; border-radius: 4px; width: 70px; } /* 页码输入框样式 */ .page-input { width: 50px; padding: 4px; border: 1px solid #ddd; border-radius: 4px; text-align: center; } /* 水平记录样式 */ .horizontal-records { display: flex; flex-direction: column; gap: 20px; } .record-card { border: 1px solid #ddd; border-radius: 4px; overflow: hidden; box-shadow: 0 2px 4px rgba(0,0,0,0.1); } .record-header { padding: 12px 16px; background-color: #f5f5f5; border-bottom: 1px solid #ddd; } .record-header h3 { margin: 0; font-size: 1.1em; } .record-body { padding: 16px; } .record-field { display: flex; margin-bottom: 12px; line-height: 1.5; } .record-field:last-child { margin-bottom: 0; } .field-name { font-weight: bold; min-width: 120px; color: #555; } .field-value { flex-grow: 1; display: flex; flex-wrap: wrap; gap: 8px; } .dntag-value { display: flex; flex-wrap: wrap; gap: 8px; } .array-value { display: flex; flex-wrap: wrap; gap: 8px; } .no-data { padding: 20px; text-align: center; color: #666; font-style: italic; } button:disabled { opacity: 0.5; cursor: not-allowed; } </style>
07-17
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值