博客 (126)

在 Vue 中,当你将一个布尔对象双向绑定到 radio 输入上时,确保 radio 的 value 属性仍然保持布尔类型是很重要的。如果 value 属性是字符串,那么 Vue 会将其解释为字符串而不是布尔值。以下是一个示例,演示如何正确地将布尔对象双向绑定到 radio 按钮,并确保 value 属性保持布尔类型:

<template>
  <div>
    <input type="radio" v-model="myBoolean" :value="true" /> True
    <input type="radio" v-model="myBoolean" :value="false" /> False
    <p>myBoolean: {{ myBoolean }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      myBoolean: false, // 布尔对象
    };
  },
};
</script>

在这个示例中,我们使用了 v-model 指令将 myBoolean 属性与两个 radio 按钮进行了双向绑定。通过将 value 属性设置为 true 和 false,我们确保了 myBoolean 属性保持布尔类型。

这样,当用户选择其中一个 radio 按钮时,myBoolean 属性将保持布尔值而不是字符串。确保 value 属性的类型与要绑定的数据类型匹配,以确保绑定的数据类型保持一致。

同样的问题出现在 select 上也是一样:

<select v-model="cat.colorId" required>
    <option :value="null">不选择</option>
    <option v-for="color in colors" :value="color.id">{{color.name}}</option>
</select>


xoyozo 2 年前
1,760

Windows 11 家庭版在安装时不能直接选择离线帐户,只能使用微软帐户登录,无论有没有连网。

没有微软帐户的朋友也不用担心,可以注册一个。

实在不想注册的,也可以选择创建新帐号,名称生日随便填,在验证这步选择跳过即可。后面会让你设置一个 PIN 码,相当于登录密码。安装完成后,在设置中创建本地帐户。

xoyozo 2 年前
2,150

不知道从哪个版本的 Chrome 或 Edge 开始,我们无法通过 ctrl+v 快捷键将时间格式的字符串粘贴到 type 为 date 的 input 框中,我们想办法用 JS 来实现。


方式一、监听 paste 事件:

const input = document.querySelector('input[type="date"]');
input.addEventListener('paste', (event) => {
    input.value = event.clipboardData.getData('text');
});

这段代码实现了从页面获取这个 input 元素,监听它的 paste 事件,然后将粘贴板的文本内容赋值给 input。

经测试,当焦点在“年”的位置时可以粘贴成功,但焦点在“月”或“日”上不会触发 paste 事件。


方式二、监听 keydown 事件:

const input = document.querySelector('input[type="date"]');
input.addEventListener('keydown', (event) => {
    if ((navigator.platform.match("Mac") ? event.metaKey : event.ctrlKey) && event.key === 'v') {
        event.preventDefault();
        var clipboardData = (event.clipboardData || event.originalEvent.clipboardData);
        input.value = clipboardData.getData('text');
    }
});

测试发现报错误:

Uncaught TypeError: Cannot read properties of undefined (reading 'getData')

Uncaught TypeError: Cannot read properties of undefined (reading 'clipboardData')

看来 event 中没有 clipboardData 对象,改为从 window.navigator 获取:

const input = document.querySelector('input[type="date"]');
input.addEventListener('keydown', (event) => {
    if ((navigator.platform.match("Mac") ? event.metaKey : event.ctrlKey) && event.key === 'v') {
        event.preventDefault();
        window.navigator.clipboard.readText().then(text => {
            input.value = text;
        });
    }
});

缺点是需要用户授权:

image.png

仅第一次需要授权,如果用户拒绝,那么以后就默认拒绝了。


以上两种方式各有优缺点,选择一种适合你的方案就行。接下来继续完善。


兼容更多时间格式,并调整时区

<input type="date" /> 默认的日期格式是 yyyy-MM-dd,如果要兼容 yyyy-M-d 等格式,那么:

const parsedDate = new Date(text);
if (!isNaN(parsedDate.getTime())) {
    input.value = parsedDate.toLocaleDateString('en-GB', { year: 'numeric', month: '2-digit', day: '2-digit' }).split('/').reverse().join('-');
}

以 text 为“2023-4-20”举例,先转为 Date,如果成功,再转为英国时间格式“20-04-2023”,以“/”分隔,逆序,再以“-”连接,就变成了“2023-04-20”。

当然如果希望支持中文的年月日,可以先用正则表达式替换一下:

text = text.replace(/\s*(\d{4})\s*年\s*(\d{1,2})\s*月\s*(\d{1,2})\s*日\s*/, "$1-$2-$3");


处理页面上的所有 <input type="date" />

const inputs = document.querySelectorAll('input[type="date"]');
inputs.forEach((input) => {
    input.addEventListener(...);
});


封装为独立域

避免全局变量污染,使用 IIFE 函数表达式:

(function() {
  // 将代码放在这里
})();

或者封装为函数,在 jQuery 的 ready 中,或 Vue 的 mounted 中调用。


在 Vue 中使用

如果将粘贴板的值直接赋值到 input.value,在 Vue 中是不能同步更新 v-model 绑定的变量的,所以需要直接赋值给变量:

<div id="app">
    <input type="date" v-model="a" data-model="a" v-on:paste="fn_pasteToDateInput" />
    {{a}}
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
    const app = Vue.createApp({
        data: function () {
            return {
                a: null,
            }
        },
        methods: {
            fn_pasteToDateInput: function (event) {
                const text = event.clipboardData.getData('text');
                const parsedDate = new Date(text);
                if (!isNaN(parsedDate.getTime())) {
                    const att = event.target.getAttribute('data-model');
                    this[att] = parsedDate.toLocaleDateString('en-GB', { year: 'numeric', month: '2-digit', day: '2-digit' }).split('/').reverse().join('-');
                }
            },
        }
    });
    const vm = app.mount('#app');
</script>

示例中 <input /> 添加了 data- 属性,值同 v-model,并使用 getAttribute() 获取,利用 this 对象的属性名赋值。 

如果你的 a 中还有嵌套对象 b,那么 data- 属性填写 a.b,方法中以“.”分割逐级查找对象并赋值

let atts = att.split('.');
let target = this;
for (let i = 0; i < atts.length - 1; i++) {
    target = target[atts[i]];
}
this.$set(target, atts[atts.length - 1], text);


xoyozo 2 年前
1,845

经常有人碰到这样一种情况,我的 918+ 有 4 个硬盘呢,怎么空间很快就没了,最重要的是,自己查看统计了所有文件占用情况,和实际的占用空间不符。这个首先可以肯定的就是空间必然是文件占用了。但是呢,有些文件是不能从 File Station 里面直接看到的,所以很多用户就搞不懂了,有时候文件删除了,空间也不见增加。今天,就来教大家一个大招,让这些不能直接看到的文件无处遁形。

一、SSH 登陆群晖

这里我们要用到一个叫 putty 的软件

putty下载链接:点此下载

在开始之前,我们要开启群晖的 SSH 或是 telnet 服务功能(控制台 - 终端机和 SNMP - 勾选启动 SSH 功能)。

 1.png

打开 putty,在主机名称输入群晖的局域网 IP 地址,然后点击下面的【打开】。

2.png

会弹出一个黑色的窗口。登入账号输入管理员:admin,按回车,然后输入 admin 的密码,要注意的是,输入密码的时候,光标是不会动的,你尽管输就行。有些用户看到代码就头疼,其实我们用到的都是些非常简单基础的命令代码,你只要照着这个步骤一步一步去做,肯定能成功,成功把空间腾出来后,你会很有成就感,哈哈!

3.jpg

切换到 root 权限,输入 sudo -i,按回车,然后也是输入 admin 的密码。

4.jpg

MAC 电脑用终端也可以登录 :

  1. 打开终端

  2. 输入命令:ssh -p 999 admin@192.168.1.9

  3. 上面 999 为自定义端口号,admin 为自己的用户名


二、查询文件

到这里我们就登陆到群晖里面了,在这里可以执行命令。

输入 cd /volume1 命令后按回车,意思是进入存储空间 1(若您的储存空间为 2,则改成 volume2,依此类推)。

输入 du -ah --max-depth=1,可以查看当前目录文件大小,这个过程可能会需要数分钟到数小时不等,依您的文件数及空间大小而定。实测 8TB 机械硬盘耗时两个多小时。

image.png

三、删除文件

像上面图片中的 @download 就是 Download Station 的缓存文件,有时候操作不当,会造成缓存不能自动删除,这个时候就需要使用代码的方法来删除缓存,才能释放存储空间了。

比如要删除 Download Station 的缓存文件夹,就是上图的 @download 文件夹,可以使用下面这个命令:rm -rf /volume1/@download

6.jpg

这个命令要慎用,一旦删除就不能恢复了!

四、还有哪些文件占用存储空间而不能直接查询

除了 Download Station的缓存文件之外,还有 File Station 里面删除了文件,但启用了回收站,文件实际上还没彻底删除,也会造成删除文件,空间没有增加的情况。这个时候清空一下回收站即可。

清除某个文件夹回收站:

7.jpg

也可以直接一次性清空所有文件夹的回收站:

8.jpg

还有 Drive 的版本控制和 Drive本身自带的回收站;

9.jpg

@synologydrive/@sync/repo 是 Synology Drive Client 的缓存目录,我删除这个目录就释放了 5TB 的空间。

除此之外,还有 Cloud Station 保留的版本,Snapshot Replication 套件生成的快照文件等。


如果发现 /volume1/@synologydrive/@sync/repo/ 这个目录占用空间过大,请参考这篇文章

转自 清风 2 年前
13,996

使用管理员用户登录 SSH 后,键入命令:

sudo -i

然后再次输入登录 SSH 的管理员用户的密码。

xoyozo 2 年前
2,258

群晖系统暂时没有类似 TreeSize 的磁盘文件管理工具,但是我们可以用磁盘映射的方式将群晖系统上的目录挂载到电脑上。这样,在电脑上就可以用 TreeSize 扫描群晖上的磁盘文件了。具体步骤如下:

一、群晖上安装 WebDAV Server

image.png

二、启用 WebDAV Server

image.png

三、新建群晖用户

image.png

千万要设置好权限。

切换到“应用程序”选项卡,关闭除 WebDAV Server 以外的所有应用程序

切换到“权限”选项卡,勾选需要访问的目录

image.png

四、在电脑上安装 RaiDrive

从官网下载,免费版即可。

五、配置 RaiDrive

打开 RaiDrive,点击顶部的“添加”,选择“NAS”,选择“Synology”,并填相应的地址和账户

image.png

技巧:将群晖提供的外部访问地址(在 控制面板-外部访问 中查看)直接在浏览器上打开,如果与群晖在同一局域网,那么会跳转到 https://[IP].[QuickConnect ID].direct.quickconnect.cn:5001/,那么参照这个地址填入到 RaiDrive 中即可在局域网中连接;如果不在同一局域网,那么会跳转到公网地址,同样可以将公网地址填入,但必须在路由器上映射端口才能在外网映射磁盘到 NAS。

六、访问文件

一切顺利,你就可以在“此电脑”中看到新建的盘符,像访问本地磁盘一样访问群晖文件。

image.png

xoyozo 2 年前
6,213

【阿里云】【HDM告警】尊敬的用户: 您的Redis【警告】,检测到时序异常发生,截止目前异常持续60秒,当前时刻异常指标: redis.memory_usage, 值, 变化率; redis.outflow, 值, 变化率;  请您登陆到DAS控制台查看详情。若不想接收该告警消息,请登录HDM控制台屏蔽告警。

进入阿里云控制台 - 数据库自治服务 DAS - 告警服务 - 告警联系人 - 找到并删除

xoyozo 2 年前
2,940

下载 sqlmap:https://github.com/sqlmapproject/sqlmap

下载 python:https://www.python.org/downloads/

以 windows 版为例:

安装 python;

解压缩 sqlmap;

“在终端中打开 / 在命令行中打开” sqlmap.py 文件所在目录;

执行命令 

python sqlmap.py -u "网址" --data="POST数据" --tables

需要注意的是,sqlmap 会记录探测过的网址的结果信息,修复网站漏洞后要再次检测是否安全时,应删除缓存文件,位置在:

C:\Users\用户\AppData\Local\sqlmap\output\

image.png

xoyozo 3 年前
4,660

原生判断

window.addEventListener('scroll', scroll)

function scroll() {
      const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
      const clientHeight = document.documentElement.clientHeight || document.body.clientHeight;
      const scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight;
      
      if (scrollTop === 0) {
        console.log('滚动到顶了');
      }
      if (scrollTop + clientHeight >= scrollHeight - 100) {
        console.log('滚动到底了');
      }
}

window.removeEventListener('scroll', scroll) // 移除滚动事件

scrollTop:文档在可视区上沿的位置距离文档顶部的距离

clientHeight:可视区的高度

scrollHeight:文档总高度

100:用于在滚动到底部之前提前加载内容(如瀑布流),提高用户体验,请自行修改数值(建议不小于 2 像素,以规避在部分浏览器上因获得值为小数时可能无法触发的问题)


jQuery 判断

window.addEventListener('scroll', scroll)

function scroll() {
    const doc_height = $(document).height();
    const scroll_top = $(document).scrollTop();
    const window_height = $(window).height();
    
    if (scroll_top === 0) {
      console.log('滚动到顶了');
    } else if (scroll_top + window_height >= doc_height - 100) {
      console.log('滚动到底了');
    }
}


xoyozo 3 年前
2,463

User-Agent 字符串不会进行更新以区分 Windows 11 和 Windows 10。

但我们可以使用 JS 进行客户端判断是否为 Windows 11:

navigator.userAgentData.getHighEntropyValues(["platformVersion"])
 .then(ua => {
   if (navigator.userAgentData.platform === "Windows") {
     const majorPlatformVersion = parseInt(ua.platformVersion.split('.')[0]);
     if (majorPlatformVersion >= 13) {
       console.log("Windows 11 or later");
      }
      else if (majorPlatformVersion > 0) {
        console.log("Windows 10");
      }
      else {
        console.log("Before Windows 10");
      }
   }
   else {
     console.log("Not running on Windows");
   }
 });

支持客户端提示 User-Agent 浏览器:

浏览器通过客户端提示 User-Agent 区别?
Microsoft Edge 94 及以上
Chrome 95 及以上
Opera
Firefox
Internet Explorer 11


M
转自 MSEdgeTeam 3 年前
2,776