diff --git a/README.md b/README.md index 9e7ace23..261be07c 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,6 @@ My Tech Blog, base on [Urara](https://github.com/importantimport/urara) - [ ] NeoDB component - [ ] ... -### License: +### License -[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/) +© 2024 Sevi.C All Rights Reserved. diff --git a/src/lib/config/friends.ts b/src/lib/config/friends.ts index 9a8485f0..33d65116 100644 --- a/src/lib/config/friends.ts +++ b/src/lib/config/friends.ts @@ -52,14 +52,6 @@ export const friends: Friend[] = [ title: '野生栗子🌰', link: 'https://blog.chestnut.monster/' }, - { - id: 'summerblue', - rel: 'friend', - name: '夏诤', - title: 'SummberBlue', - link: 'https://blog.summerrrrrr.blue', - descr: '早睡早起身体好' - }, { id: 'loikin', rel: 'friend', diff --git a/src/lib/config/general.ts b/src/lib/config/general.ts index 784a09d5..dff140bc 100644 --- a/src/lib/config/general.ts +++ b/src/lib/config/general.ts @@ -128,7 +128,7 @@ export const footer: FooterConfig = { link: '/privacy' } ], - html: 'CC BY-NC-SA 4.0', + html: '@Sevi.C All Rights Reserved.', since: '2021' } diff --git a/urara/2021-11-08-ux1/+page.md b/urara/2021-11-08-ux1/+page.md new file mode 100644 index 00000000..b8702f49 --- /dev/null +++ b/urara/2021-11-08-ux1/+page.md @@ -0,0 +1,132 @@ +--- +title: Overview of User Experience Design +summary: Introduction to User Experience Design|Week1 +created: 2021-11-08T10:54:40+08:00 +# categories: +# - UX学习笔记 +# - Introduction to User Experience Design +tags: + - UX +--- + +## 课程简介 + +这是一门在 [Coursera](https://www.coursera.org/learn/user-experience-design) 上的 UX 课程,共有五个星期的内容,讲了 UX 的基本概念和实际操作流程,主要侧重用户研究方面,也讲了很多和设计心理学有关的内容,很适合 UX 入门。 + +我将按照课程内容的划分,分别发布五个 weeks 的笔记,这是第一篇。 + +原笔记是在 Notion 上写的,我喜欢用 Notion 里面的 toggle 效果,用“提问”-“答案”的形式来启发思考,但是博客这里用折叠文本比较麻烦,所以直接列出来了 + +## Week 1 笔记 + +### 什么是 ux? + +> User Experience design is design that is user centered。The goal is to design artifacts that allow the users to meet their needs in the most effective efficient and satisfying manner。 +> +> **以用户为中心的设计。目标是轻松高效地满足用户的需求。** + +### 用户体验设计的核心概念 + +> “用户使用界面来完成任务” + +通过理解用户以及他们要完成的任务,以便设计出最好的界面 (interface) + +### 什么是用户 + +这里的“用户”是指使用一些技术来达到目的的个体 + +### 什么是界面 + +有输入、输出、系统,于此同时,每个输入都会导致一个期望的输出: +![有输入、输出、系统,于此同时,每个输入都会导致一个期望的输出](/2021-11-08-ux1/1.png) +个人使用界面的能力与个人特征、群体、社会有关 +![个人使用界面的能力与个人特征、群体、社会有关](/2021-11-08-ux1/2.png) + +### 用户体验设计的目标 + +![](/2021-11-08-ux1/3.png) + +**设计“能用”并且“好用”的界面** + +- “**能用**”的意思是:它可以让用户完成一个任务。在图中,这个系统 (S) 就产生了期望的成果 (Output) +- “**好用**”的意思是:用户可以有效高效甚至满意地达成这项任务。在我们的图表中,这需要轻松快速地输入 (Input) 并且输出 (Output) 的结果有效的完成了任务 + +### 界面设计环 (四个步骤) + +![](/2021-11-08-ux1/4.png) + +#### Step1:Requirements Gathering 收集需求 + +- Understanding the user and what her goals are,What are the current practices +- This step can also be thought of as understanding the**“problem space”**- what is hindering the completion of the task how can the task or process be improved +- A whole host of techniques are presented that allow the designer to collect data about the user,her goals and current practices + +#### Step 2:Design Alternatives 设计方案 + +- Once you understand the users,their goals,and their current practices (e.i., the problem space) you are able to take this data and **develop various design options** that will improve the user experience + +#### Step 3:Prototyping 原型 + +- Techniques for modeling the novel designs before a final version is produced + +#### Step 4:Evaluation 评估测试 + +- A set of techniques for ascertaining that your design meets the needs of the user + +### 什么样的界面是“实用”的? + +“实用性”指的是有效、高效并且让用户觉得满意的。 + +> 如果用户能够理解怎样的输入 (Input) 会带来所需的输出 (Output) 那么这个界面就是实用的 + +### 好设计的三个特征 + +![](https://i.loli.net/2021/11/08/MtmwlyuXHGgbJPZ.png) + +#### 1 - Affordance (示能) + +> 指一个物理对象与人之间的关系 +> +> (无论是动物还是人类,甚至机器和机器人,他们之间发生的任何交互作用) + +是指可以感知到的事物的实际属性,主要是那些决定事物如何被使用的基本属性 (看看你的智能手机,我们会看到很多种功能,例如按键,可以感知到可以被按。) + +#### 2 - Signifiers (意符) + +> 能告诉人们正确操作方式的任何可感知的标记或声音。 + +示能决定可能进行哪些操作,意符则点名操作的位置。 + +#### 3 - Feedback (反馈) + +> 一些让你知道系统正在处理你的要求的方式 + +反馈需要将用户信息发送回来其中包括哪些系统输入的信息已发生它跟我们沟通操作结果 + +- 输入:示能、意符 +- 输出:示能 + +### 如何与“用户”接洽 + +注意礼貌、着装 + +#### 三个步骤 + +**1 - 介绍** + +- 简要概述目标 +- 坦率:让用户知道该会话的目标是什么。询问他们坦率的意见。 +- 保密:说明交互内容是保密的。 +- 自愿:在介绍期间,向用户解释他们的参与完全是自愿的。他们可以随时停止参与。如果他们希望停止参与,这不会消极地影响他们与你的公司或机构的关系。这一部分是很重要的,它能让用户放心并能够不受约束,因为你可能代表一个在社区中具有较高知名度的实体 +- 开放:让他们知道,没有正确或错误的答案,他们应该简单直接地向你提供反馈和意见 + +**2 - 交流** + +- 中立态度、语气轻松专业。 +- 如果形式允许,鼓励详细阐述意外或有趣的信息 +- 保持对交流过程的控制,尽量覆盖所有话题 + +**3 - 结束** + +- 在会话结束时,提醒他们有关交互的目标和您打算如何处理他们提供的数据。 +- 询问他们是否还有需要补充的内容。 diff --git a/urara/2021-11-09-ux2/+page.md b/urara/2021-11-09-ux2/+page.md new file mode 100644 index 00000000..b5adf332 --- /dev/null +++ b/urara/2021-11-09-ux2/+page.md @@ -0,0 +1,407 @@ +--- +title: Requirement Gathering +summary: Introduction to User Experience Design|Week2 +created: 2021-11-09T22:26:49+08:00 +categories: + - UX学习笔记 + - Introduction to User Experience Design +tags: + - UX +--- + +## **Overview** + +- **设计流程的第一步** + + 了解用户当前是如何完成任务的 + +- **需求收集的目标是什么?** + + 理解问题域 + +- **问题域(problem space)包含什么?** + + 1. 谁是我们的用户 + 2. 什么时候使用产品、在什么地点、为什么、以及他们当前如何实现目标任务 + 3. 用户所认为的当前存在的问题是什么 + 4. 以及用户自己关于如何改进任务流程的心愿清单 + +- **需求收集的陷井** + + 设计师可能会直接开始设计可供选择的设计品,尽管他们尚未完全了解任务,用户以及用户如何实现任务 换句话说,他们急于直奔主题了 他们在没有取得用户数据的基础上就开始设计了 + +- **设计是一个系统性的数据驱动的过程** + +## **Types of Users and Types of Data** + +### 数据类型 + +#### 定量 + +- 定量数据可以被认为是可以用数字转录的数据, 比如调查数据(用户年龄、性别等等) +- 定量分析是依据统计数据,建立数学模型,并用数学模型计算出分析对象的各项指标及其数值的一种方法。 + +#### 定性 + +- 定性数据更容易被认为是为我们提供专题的信息,可放到叙事语境中(如问卷中的开放性问题) +- 定性分析则是主要凭分析者的直觉、经验,凭分析对象过去和现在的延续状况及最新的信息资料,对分析对象的性质、特点、发展变化规律作出判断的一种方法。 + +> 设计师通常结合使用两种数据,这种方法称为 _混合方法(Mixed method approach)_ + +### 将用户视为利益相关者的三个类型 + +**1.主要 Primary** + +主要利益相关者是直接使用设计的人员。这些是设计者最常与之互动的用户,他们被称为**最终用户** + +**2.二级 Secondary** + +不直接使用设计,但可以**间接地使用**,因为他们从中可得到某种输出 + +**3.三级 Tertiary** + +可能根本不使用设计 ,但**直接受设计的影响**, 无论是消极还是积极的方式 + +### 了解利益相关者的意义 + +> 考虑二级和三级利益相关者,也可以帮助我们创造具有创新性的设计,并为我们的客户提供竞争优势。从这个意义上讲了解利益相关者会带来更好的用户体验设计 + +## **Discovery Technique Overview** + +### 四种调研方法 + +1. 自然观察 (Naturalistic observation) +2. 问卷法( Surveys) +3. 焦点小组( Focus groups) +4. 访谈 (Interviews) + +### 交互程度 + +![](/2021-11-09-ux2/1.png) + +### 进行的场景 + +![](/2021-11-09-ux2/2.png) + +### 在设计周期中迭代 + +![](/2021-11-09-ux2/3.png) + +## **Naturalistic Observation 自然观察** + +### 是什么 + +是在用户自己的环境中,观察用户的行为,不需要询问用户何时何地以及怎样完成既定任务的 设计师会亲自到用户完成任务的地点,并观察他们的行为。 + +### 如何做 + +- 预期计划 +- 实地进行 +- 过程中设计师与用户无交谈 + +### 数据 + +定性、定量 + +### 优点 + +- 直接观察用户的行为,随时随地收集数据 +- 用户的行为习惯真实自然,不受设计师主观影响 + +### 缺点 + +- **数据收集受设计师主观影响。** + + 设计师所收集到的数据,局限于他们个人的收集方式和理解方式。无法核实设计师做出的 假设正确与否 + +- **停留表面,看不到深层原因。** + + 我们并不知道为什么 用户采取这样的方式完成任务 + +### 道德局限 + +需要注意用户隐私、匿名化 + +### 在设计流程中 + +> 基于收集到的数据,进行下一步调研,如问卷、焦点小组等,使问题域更聚焦,探寻真正的问题所在,解释用户行为的原因 + +## **Survey 问卷** + +### 是什么 + +- 问卷调查的目的是了解用户的观点。 +- 最常见的是让用户自我报告他们的行为、主观感觉、态度和感受。我们也可以获取他们对于他人的看法 + +### 如何做 + +- 实地、实验室 +- 几乎不需要直接和用户交流 +- 形式:纸质问卷、电子问卷、面对面调查 + +### 数据 + +#### 1.定性-封闭性问题 + +**Closed-ended questions** + +- **顺序回答** + - **二分型问题 (dichotomous )** + 是/否 + - **李克特评分 (likert scales)** + 评分 1-5 + - **排序 (rank)** + 如按照喜好程度排序 +- **乱序回答** + - 给用户呈现了一系列的问题,这些问题并没有逻辑顺序 + - 例如,人种学问卷:如性别、 教育程度或者是一些列举项,供用户勾选适用于他们的选项 + +#### 2.定量-开放性问题 + +**Open-ended questions** + +目的是获取用户简短的回答,包括他们的观点、偏好、态度等 + +### 优点 + +- 高效收集数据 +- 数据易于分析 + +### 缺点 + +- 信息表面化,不能提供深入洞察 +- 回忆偏倚、社会称许性偏见和样本偏差 + +### 在设计流程中 + +![下一步组织焦点小组或自然观察,深入洞察](/2021-11-09-ux2/4.png) + +## **Focus group 焦点小组** + +### 是什么 + +- 目的是让用户参与直接对话 +- 焦点小组在可控的环境中进行,通常是一个房间   在这个充满隐私性的房间里 用户可以自由地分享和讨论自己的观点 +- 焦点小组能够与参与者产生高度互动,这种程度高于   问卷调查,但是低于采访 + +### 如何做 + +#### 组成 + +- **用户** + - 5-10 个用户 + - 这些用户应能够代表设计师所关注的用户群体 +- **设计团队** + + **1. 主持人** + + - 一个训练有素的主持人 他负责组织用户讨论的话题 + - 主持人必须非常擅长深入挖掘,在讨论过程中出现的有价值的主题。但同时也要引导用户的讨论 使之覆盖所需要的主题范围 + + **2. 记录员** + + - 负责记录用户和主持人之间的谈话要点 + + **3. 媒介记录员(可选)** + + - 使用录音或者   录像设备进行记录 + +- **流程** + + ![热身-创新训练-三主题讨论-用户最终意见总结](/2021-11-09-ux2/5.png) + +### 数据 + +- **定性** + + - 对话过程中记录员写下的一系列笔记 + - 完整的焦点小组对话脚本 + - 对焦点小组的分析 + +- **定量** + + - 可能会在焦点小组一开始进行收集 (例如收集用户的人种学统计信息,或者捕捉关于用户态度的原始问卷调查信息,以及用户对于目标话题的观点) + - 主持人应当善于运用这些数据快速开始对话 + +### 优点 + +- 能够在短时间内收集到关于所感兴趣话题的海量数据 +- 充满活力的小组讨论 或许能够激发出不一样的结果 这些结果是一对一访谈无法得到的 + +### 缺点 + +- 需要设计团队去执行 +- 数据收集的质量依赖主持人水平 +- 群体思维 + +### 在设计流程中 + +![](/2021-11-09-ux2/6.png) + +- 设计流程中的高潮,应在进行其他与用户交互较少的调研方法后使用(如自然观察、问卷 +- 在焦点小组之后,设计师或许需要采访其他的用户   目的是获取更多关于焦点小组中发现的有趣话题的信息 + +## **Interviews** + +### 是什么 + +目的是深度收集用户信息 + +### 如何做 + +- 实地、实验室 +- 足够的隐私程度 以确保用户可以自如地回答问题 + +### 数据 + +定性>定量 + +- **定性** + - 设计师所作的一系列访谈笔记 + - 访谈记录的系统性分析 +- **定量** + - 可以在访谈的开始进行收集 + - 可以以简短问卷的形式进行(它可以用来迅速获取人种学信息,或者 快速了解用户对于访谈话题的态度,访谈者可以利用这些信息开始访谈环节) + +### 优点 + +- 与用户一对一访谈(深度访谈) +- 灵活的采访提纲 + +### 缺点 + +- 需要熟练的采访者 + > 需要知道用户将会继续说什么,以及 何时控制不再提供价值的对话。 采访者的技能在保持融洽关系方面也很重要, 这种关系应该是既灵活又平衡的。 它使用户舒适, 足以提供诚实的意见 但不能太舒适 而导致用户想用采访者的反应来取悦她。 +- 数据的收集和分析耗时 +- 定性数据分析费力 + +### 在设计流程中 + +![](/2021-11-09-ux2/7.png) + +- 据收集策略达到极点时,访谈最有用。 + +- 这意味着当问题得到很好的理解时, 设计人员在需求收集流程中处于关键位置, 需要的是用户最终的澄清或见解。 + +## **User Results 用户数据处理** + +> 假设:已对定性和对定量数据进行了适当的分析 + +### 描述性统计信息 + +**Descriptive statistics** + +描述性统计允许我们总结定量信息 这包括数据集的范围、平均值和中值 + +1. 范围 +2. 平均值 +3. 中值 (减少极端数据的影响) + +### 用户特征表 + +**User characteristics table** + +特征表以简单的形式提供了我们所有数据的快速总结,包括定量数据和定性数据 + +![](/2021-11-09-ux2/8.png) + +### 人物画像 Persona + +## **Presenting Task Findings** + +### Scenario + +场景 + +> 场景使得我们能**了解用户如何使用系统。** + +![Scenario例子](/2021-11-09-ux2/9.png) + +#### 是什么 + +场景提供了定性和定量数据的描述。 + +#### 作用 + +- 使我们有机会传达我们在故事线中 收集数据的丰富性 +- 故事线会突出所有任务的重要方面以及目前如何完成任务。 +- 它让任务变的真实,超越了 枯燥的数据图表和表格 + +### Essential Case Study + +基本案例场景 + +> 帮助理解  **用户的活动以及系统的要求**。 + +![案例](/2021-11-09-ux2/10.png) + +#### 三个要素 + +**1.用户的目标** + +- 首先,它用户的目标进行命名。 这捕捉到了 X 的哪些方面。 +- 在本例中 用户可能想知道她去西印度群岛是否需要签证。 + +**2. 用户意向** + +- 她进入系统需要进行的一系列步骤。 + +**3.系统的责任** + +- 用户完成每个步骤后系统必须执行的操作。 +- 所以在这里,用户首先要找到 签证要求然后系统请求获得目的地和国籍。 一旦用户提供所需信息 系统将获得相应的签证等信息。 + +### Hierarchical Task Analysis + +分层任务分析 + +> 最常见的任务分析技术。  使我们考虑**用户当前如何完成任务**。关键点是**可观察的行为**。 + +![](/2021-11-09-ux2/11.png) + +- 简单的形式就是一个**大纲**。 +- 从目标开始。 并对目标中的每个主要步骤进行**编号**。 其中一些步骤包含必须先完成的小步骤 然后才能继续下一步 这项技术是关于用户目标的。 +- 与基本案例不同。 我们**没有考虑航空公司系统**需要在每个用户步骤中做什么。 +- 另外请注意, 我没有将一些系统交互任务列入, 比如使用滚动条。 这**只是与用户和完成目标的步骤有关。** + +### Current UI Critique + +当前 UI 评估 + +![](/2021-11-09-ux2/12.png) + +![](/2021-11-09-ux2/13.png) + +- 需要与 UI 进行真实交互。 +- 系统地分析当前正在使用的界面。 你要确认你明确地传达出需求被满足以及 为了改善用户体验你能做的事情。 + +#### 步骤 + +**1.确定用户任务** + +对于每个 UI 对应的每个 UI ,你想要确定任务或者用户使用的目的是什么 + +**2. 测定任务完成时间** + +要客观的测定所需时间去 响应这个客户提交的任务 + +在这个例子中 我选择了一些点击,它会让我使用这个应用程序,或者网站,或者通过终端完成任务。 + +**3. 评估操作** + +**4. 改进方法** + +## **相关资源** + +Resources for Requirement Gathering + +1. [25 Useful Brainstorming Techniques](http://personalexcellence.co/blog/brainstorming-techniques/) +2. [Non-Functional Requirements - Minimal Checklist](http://leadinganswers.typepad.com/leading_answers/2009/03/nonfunctional-requirements-minimal-checklist.html) +3. [Differentiating between Functional and Nonfunctional Requirements](http://searchsoftwarequality.techtarget.com/answer/Differentiating-between-Functional-and-Nonfunctional-Requirements) +4. [Facilitated Brainstorming](http://www.usabilityfirst.com/usability-methods/facilitated-brainstorming/) +5. [5 powerful ways to brainstorming with teams/](http://blog.abovethefolddesign.com/2010/11/11/5-powerful-ways-to-brainstorming-with-teams/) +6. [ips for Structuring Better Brainstorming Sessions](http://www.inspireux.com/2013/07/18/tips-for-structuring-better-brainstorming-sessions/) +7. [Collaborative Brainstorming for Better UX Workshop](http://www.slideshare.net/jessicaivins/aiga-cincy-uxworkshop01) +8. [WHAT IS AN AFFINITY DIAGRAM?](http://asq.org/learn-about-quality/idea-creation-tools/overview/affinity.html) +9. [Affinity Diagrams](https://www.mindtools.com/pages/article/newTMC_86.htm) +10. [Affinity diagramming](http://infodesign.com.au/usabilityresources/affinitydiagramming/) diff --git a/urara/2021-11-14-ux3/+page.md b/urara/2021-11-14-ux3/+page.md new file mode 100644 index 00000000..3271d0e4 --- /dev/null +++ b/urara/2021-11-14-ux3/+page.md @@ -0,0 +1,111 @@ +--- +title: Design Alternatives +summary: Introduction to User Experience Design|Week3 +created: 2021-11-14T11:18:45+08:00 +categories: + - UX学习笔记 + - Introduction to User Experience Design +tags: + - UX +lastmod: 2022-04-16T12:56:27.924Z +--- + +## Review of Design Goals 审查设计目标 + +### 用户体验的核心目标 + +> "用户使用界面来完成任务 " +> +> 通过理解用户以及他们要完成的任务 以便设计出最好的界面(interface) + +前提是,最好的界面 只能在我们了解用户和他们想要完成的任务之后才能被设计出 + +### 设计的定义 + +> 一种创新的开发用来满足一些需求。 + +### 设计的目标 + +- 要比现有的设计更好地满足用户的需要 +- 不是为了新奇本身,而是为了服务和改善用户体验 +- 设计新的界面是为了**找到更好的方法来调解用户如何实现任务**。 它可能需要我们创建一个全新的系统。 或者,我们可以简单地设计出新的输入和输出。 + +### 设计时,需考虑的三个方面 + +![](/2021-11-14-ux3/1.png) + +- **个人层面 individual** + - 考虑用户特征。 这些包括用户的年龄,教育水平,和对科技的适应程度, + - 考虑用户之间的差异。 +- **群体 group** + - 考虑用户之间的交互(一组用户) +- **社会 society** + - 文化事件会影响系统的使用 和采纳情况。 + - 我们需要了解与用户所从事的任务相关的文化价值观, 并在设计时考虑这些问题 + +## **Design Alternatives 设计替代方案** + +### 目标 + +开发一个比现在更能满足用户需求的界面(基于设计的问题空间) + +### 关键 + +使用屏幕实践将设计基础概念化 + +### Road map 路线 + +- **能用 useful** + + - **目标** + + 改善用户完成目标任务的能力 + + - **方法** + + 回顾第一阶段获得的数据 并且鉴别出用户的需求 + + 1. **显性需求** + + ![](/2021-11-14-ux3/2.png) + + 2. **隐形需求** + + ![](/2021-11-14-ux3/3.png) + +- **好用 usable** + + - **目标** + + 以功能性和在第一阶段所发现的非功能性的需求为基础,使用户更加有效高效和满意 地完成任务,从而改善他们的用户体验 + + - **方法** + + 回顾第一阶段的数据,确定设计可替代品中功能性和非功能性的需求 + ![](/2021-11-14-ux3/4.png) + + 1. **功能性需求** + + ——面向用户的 + + 系统应该完成的,这些基于用户所期望的系统功能 + + 2. **非功能性需求** + + ——面向商家的 + + 和系统开发有关的限制。它们也可以被看作质量特性( 这些特性包含了许多或后端功能,比如安全性,可执行性,可维护性 但是他们也包括了前端功能货可用特性,像布局、流程或者甚至是语言本地化需求) + +- **小组讨论** + - 头脑风暴 + - 学生或设计师的个人特征, 也会影响到他们发现的需求 + - 在头脑风暴中,最重要的原则是打开思路,不要错过任何点子 + - 想法整理 + 使用类同图表有助于把头脑风暴数据设计成流线型 + 1. 参与者是设计师或与设计师相关的人 + 2. 在各自的便贴纸上写下想法。 + 3. 然后设计师收起这些纸条 + 4. 并把他们按照相同程度组织起来,以一些典型的概念为导向。 + 5. 之后设计师们来决定什么样的界面   可以满足所有的功能性的需求   一类或者一个同类的需求 +- **界面类型** + ![](/2021-11-14-ux3/5.png) diff --git a/urara/2021-11-18-ux4/+page.md b/urara/2021-11-18-ux4/+page.md new file mode 100644 index 00000000..19f3f919 --- /dev/null +++ b/urara/2021-11-18-ux4/+page.md @@ -0,0 +1,130 @@ +--- +title: Prototyping +summary: Introduction to User Experience Design|Week4 +created: 2021-11-18T21:26:41+08:00 +categories: + - UX学习笔记 + - Introduction to User Experience Design +tags: + - UX +--- + +## **关于 Prototyping** + +### 什么是原型开发 + +- 原型开发可以被定义为一个新颖设计的早期模型 +- 通过原型来评估新设计的各个方面 并检查设计是否达到了预期的结果 + +### 原型开发的作用 + +- 经济(节约时间的金钱) +- 快速构建、迭代 + +### 水平原型 + +![](/2021-11-18-ux4/1.png) +涵盖功能的广度,整合所含的功能(大概有什么) + +### 垂直原型 + +![](/2021-11-18-ux4/2.png) +对一些特征进行深入的建模(多层级) + +## **低保真 Lofi Prototype** + +### 低保真和高保真的区别 + +- 低保真原型与最终设计几乎没有什么相似之处,无论是在形式或功能上(快速迭代、验证想法) +- 高保真原型则与最终设计非常相似 + +### 注意事项 + +- 注重用户反馈 +- 也可以让利益相关者加入反馈过程 +- 避免完美主义,注重想法的表达和验证,关注核心路径 + +### 三种形式 + +#### 1. 草图 + +表明用户场景,痛点是怎么产生的(场景) +![](/2021-11-18-ux4/3.png) + +#### 2. 故事版 + +![](/2021-11-18-ux4/4.png) + +- 一种以静态方式提供叙事的常用方法 +- 将设计放在上下文中,来考虑用户如何在给定的场景中使用我们的新设计。 +- 场景互动的迭代,简单的任务图形、场景互动 + +#### 3.卡片原型 + +![](/2021-11-18-ux4/5.png) + +- 表示我们与实际界面可能发生的交互序列。 +- 使用一组索引卡。逐一代表一个用户在尝试完成任务时,会遇到的一序列屏幕。 + +## **其他原型方式** + +### 绿野仙踪/奥茨法师 + +_Wizard of Oz_ + +![](/2021-11-18-ux4/6.png) + +- 用来模拟产品的功能。 +- 通过让人执行通常由计算机执行的任务,在这里用户不知道该产品是不具备功能性的 +- 优点:能够节省建立功能性产品的时间和金钱 +- 缺点: + - 需要相当长的时间来使其正常运转,并且它总是需要多人操作 + - 需要一个训练有素的巫师,最终用户可能对系统有不切实际的期望。 + - 基于欺骗性的功能,反过来可能会限制他们提供反馈,继而限制从收集的数据中得出的推论 + +### 概念验证视频 + +_Proof of Concept Video_ + +- 一个能够在各种场景下展示各种用途和系统的功能的视频(系统是如何工作的 以及在什么情况下它会有用) + +### 隐喻技术 + +_Metaphor Development_ + +- 考虑用户如何看待设计 +- 帮助用户建立新设计如何运作的**相关心理模型** +- 隐喻将新功能与用户以及熟悉的系统功能相比较对比。 + +## **相关资源** + +### Resources and Tools for Protoyping 1 + +1. [prototyping.html](http://www.usability.gov/how-to-and-tools/methods/prototyping.html) +2. [high fidelity prototype/](http://www.usabilityfirst.com/glossary/high-fidelity-prototype/) +3. [high fidelity vs low fidelity prototyping web design and app development](http://www.atlargeinc.com/insights/high-fidelity-vs-low-fidelity-prototyping-web-design-and-app-development) +4. [Social Mirror](https://www.youtube.com/watch?v=91-JnTq3MhA) + +### Tools + +1. [Uxrecorder](http://www.uxrecorder.com/) +2. [Invision](https://www.invisionapp.com/) +3. [Marvel](https://marvelapp.com/) +4. [Axure](http://www.axure.com/) + +### Resources for Prototyping 2 + +1. [What a prototype is and is not](https://uxmag.com/articles/what-a-prototype-is-and-is-not) +2. [the skeptics guide to low fidelity prototyping](https://www.smashingmagazine.com/2014/10/the-skeptics-guide-to-low-fidelity-prototyping/) +3. [low fidelity prototype](http://www.usabilityfirst.com/glossary/low-fidelity-prototype/) +4. [why every consumer internet startup should do more low fidelity prototyping](http://andrewchen.co/why-every-consumer-internet-startup-should-do-more-low-fidelity-prototyping/) +5. [lofi vs hifi prototyping how real does the real thing have to be](http://www.telono.com/en/articles/lo-fi-vs-hi-fi-prototyping-how-real-does-the-real-thing-have-to-be/) +6. [prototyping types of prototypes](http://it.toolbox.com/blogs/enterprise-solutions/prototyping-types-of-prototypes-14927) +7. [horizontal and vertical prototypes](http://www.usabilityfirst.com/glossary/horizontal-and-vertical-prototypes/) +8. [introduction sketch ui design/](http://marketblog.envato.com/grow-improve/creativity/introduction-sketch-ui-design/) +9. [the messy art of ux sketching/](https://www.smashingmagazine.com/2011/12/the-messy-art-of-ux-sketching/) +10. [how to draw quick useful ui sketches](http://www.slideshare.net/LaneHalley/how-to-draw-quick-useful-ui-sketches) +11. [User interface sketching tips part-1](http://ui-patterns.com/blog/User-interface-sketching-tips-part-1) +12. [storyboarding in the software design process](https://uxmag.com/articles/storyboarding-in-the-software-design-process) +13. [the 8 steps to creating a great storyboard](http://www.fastcodesign.com/1672917/the-8-steps-to-creating-a-great-storyboard) +14. [users story ux storyboarding](http://www.slideshare.net/fgarofalo/users-story-ux-storyboarding) diff --git a/urara/2021-11-18-ux5/+page.md b/urara/2021-11-18-ux5/+page.md new file mode 100644 index 00000000..83e7f7f1 --- /dev/null +++ b/urara/2021-11-18-ux5/+page.md @@ -0,0 +1,94 @@ +--- +title: Evaluation +summary: Introduction to User Experience Design|Week5 +created: 2021-11-18T22:09:49+08:00 +categories: + - UX学习笔记 + - Introduction to User Experience Design +tags: + - UX +--- + +## **评估** + +- 可以确定我们正在改善用户的体验 +- 需要定性、定量的数据 + +## **分类** + +### 形成性评估 + +- 在设计**低保真**原型的过程中进行的 +- 数据:( 例如:完成任务的时间或点击次数)(关注任务) +- 环境:一个受控环境, 例如, 实验室或办公室 + +### 总结性评估 + +- 是在**高保真**原型或最终界面即将完成的情况下进行的。 +- 数据:设计者能够访问的和分析的数据, 它们可以告诉我们如何使用系统。 例如,用户开始和结束会话时可能会有时间戳, 并记录用户如何与系统交互的数据(真实场景)、 +- 场景:高保真原型可在野外进行,如真实的使用场景 + +## **如何评估** + +### 数据收集 + +- 以问卷形式进行的定量数据, +- 记录用户完成任务时所经过的路径的数据。 +- 用户访谈的形式获得的定性数据 + +### 衡量 + +- 衡量任务的目标所达到的程度(完成程度) +- 包括完成任务的时间、单击次数或   执行任务时出现的错误数。 + +### 可学习性 + +- 定义:首次成功完成任务的简单程度。 +- 衡量:完成任务的点击次数、完成任务所需的时间量来获得客观的测量结果, 然后将这些数据与专家的表现进行比较。 + +### 可记忆性 + +- 定义:要记住产品用方法的难易程度(如何在反复试验之后在界面上执行给定的任务) +- 衡量:时间量或点击次数(完成一项反复试验的任务, 以获得可记忆性的测量) + +### 主观情感评估 + +![](/2021-11-18-ux5/1.png) + +- 认知测量:心理负担 +- 情感测量:情感体验 + +## **相关资源** + +1. [usability evaluation](http://www.usability.gov/what-and-why/usability-evaluation.html) +2. [15. Usability Evaluation](https://www.interaction-design.org/literature/book/the-encyclopedia-of-human-computer-interaction-2nd-ed/usability-evaluation) +3. [more than ease of use](http://www.wqusability.com/articles/more-than-ease-of-use.html) +4. [Measuring Usability: Are Effectiveness, Efficiency, and Satisfaction Really Correlated?](http://www.diku.dk/~kash/papers/CHI2000_froekjaer.pdf) +5. [usability 101|introduction to usability/](https://www.nngroup.com/articles/usability-101-introduction-to-usability/) + +## **推荐教材** + +### Trade Book + +- **The Design of Everyday Things** + 2013 edition by Don Norman + +### Text Books + +- **Interaction Design** + - by Jennifer Preece, Helen Sharp and Yvonne Rogers (in alphabetical order). + - There are four editions of this book. I believe any of the editions are a good purchase. This is the book I use in my undergraduate college course. +- **Human Computer Interaction** + - 2004 by Dix, Finlay, Abowd & Beale. + - This is an advance text book. +- **Understanding Your Users** + - 2015 edition by Baxter, Courage & Caine. + - I really like this book because it does what it claims, provides a "practical guide to User Research Methods + +## **参考网站** + +- [What is Usability? | Usability Body of Knowledge](http://www.usabilitybok.org/what-is-usability) +- [User interface design - Wikipedia](https://en.wikipedia.org/wiki/User_interface_design) +- [User experience design - Wikipedia](https://en.wikipedia.org/wiki/User_experience_design) +- [Usability First: Usability in Website and Software Design](http://www.usabilityfirst.com/) +- [Methods](http://www.usability.gov/how-to-and-tools/methods/index.html) diff --git a/urara/2022-03-03/+page.md b/urara/2022-03-03/+page.md new file mode 100644 index 00000000..e62ea44f --- /dev/null +++ b/urara/2022-03-03/+page.md @@ -0,0 +1,78 @@ +--- +title: JavaScript · 判断水仙花数 +summary: 用JavaScript判断水仙花数 +created: 2022-03-03T15:07:14.533Z +categories: + - JavaScript +tags: + - JavaScript +slug: Narcissistic-number-in-JavaScript +lastmod: 2022-04-07T07:20:02.340Z +--- + +题目来源: [“如果”可以“重来” | 百度前端技术学园](http://ife.baidu.com/javascript/if&while.html#%E7%BC%96%E7%A0%81%E4%B8%89) + +## 题目 + +根据用户输入的数据,判断水仙花数(三位数),水仙花数是指一个 n 位数 (n≥3),它的每个位上的数字的 n 次幂之和等于它本身。 + +```html + + +
+ + +``` + +**需求说明** + +- 当点击 `开始判断` 按钮,就执行 `numDaffodils` 函数判断输入的数字是否为水仙花数. +- 如果是,就弹出提示框提示是水仙花数,如果不是,就提示不是水仙花数 +- 例如输入 153,`153=1* 1*1+5*5*5+3*3*3` , 是水仙花数,就提示 153 是水仙花数。 +- 请加入输入判断,必须输入数字,不能输入其他类型。 + +## 解法 + +```html + + +
+ + +``` + +这里有一个坑:从 `` 获取输入内容[^1],因为 `type=text` ,所以输出的是 `string` 而不是 `number`,不能直接用`typeof ==='number'`判断输入的是不是数字 + +## 参考 + +- [learn/task2_3 简单水仙花.html · Homeuh/learn · GitHub](https://github.com/Homeuh/learn/blob/6ed2d79cd6abff09f981c0af21080c38b55b6ef2/out/artifacts/Web0_1_Web_exploded/Task_JS/task2_3%E7%AE%80%E5%8D%95%E6%B0%B4%E4%BB%99%E8%8A%B1.html) + +- [IFE/水仙花数.html · Yaomiaomu/IFE · GitHub](https://github.com/Yaomiaomu/IFE/blob/fed038d6c76b2bf62ee83d6539c927c6fa333b91/JAVASCRIPT/%E6%B0%B4%E4%BB%99%E8%8A%B1%E6%95%B0.html) + +[^1]: [HTML text input allow only numeric input](https://stackoverflow.com/questions/469357/html-text-input-allow-only-numeric-input) diff --git a/urara/2022-03-04-decbin/+page.md b/urara/2022-03-04-decbin/+page.md new file mode 100644 index 00000000..754dd785 --- /dev/null +++ b/urara/2022-03-04-decbin/+page.md @@ -0,0 +1,76 @@ +--- +title: JavaScript · 十进制数转二进制 +summary: 用JavaScript将十进制数转二进制数 +created: 2022-03-04T14:57:48.683Z +draft: '' +tags: + - JavaScript +categories: + - JavaScript +lastmod: 2022-04-16T12:54:16.167Z +type: default +# changelogs: +# - tag: "20220308" +# summary: +# - 将`push` 改为`unshift` +# - 使用`padding`填充字符串 +# - 修改`binNumber.length >= binBit` +--- + +## 题目 + +来源:[“如果”可以“重来” | 百度前端技术学园](http://ife.baidu.com/javascript/if&while.html#:~:text=opens%20new%20window) + +验证工具:[在线进制转换 | 进制转换器 — 在线工具](https://www.sojson.com/hexconvert.html) + +### Task1 + +实现当点击转化按钮时,将输入的十进制数字转化为二进制,并显示在 `result` 的 `p` 标签内 + +### Task2 + +- 转化显示后的二进制数为 bin-bit 中输入的数字宽度,例如 `dec-number` 为 5 ,`bin-bit` 为 5 ,则转化后数字为 `00101` +- 如果 `bin-bit` 小于转化后的二进制本身位数,则使用原本的位数,如 `dec-number` 为 5 ,`bin-bit` 为 2 ,依然输出 `101` ,但同时在 console 中报个错。 + +## 解法 + +```html + + + +

运算结果

+ +``` diff --git a/urara/2022-03-06-airtable/+page.md b/urara/2022-03-06-airtable/+page.md new file mode 100644 index 00000000..d3149799 --- /dev/null +++ b/urara/2022-03-06-airtable/+page.md @@ -0,0 +1,115 @@ +--- +title: Airtable · 网页剪藏 +summary: Airtable Web Cilpper设置 +created: 2022-03-06T05:58:29.026Z +categories: + - 实用技巧 +tags: + - 实用技巧 +# layout: post +lastmod: 2022-04-16T12:54:20.049Z +--- + +## 书签这回事 + +上回说到用 [自建网页书签 Flare](https://sevic.me/blog/flare/) ,今天不小心把 SSH 链接弄坏了(也就是连不上了),因为搭载的服务不多,所以把整个服务器都重装了,Flare 网页书签也炸了。 + +其实搭建之后我没有用过(一次都没有),平时的书签管理主要靠搜索,各个浏览器之间的书签互相导入后,直接在搜索栏搜,如果是常用的网址,我用 Chorme 扩展 [eesel](https://chrome.google.com/webstore/detail/eesel-productivity-at-wor/jffaiidojfhflballoapgofphkadiono) 来解决,它可以列出最近用过的网页,按站点分类,查找起来很方便 + +![essel 书签](https://s2.loli.net/2022/03/06/JuHOINUdjprxV19.png) + +最近还推出了一个新功能,可以通过命令进行一下快捷操作,如创建新的 coda 文件、figma 文件等……有点像 Alfred + +![](https://s2.loli.net/2022/03/06/7ZzGSUrWKR1vm6k.png) + +然后还有一个工具叫 [Omni](https://chrome.google.com/webstore/detail/omni-bookmark-history-tab/mapjgeachilmcbbokkgcbgpbakaaeehi) 可以做类似的事情,它还可以搜收藏夹,但不知道为什么我的 Chrome 用不了这个,所以也一直没用。 + +## 关于 Airtable + +Airtable 是一个多功能的表格应用,它的表格跟 Notion 里的 Database 挺像的,不过功能更多,用来做网页收藏夹 Free Plan 完全够用。基本的操作可以看这个: [真· Airtable 3 分钟菜鸟入门 - 少数派](https://sspai.com/post/44746) ,我没有什么要补充的。 + +从去年开始,我开始用 Airtable 整理我的一些收藏夹。原因如下: + +1. 可以分享的表格链接,移动端网页适配也很好 +2. 提供可嵌入网页(如博客)的 ` + +## 怎么用 Airtable 剪切网页 + +我的收藏夹示例: [Airtable - About Coding](https://airtable.com/shrpftxf6JgRomP2X/tblEvtThXHNBMQ8lW/viwSXGTALloahC10H) + +### 1. 创建表格 + +至少包含三项内容: + +1. URL:用来放网页的链接 +2. LongText:网页描述 +3. Attachment:放网页截图 + +如果需要打开 Markdown 格式支持,需要打开 `Enable rich text formatting` +![](https://s2.loli.net/2022/03/06/7agleEFG5YyNSWU.png) + +也可以增加 Tag 和 Categories 分类等其他内容,下面是我建的示例文件: + +![](https://s2.loli.net/2022/03/06/3IRug7QaOs46vBW.png) + +### 2. 创建 app + +点击右上角的 `App` → 点击 `App an app` → 搜 `Web clipper` +![](https://s2.loli.net/2022/03/06/ldpgQ9weHMJctUf.png) + +点击 `add` 添加应用 + +![](https://s2.loli.net/2022/03/06/v2TPpVXMnt4jYx8.png) + +然后按提示安装 Chrome 拓展,你可以直接在这里安装: [Airtable web clipper](https://chrome.google.com/webstore/detail/airtable-web-clipper/fehcbmngdgagfalpnfphdhojfdcoblgc) + +为剪切动作命名,如直接用表格名字:About Coding +![](https://s2.loli.net/2022/03/06/69YEJzKCX5xntP7.png) + +然后点击 `Add to Extension`, 你会看到它出现在了 Web clipper 里面,不过现在先不用管,点击左上角关掉。![](https://s2.loli.net/2022/03/06/1tiLkpEXqTKJw3o.png) + +### 3. 配置剪切设置 + +在 Web clipper 的设置页面(如下),可以调整表格里面各个单元格对应的网页数据,可以按需设置 + +![](https://s2.loli.net/2022/03/06/6FMhjrZR2NSsqOG.png) + +其中: + +- Page Title:页面标题 +- Page URL:页面链接 +- Selected text:打开 Web Clipper 时选中的文本 +- Meta tag:The field will be prefilled with the value of the matching meta tag. (不知道是什么 +- Text content by CSS selector:用 CSS 选择文本,会返回第一个符合选择器的文本内容,如 `.page-description` +- HTML attribute by CSS selector :结合 HTML 属性选择 + +我的设置是: + +- Name——Page title +- URL——Page URL +- Attachments——none +- Description——Selected Text + +### 4. Web Clipper 剪切 + +配置好后就可以开始使用了。在你需要剪切的网页,打开 Airtable web clipper,也就是先前安装的浏览器拓展,点击相应动作,比如刚才创建的 About Coding(如果这个面板有挡到页面内容,可以用鼠标拖动到别的地方) + +![](https://s2.loli.net/2022/03/06/RTu2xDNn5teqlQP.png) + +在 Attachment 里选择附加图片的来源: +![](https://s2.loli.net/2022/03/06/tyU87WD4jsdBHiN.png) + +Description 里面的内容可以自己写,也可以在打开 Web clipper 之前先选中,打开后会自动填充进去,如图: +![](https://s2.loli.net/2022/03/06/vPLMNaOlkotWV2Y.png) + +最后点击 `Add record` 就完成啦 diff --git a/urara/2022-03-07-filter/+page.md b/urara/2022-03-07-filter/+page.md new file mode 100644 index 00000000..29415c7c --- /dev/null +++ b/urara/2022-03-07-filter/+page.md @@ -0,0 +1,65 @@ +--- +title: JavaScript · 字符串去重 +summary: 编码实现字符串去重 +created: 2022-03-07T13:55:21.090Z +tags: + - JavaScript +categories: + - JavaScript +lastmod: 2022-04-07T07:20:30.550Z +--- + +## 题目 + +来源:[百度前端学院](http://ife.baidu.com/javascript/string.html#%E5%AD%97%E7%AC%A6%E4%B8%B2) + +```js +/* +去掉字符串 str 中,连续重复的地方 +*/ +function removeRepetition(str) { + // do something +} + +// 测试用例 +console.log(removeRepetition('aaa')) // ->a +console.log(removeRepetition('abbba')) // ->aba +console.log(removeRepetition('aabbaabb')) // ->abab +console.log(removeRepetition('')) // -> +console.log(removeRepetition('abc')) // ->abc +``` + +## 解法 + +```js +function removeRepetition(str) { + let strArr = [...str] + const result = strArr.filter((s, i, arr) => s !== arr[i + 1]).join('') + return result +} + +console.log(removeRepetition('aaa')) // ->a +console.log(removeRepetition('abbba')) // ->aba +console.log(removeRepetition('aabbaabb')) // ->abab +console.log(removeRepetition('')) // -> +console.log(removeRepetition('abc')) // ->abc +``` + +如果没有限定条件说是“连续重复”,就可以用 **Set**: + +```js +function removeRepetition(str) { + let strArr = [...new Set(str)] + return strArr.join('') +} +console.log(removeRepetition('aaa')) // ->a +console.log(removeRepetition('abbba')) // ->ab +console.log(removeRepetition('aabbaabb')) // ->ab +console.log(removeRepetition('')) // -> +console.log(removeRepetition('abc')) // ->abc +``` + +## 其他解法 + +- [filter 结合 call Method](https://www.programminghunter.com/article/7794242622/) +- [用 for 循环的两种方式](https://www.cnblogs.com/zyc-zsxbh/p/9327364.html) diff --git a/urara/2022-03-07-obsidian-notes1/+page.md b/urara/2022-03-07-obsidian-notes1/+page.md new file mode 100644 index 00000000..2730b953 --- /dev/null +++ b/urara/2022-03-07-obsidian-notes1/+page.md @@ -0,0 +1,101 @@ +--- +title: Obsidian · 网课学习笔记整理 +summary: 拆分整合的过程 +created: 2022-03-06T16:23:33.118Z +tags: + - Obsidian +categories: + - Obsidian +lastmod: 2022-04-07T07:20:39.933Z +--- + +最近在用 obsidian 做网课学习笔记,感觉还挺好用的。简单记一下我记笔记的一些方法(其实也不算什么方法)需要用到的插件:Image Auto Upload,用来传图片。 + +其实我的记笔记方法很简单,就是不断拆碎重组,方便后面查找。 + +上课时,先按时间顺序书写笔记,就像传统的笔记本一样,上完课后再将那一页笔记拆碎重组到知识结构中。方法论大概是 MOC?就是用索引去整理笔记结构,而不是所处文件夹的层次,这里我们先不做深入探讨。 + +下面以学习 JavaScript 为例子。 + +我近期的笔记目录页面(用 Logseq 发布):[JavaScript](https://javascript-logseq.netlify.app/#/page/javascript) + +## 具体的方法 + +我把几乎所有的笔记都放在一个叫 `Zone` 的文件夹内,常用的会打上星标,或者移到最外层文件夹,新笔记默认放在 `Zone` 文件夹下。 + +### Step1-构建地图 + +MOC 是 Map of Contents,也就是内容地图,所以我们会从构建一张地图出发。刚开始地图不需要太完美,很精细,因为一个不识路的人是没办法认路的,何况是指路、画地图,反正后面也要调整,可以随意一点。 + +我刚开始创建了一个叫 `JavaScript` 的索引页,里面用标题列了几项比较重要的内容,比如 OOP / DOM 之类的,然后在页面最上面列了几项常用的内容: +![](https://s2.loli.net/2022/03/06/ybuxoSJmQGKcAV3.png) + +之后会以这一页内容为目录索引,不断补充和修改,构建自己的知识结构 + +### Step2-写课堂笔记 + +首先需要创建一个空白页面。我用 Obsidian 里自带的插件 `ZK 卡片 ` 创建,可以自动生成时间戳标题,这个功能可以在设置里打开: + +![](https://s2.loli.net/2022/03/06/ZXVqaIcS4xy6Evs.png) + +然后点击左边功能栏就可以创建并打开了 + +![](https://s2.loli.net/2022/03/06/VQZpj96GbzxhO7i.png) + +创建好之后,把这页笔记添加到索引页中,方便后面查找: + +![](https://s2.loli.net/2022/03/06/Xr9CR7dfekTts5M.png) + +然后就可以写课堂笔记了,如果需要在笔记中插入图片,可以使用 Image Auto Upload 这个插件,配合 PicGo 客户端,可以在 Obsidian 里上传图片到图床,非常好用,直接粘贴图片到页面就可以了,具体可以看插件描述。 + +![](https://s2.loli.net/2022/03/06/V8SgsyWqONeYwjB.png) + +记笔记的过程没什么特别的,如果提到了一些我还不了解,以后还想深入的话题,我会用 `[[ ]]` 先标出来, 后面整理笔记的时候看到会留意下。 + +### Step3-重组笔记 + +做完笔记后,将笔记重组。 + +#### 布局 + +先打开三个窗口,布局如下: + +![](https://s2.loli.net/2022/03/06/QwSIsWMHUlbZ71r.png) + +其中课堂笔记和索引页面需要锁定,这样新打开的窗口就会一直在右下角那个地方,将在这个区域编辑笔记内容。 + +#### 结构编辑 + +浏览课堂笔记大纲,看下本节课的知识点应该放在索引里的哪里,知识点之间应该是怎样的关系,在索引里用 `[[]]` 都列出来,简而言之就是画思维导图。我的一个比较粗糙的整理: + +![](https://s2.loli.net/2022/03/06/bHa4rFvRIB58jeT.png) + +这样就可以比较直观地看到哪些内容整理了,哪些没有整理。 + +#### 拆分笔记 + +然后就可以将左边的笔记拆分整合到右边的索引中了,按住快捷键 `CMD`,鼠标点击索引里的链接打开新页面,然后在右下部分复制整理。写完一个知识点后可以不用关闭窗口,按住 `CMD` 然后点击链接,继续在右下窗口编辑笔记。 + +看到索引浅色链接(没有创建页面的)都没了,就基本整理完了,可以再看看课程笔记里有没有要补充的。 + +然后就整理完啦!之后继续补充索引页面就好了……^\_^ + + diff --git a/urara/2022-03-09-caesar-cipher/+page.md b/urara/2022-03-09-caesar-cipher/+page.md new file mode 100644 index 00000000..e4b07a61 --- /dev/null +++ b/urara/2022-03-09-caesar-cipher/+page.md @@ -0,0 +1,116 @@ +--- +title: JavaScript · Caesar Cipher 凯撒加密 +summary: 用JavaScrpit编码实现凯撒加密算法 +created: 2022-03-08T16:01:08.850Z +tags: + - JavaScript +categories: + - JavaScript +lastmod: 2022-04-07T07:20:47.694Z +--- + +## 题目 + +来源:[操作字符串对象 | 百度前端技术学园](http://ife.baidu.com/javascript/string.html#%E5%AD%97%E7%AC%A6%E4%B8%B2) + +编码实现凯撒加密算法,根据输入的偏移量,实现对字符串的加密和解密. + +恺撒加密(Caesar cipher),是一种最简单且最广为人知的替换加密技术。明文中的所有字母都在字母表上向后(或向前)按照一个固定数目进行偏移后被替换成密文。 + +例如,当偏移量是 3 的时候,所有的字母 A 将被替换成 D,B 变成 E,以此类推。 + +**需求说明** + +- 点击加密按钮,根据用户输入的偏移量,对明文进行加密,加密后的为密文,显示在密文输入框中 +- 点击解密按钮,根据用户输入的偏移量,对密文进行加密,解密出来的为明文,显示在明文输入框中 + +## 解法 + +- `string.replace` 替换数字 +- 用`.charCodeAt()` 获取字母编码 +- 正则表达式`/[A-Za-z]/g`选择字母 +- 偏移量超过范围的,往反方向偏移 +- 结果验证:[凯撒密码加密/解密 - 一个工具箱 ](http://www.atoolbox.net/Tool.php?Id=778) + +### HTML + +```html + + +
+ +``` + +### JS + +```js +let offsetInput = document.querySelector('input[name=offset]') +let plain = document.querySelector('input[name=plain') +let enc = document.querySelector('input[name=enc]') + +// 加密 +function encrypt() { + let offset = Number(offsetInput.value) + function conver(s) { + let charCode = s.charCodeAt(0) + // 替换大写字母 A-Z:65-90 + if (charCode <= 90 && charCode >= 65) { + return String.fromCharCode(charCode + offset < 90 ? charCode + offset : charCode - offset) + } else { + //替换小写字母 a-z:97-122 + return String.fromCharCode(charCode + offset < 122 ? charCode + offset : charCode - offset) + } + } + enc.value = plain.value.replace(/[A-Za-z]/g, conver) + + // 替换大写字母 A-Z:65-90 + // function transUpper(s) { + // let charCode = s.charCodeAt(); + // return String.fromCharCode( + // charCode + offset <= 90 ? charCode + offset : charCode - offset + // ); + // } + + // //替换小写字母 a-z:97-122 + // function transLower(s) { + // let charCode = s.charCodeAt(); + // return String.fromCharCode( + // charCode + offset <= 122 ? charCode + offset : charCode - offset + // ); + // } + // let encUpper = plain.replace(/[A-Z]/g, transUpper); + // enc.value = encUpper.replace(/[a-z]/g, transLower); +} + +// 解密 +function decrypt() { + let offset = Number(offsetInput.value) + function conver(s) { + let charCode = s.charCodeAt(0) + // 替换大写字母 A-Z:65-90 + if (charCode <= 90 && charCode >= 65) { + return String.fromCharCode(charCode - offset < 65 ? charCode + offset : charCode - offset) + } else { + //替换小写字母 a-z:97-122 + return String.fromCharCode(charCode - offset < 97 ? charCode + offset : charCode - offset) + } + } + plain.value = enc.value.replace(/[A-Za-z]/g, conver) +} +``` + +## 参考 + +- [凯撒密码 javascript](https://blog.csdn.net/dikanjiang6340/article/details/101264748?utm_relevant_index=1) +- [Caesar Cipher in Javascript - Stack Overflow](https://stackoverflow.com/questions/44232645/caesar-cipher-in-javascript?newreg=0a8ff4c05c484b01a7df20821475fb15) diff --git a/urara/2022-03-09-css-tab/+page.md b/urara/2022-03-09-css-tab/+page.md new file mode 100644 index 00000000..d3b72ed4 --- /dev/null +++ b/urara/2022-03-09-css-tab/+page.md @@ -0,0 +1,101 @@ +--- +title: CSS · Tab选项卡 +summary: 一个纯 CSS 实现的 Tab 选项卡 +created: 2022-03-09T07:42:25.299Z +tags: + - CSS +categories: + - CSS +lastmod: 2022-04-07T07:40:02.371Z +--- + +一个纯 CSS 实现的 Tab 选项卡 + +## 原理 + +> 通过隐藏的 `input` 和与之关联的 [label](https://so.csdn.net/so/search?q=label&spm=1001.2101.3001.7020) 点击 `label` 触发 `input` 的 `checked` 状态触发的,再配合使用元素状态的伪类 `:checked `样式就可以实现不同状态的切换,中间的过度效果还可以配合 CSS3 的 `transition`过度效果实现 [^1]。 + +## 代码 + +- `input` 的`name` 都一样,`id`不同 + +### HTML + +```html +
+ + + + + + + + + + + + +
+

THIS IS TAB1 CONTENT

+

Notice the gap between the content and tab after applying background cololr

+
+
+

THIS IS TAB2 CONTENT

+

Notice the gap between the content and tab after applying background cololr

+
+
+

THIS IS TAB3 CONTENT

+

Notice the gap between the content and tab after applying background cololr

+
+
+``` + +### CSS + +```css +/* 隐藏input和tab内容 */ +.tab-frame input, +.tab-content { + display: none; +} + +/* 导航栏样式:未选中时 */ +.tab-frame label { + color: #555; + padding: 10px 20px; + border-bottom: 1px solid #555; + cursor: pointer; + float: left; +} + +/* 导航栏样式:选中时 */ +.tab-frame input:checked + label { + color: #0f71aa; + border: 1px solid #555; + border-bottom: none; + border-radius: 4px 4px 0px 0px; + cursor: default; +} + +/* Tab内容样式 */ +.tab-frame .tab-content { + color: #0f71aa; + font-size: 1.5rem; + font-weight: bold; + padding-top: 40px; + clear: left; +} + +/* 点击的时候显示tab内容,即input checked的时候显示label*/ +.tab-frame input:nth-of-type(1):checked ~ .tab-content:nth-of-type(1), +.tab-frame input:nth-of-type(2):checked ~ .tab-content:nth-of-type(2), +.tab-frame input:nth-of-type(3):checked ~ .tab-content:nth-of-type(3) { + display: block; +} +``` + +## 参考 + +Demo:[Tabs CSS & HTML, no JS & Jquery](https://codepen.io/llgruff/pen/ZGBxOa) + +[^1]: [CSS tab 选项卡 (标签页) 切换](https://blog.csdn.net/baiding1123/article/details/51889201) diff --git a/urara/2022-03-09-typewriter/+page.md b/urara/2022-03-09-typewriter/+page.md new file mode 100644 index 00000000..4e4d3d33 --- /dev/null +++ b/urara/2022-03-09-typewriter/+page.md @@ -0,0 +1,59 @@ +--- +title: JavaScript · 打字机效果生成器 +summary: 用 JavaScript 实现网页打字机效果 +created: 2022-03-08T16:19:05.137Z +tags: + - JavaScript +categories: + - JavaScript +lastmod: 2022-04-07T07:40:27.758Z +--- + +## 题目 + +来源:[百度前端学院](http://ife.baidu.com/javascript/string.html#%E4%BB%BB%E5%8A%A1%E5%9B%9B) + +参照 [打字机效果 DEMO (opens new window)](https://b.bdstatic.com/searchbox/icms/searchbox/img/%E6%89%93%E5%AD%97%E6%9C%BA.gif),实现一个打字机效果生成器 + +**需求说明** + +- 在输入框中输入需要实现打字机效果的文本 +- 实现原理使用定时器间隔一段时间递增地截取字符串的长度 +- 点击 button 实现打字机效果的生成,将文本输出到 id 为 showText 的标签中 + +```html + + + +

+ +``` + +## 解法 + +```html + + + +

+ +``` + +## 参考 + +[How TO - Typing Effect](https://www.w3schools.com/howto/howto_js_typewriter.asp) diff --git a/urara/2022-03-10-forty/+page.md b/urara/2022-03-10-forty/+page.md new file mode 100644 index 00000000..d97b77d1 --- /dev/null +++ b/urara/2022-03-10-forty/+page.md @@ -0,0 +1,30 @@ +--- +title: Forty页面仿写 +summary: 完成 HTML、CSS 代码编写,暂无 JavaScript +created: 2022-03-10T08:38:17.227Z +preview: '' +draft: '' +tags: + - CSS + - HTML +lastmod: 2022-04-07T07:39:48.473Z +--- + +## 题目 + +来源:[百度前端学院|浮动实战任务](http://ife.baidu.com/csspart/floatTask.html) + +通过 HTML 及 CSS 参考[示例图](https://b.bdstatic.com/searchbox/icms/searchbox/img/task1.png)实现页面开发,要求实现效果与示例图基本一致 + +- 页面宽度固定(定宽), 请应用 CSS 浮动以及前几天所学的 CSS 样式来完成页面效果 +- 只需要完成 HTML、CSS 代码编写,不需要写 JavaScript + +## 示例图 + +![](https://s2.loli.net/2022/03/10/V9ZpjQYFvxEDGXJ.jpg) + +## Demo + +https://forty-seviche.netlify.app/ + +耗时:4 小时(还没有做自适应等很多东西……╮( ̄ ▽  ̄"")╭ diff --git a/urara/2022-03-11-miniflux-to-pocket/+page.md b/urara/2022-03-11-miniflux-to-pocket/+page.md new file mode 100644 index 00000000..c9eaaebc --- /dev/null +++ b/urara/2022-03-11-miniflux-to-pocket/+page.md @@ -0,0 +1,110 @@ +--- +title: Miniflux · 保存文章到 Pocket 以及 RSS +summary: 将 Miniflux 上的文章到保存到 Pocket/Instapaper,以及 RSS 相关文章和资源 +created: 2022-03-10T16:24:38.663Z +tags: + - RSS + - Miniflux +lastmod: 2022-04-07T07:38:52.406Z +--- + +将 Miniflux 上的文章到保存到 Pocket/Instapaper,以及 RSS 相关文章和资源 + +Miniflux 文档: [Integration with External Services](https://miniflux.app/docs/services.html) + +## 1. 创建 Pocket Application + +在 [这里](https://getpocket.com/developer/apps/new) 创建一个 Pocket 应用,以获取 Consumer Key + +我的设置如下: + +![](https://s2.loli.net/2022/02/24/yfXLehkWrisS9Hb.png) + +## 2. 获取 Consumer Key 用户密钥 + +在**My Apps**下面找到刚刚创建的应用,复制 Consumer Key: + +![](https://s2.loli.net/2022/02/24/vO4jyhTfBaHRZ6n.png) + +在 Miniflux 后台,设置 → 集成 → Pocket → **Pocket 用户密钥**(第一栏)中 填入刚刚复制的 Consumer key + +## 3. 获取 Access Token 访问密钥 + +填好后,通过通过点击下面的 **连接您的 Pocket 账户** 自动获取 Access Token(访问密钥): + +![](https://s2.loli.net/2022/03/10/tzYeCNksmRaBIFj.png) + +点击链接后按 **授权**。 +![](https://s2.loli.net/2022/03/11/sZOU8tBpjAJW3ol.png) + +这里可能会跳到 `http://localhost/integration/pocket/callback` 然后就无法访问页面了,解决办法很简单,把 `localhost` 改为你的服务器 ip 端口或者 miniflux 所在域名即可,如 `http://miniflux.com/integration/pocket/callback`,按回车会跳回到 miniflux 设置页面。 + +出现这个提醒就连接成功了: +![](https://s2.loli.net/2022/03/11/ktoi3lOGjpQHP9B.png) + +然后就可以点击文章页面的**保存**测试看看。 +![](https://s2.loli.net/2022/03/11/uCBj6IAWxN149Xo.png) + +## 其他 + +### 1.为博客添加 Pocket 收藏按钮 + +在 [此处](https://getpocket.com/publisher/button)复制需要的 Pocket 收藏按钮样式,添加到主题的 layout 里面(具体要看不同主题的设置,wordpress 似乎有内置这功能,我不确定,有三种效果。 + +### 2.用 Fever 同步到 Reeder + +1. 在 Miniflux 中创建 Fever 账户和密码 +2. 在 Reeder 中添加 Fever 账号,其中: + +- server:`https://miniflux 的网址/fever` +- email:Fever 用户名 +- password:就是 Fever 密码 + +### 3.连接到 Instapaper + +官网:[Instapaper](https://www.instapaper.com/) + +用户名为 Instapaper 的登录邮箱,设置好更新下就可以了~ + +## RSS 相关内容 + +来都来了,整理一下最近看过的相关内容,因为隐私问题,长毛象上的嘟文暂时不贴(除了我自己的 + +### 1. Miniflux 搭建 + +- [RSS | RSSHub 搭配 Miniflux,实现订阅自由](https://mantyke.icu/2021/rsshub-miniflux/) +- [Miniflux | 利用 Docker-compose 搭建 RSS 阅读器](https://blog.tantalum.life/posts/build-miniflux-in-docker/#%E6%90%AD%E5%BB%BA%E8%BF%87%E7%A8%8B) +- [Miniflux:自建私有 RSS 订阅工具,可多用户使用](https://www.moerats.com/archives/385/comment-page-1) +- [简易 RSS 阅读器 | Miniflux 2 安装教程](https://www.moewah.com/archives/3157.html) + +### 2. 其他选择 + +- [RSS 服务对比评测](https://type.cyhsu.xyz/2018/05/rss-aggregators-review-2018/) +- [找不到满意的 RSS 服务?你可以自己搭建一个](https://sspai.com/post/57498) +- [用 Tiny Tiny RSS 自建 RSS 服务](https://type.cyhsu.xyz/2017/10/use-ttrss-to-build-a-self-hosted-rss-service/) +- [(另一篇)Tiny Tiny RSS 教程](https://sspai.com/post/42787) +- [(2021) 自建 RSS 阅读器 Tiny Tiny RSS 教程,docker 安装 Awesome TTRSS](https://blog.naibabiji.com/tutorial/tiny-tiny-rss.html) +- [创建一个私有的 rss 订阅工具 Wallabag](https://www.vpslala.com/t/762) + +### 3. RSS 生成 + +- [可能是目前最全的 RSS 源,微信公众号也有!](https://mp.weixin.qq.com/s/K00wWvlAJu4KLbxru9-bXQ) +- [Feed Creator](http://createfeed.fivefilters.org/) +- [根据页面 HTML 生成 RSS 链接](https://social.datalabour.com/@nonsense/107824299041894067) +- [你的专属 RSS 源:在自己的 VPS 上安装 RSSHub](https://sspai.com/post/66451) +- [8 个好用的 WordPress RSS Feed 插件](https://www.wpdaxue.com/wordpress-rss-feed-plugins.html) + +### 4. 看什么 + +- [分享你认为值得订阅的内容 | Notion 小活动 Vol.13](https://www.notion.so/cnotion/Notion-Vol-13-89e51bdb621a4e009e7ec60d1cc58c2f#16368490755248a28efa4c229dc56321) +- [产品沉思录|优质订阅源](https://www.notion.so/ca290ef313804bae8584804440548c80?v=4470668a5078437f816b0273ed042ebf) +- [中文 Newsletter 导航](https://www.notion.so/kfang/Newsletter-68ee46c0a4574f659fb8a873ead438c6) +- [中文独立博客列表](https://github.com/timqian/chinese-independent-blogs) + +#### 5. 关于 RSS + +- [论 RSS 的「复兴」](https://type.cyhsu.xyz/2018/04/on-the-so-called-revival-of-rss/) +- [关于 RSS 协议的一些迷思](https://blog.dylanwu.space/2021/11/30/myth-of-rss.html) +- [是 RSS 复兴的时候了(翻译 )](https://www.fengkx.top/post/translation-of-RSS-revival/) +- [RSS3](https://rss3.io/) +- [拆解 RSS3— 是否可以真正的开启 Web3 社交?](https://mp.weixin.qq.com/s/CYmXvEHSd7idhDHtEe3ehw) diff --git a/urara/2022-03-29-12px/+page.md b/urara/2022-03-29-12px/+page.md new file mode 100644 index 00000000..08c2bd02 --- /dev/null +++ b/urara/2022-03-29-12px/+page.md @@ -0,0 +1,52 @@ +--- +title: CSS · 解决 Chrome 中小于12px的字体不显示的问题 +lastmod: 2022-04-07T07:36:23.629Z +summary: 先用scale总体缩小再补上减少的宽度 +created: 2022-03-29T13:46:29.228Z +tags: + - CSS + - CSS Trick +categories: + - CSS +toc: false +--- + +如设置字体大小为 10.2px + +### HTML + +```html +

+ I am a frontend developer with a particular interest in making things simple and automating daily tasks. I try to keep up with + security and best practices, and am always looking for new things to learn. +

+``` + +### CSS + +```css +p { + color: #dcdcdc; + + /*缩小基准大小,也就是缩小后的字体应该是 10.2px=12px*0.85*/ + font-size: 12px; + + /* 缩小比例 10.2px/12px=0.85 */ + transform: scale(0.85); + + /*设置缩放中心*/ + transform-origin: 0 0; + + /*(1-0.85)+1,补上缩小的宽度,这里可以按视觉效果调整一点*/ + width: 118%; + + /*兼容IE*/ + *font-size: 10.2px; +} +``` + +参考: + +- [css 小于 12px 字体\_MAIMIHO 的博客-CSDN 博客](https://blog.csdn.net/maimiho/article/details/121548769) +- [css 设置字体小于 12px 的方法 - 代码先锋网](https://www.codeleading.com/article/46263149244/) +- [Set CSS font-size less than 12px in webkit browser](https://codepen.io/mjj2000/pen/AYEqwJ) diff --git a/urara/2022-05-07-vps-init/+page.md b/urara/2022-05-07-vps-init/+page.md new file mode 100644 index 00000000..a2d4de09 --- /dev/null +++ b/urara/2022-05-07-vps-init/+page.md @@ -0,0 +1,363 @@ +--- +title: VPS 安全初始化 +created: 2022-05-06 +summary: 上次 VPS 被别人暴力破解了,一哭二闹三重装之后,有了本文 +tags: + - VPS + - Self hosted +--- + +**前情提要:** + +前段时间我所购买的 VPS 服务商 Contabo 发邮件来说,我用 VPS 攻击了其他的服务器,让我快点停止这种行为,要是不改就罚我的钱,但是我并没有在上面装什么奇怪的东西,就只装了一个聊胜于无的 WordPress,手足无措之余在 Mastodon 哀嚎了一下,得到了很多热心网友的帮助,才发现原来我一直在裸奔使用 VPS,什么安全措施都没采取:( + +鉴于 VPS 上本来就没有什么东西,我决定重新初始化机子,本文是初始化的笔记,我的系统是 Ubuntu 20.04,文中提到的 ufw 是内置的,没有额外安装, 有些步骤上有所省略,最好对照着提到的参考文章看。 + +(再次感谢 Allen Zhong、糖喵、南狐、shrik3 等朋友的热心指导 o(≧v≦)o!) + +## 思路 + +下面这两点都是 Contabo 客服发给我的防护建议,用 Deepl 翻译了一下 + +### 日常防护 + +- 检查你的服务器是否有可疑的进程并删除它们(例如使用以下命令:ps aux| grep stealth) +- 检查错误日志,例如/var/log/apache2/error_log,找出是否有任何恶意脚本的错误信息或恶意软件下载的迹象。 +- 攻击者经常在以下目录中安装恶意软件。/tmp/ , /var/tmp/ - 请使用 find /tmp (find /var/tmp) 来检查隐藏的文件。 +- 扫描你的服务器以防止安装的 rootkits。 +- 运行一个防病毒软件,如 ClamAV 或 ClamWin。 + +### 安全检查 + +1. 保持定期备份。 +2. 保持你的整个系统一直是最新的,这意味着你必须定期安装使用的软件包和网络应用程序的更新和补丁。 +3. 安装并运行一个防病毒软件,如 ClamAV 或 ClamWin,以保持你的服务器不受恶意软件侵害。 +4. 设置一个防火墙,关闭所有你不需要的端口,并将 SSH 的 22 或 RDP 的 3389 等默认端口改为其他。 +5. 通过安装一个合适的软件,如 cPHulk 或 Fail2ban,阻止暴力攻击。 +6. 避免使用只在不安全的设置下工作的脚本。 +7. 不要点击电子邮件中的任何可疑附件或链接,或访问不安全的网站。 +8. 使用 SSH-Keys 而不是密码。 + +--- + +最后我将 VPS 里的内容全删了,从 0 出发,下面是具体的操作步骤: + +## 1. 创建新用户 + +参考: [VPS 建站新手上路 - YOLO](https://yolo.blue/vps-hosting-setup/) + +首先用 root 登陆,然后输入 adduser + 用户名 创建新用户,如添加用户`jack` + +```shell +adduser jack +``` + +接着输入两遍密码,其他信息可以按 Enter 留空 + +给这个用户 root 权限: + +```shell +sudo usermod -aG sudo jack +``` + +其他参考: [如何在 Ubuntu 上添加和删除用户 | myfreax](https://www.myfreax.com/how-to-add-and-delete-users-on-ubuntu-18-04/) + +## 2. 配置 SSH-keys + +参考: [给 VPS 配置 SSH 密钥免密登录 - P3TERX ZONE](https://p3terx.com/archives/configure-ssh-keyfree-login-for-vps.html) + +### 本地生成 SSH 密钥对 + +文中提到可以在远端 VPS 上,也可以在本地,这里我选择在本地生成。 + +打开终端,输入 `ssh-keygen` ,连续按四次 Enter (密码设置为空),如果出现了 `overwrite(y/n)?` 就说明之前就有生成了,你可以选择 `y` 重新生成一个,或者就用已有的这个 + +比如: + +```bash +root@p3ter:~# ssh-keygen # 输入命令,按 Enter 键 +Generating public/private rsa key pair. +Enter file in which to save the key (/root/.ssh/id_rsa): # 保存位置,默认就行,按 Enter 键 +Enter passphrase (empty for no passphrase): # 输入密钥密码,按 Enter 键。填写后每次都会要求输入密码,留空则实现无密码登录。 +Enter same passphrase again: # 再次输入密钥密码,按 Enter 键 +Your identification has been saved in /root/.ssh/id_rsa. +Your public key has been saved in /root/.ssh/id_rsa.pub. +The key fingerprint is: +SHA256:GYT9YqBV4gDIgzTYEWFs3oGZjp8FWXArBObfhPlPzIk root@p3ter +The key's randomart image is: ++---[RSA 2048]----+ +|*OO%+ .+o | +|*=@.+++o. | +| *o=.=.... | +|. +.B + +o. | +| . + E *S. | +| o o | +| . | +| | +| | ++----[SHA256]-----+ +``` + +出现那个神秘的矩形就是生成好了 + +### 安装公钥 + +在本地终端: + +```bash +ssh-copy-id -pport user@remote +``` + +`user` 为用户名,`remote` 为 IP 地址,`port` 为端口号。 + +也可以不加端口号: + +```bash +ssh-copy-id user@remote +``` + +然后按要求输入密码,如果是用 root 登陆的,就是用的初始密码,如果是用上面设置的新用户,那就跟之前设置的用户密码一样 + +### 修改权限 + +**登入 VPS **后,在远程终端输入: + +```bash +chmod 600 .ssh/authorized_keys +``` + +### 修改 sshd 配置文件 + +打开配置文件: + +```bash +nano /etc/ssh/sshd_config +``` + +找到下面这两行,并改成这样: + +```bash +PermitRootLogin no +AllowUsers username #如果没有这一行就手动添加 +RSAAuthentication yes #这一行我找不到就没有配置 +PubkeyAuthentication yes +``` + +记得 username 要换成自己设置的名字,也就是上面配置的 jack + +修改完按 Ctrl+o 保存,Enter 确认,Ctrl+X 退出编辑 + +重启 ssh 服务 + +```bash +systemctl reload sshd +``` + +或者 + +```bash +service sshd restart +``` + +### 禁用密码登陆和改端口 + +设置好后,试试看能不能用 ssh 登陆,如果可以,再 `sudo nano /etc/ssh/sshd_config` 修改配置,禁用密码登陆: + +```bash +PasswordAuthentication no +``` + +### 修改默认登陆端口 + +然后改默认登陆端口[^1],应该什么数都可以吧,什么 8080,9080,8888,3141…… + +找到 `Port 22` 这行,在下面加你要开的口 + +```bash + Port 22 + Port 8888 +``` + +加完了之后重启 + +```bash +sudo service sshd restart +``` + +打开防火墙并给你设置的端口放行 + +```bash +sudo ufw allow 8888 +sudo ufw enable +``` + +`sudo ufw status` 查看防火墙状态,比如: + +```bash +Status: active + +To Action From +-- ------ ---- +8888 ALLOW Anywhere +8888 (v6) ALLOW Anywhere (v6) +``` + +然后重新连接一下 VPS,用设置好的端口登陆看看,如果没问题的话重新 `sudo nano /etc/ssh/sshd_config` ,注释掉 `Port 22` 那一行 + +## 3. 安装 ClamAV + +参考: + +- [如何在 Ubuntu 20.04 LTS 上安装 ClamAV - LinuxCapable](https://www.linuxcapable.com/zh-CN/%E5%A6%82%E4%BD%95%E5%9C%A8-ubuntu-20-04-%E4%B8%8A%E5%AE%89%E8%A3%85%E5%92%8C%E4%BD%BF%E7%94%A8-clamav/) +- [How to Install and Use ClamAV on Ubuntu 20.04](https://linoxide.com/how-to-install-and-use-clamav-on-ubuntu-20-04/) + +### 安装 + +```bash +sudo apt update +sudo apt install clamav clamav-daemon -y +``` + +### 更新病毒数据库 + +先停止 `clamav-freshclam` 服务 + +```bash +sudo systemctl stop clamav-freshclam +``` + +执行更新: + +```bash +sudo freshclam +``` + +启动`clamav-freshclam` 服务 + +```bash +sudo systemctl start clamav-freshclam +``` + +### 开机启动 + +```bash +sudo systemctl is-enabled clamav-freshclam +``` + +### 下载 ClamAV 数据库 + +先关掉 clamav-freshclam 再下载 + +```bash +sudo systemctl stop clamav-freshclam +sudo freshclam +``` + +查看 clamav 的目录和文件的日期 + +```bash +ls /var/lib/clamav/ +``` + +### 限制 Clamscan CPU 使用率 + +**`nice`**:降低 clamscan 的优先级(限制相对 cpu 时间)。 + +```bash +sudo nice -n 15 clamscan +``` + +**`cpulimit`**:限制绝对的 CPU 时间。 +安装 cpulimit + +```bash +sudo apt-get install cpulimit +``` + +使用 cpulimit 来限制 clamscan: + +```bash +cpulimit -z -e clamscan -l 20 & clamscan -ir / +``` + +### 常见 CLI + +```bash +clamscan /home/filename.docx #扫描特定目录或文件 +clamscan --no-summary /home/ #扫描结束时不显示摘要 +clamscan -i / #打印受感染的文件 +clamscan --bell -i /home #警惕病毒检测 +clamscan -r --remove /home/USER #删除受感染的文件 +``` + +### ClamAV 返回码 + +- 0:未发现病毒。 +- 1:发现病毒。 +- 2:发生了一些错误。 + +## 4. 安装 Fail2ban + +安装 fail2ban 以阻止重复登录尝试 + +参考:[准备你的机器 - Mastodon documentation](https://docs.joinmastodon.org/zh-cn/admin/prerequisites/) + +### 准备 + +更新软件包: + +```bash +sudo apt update +sudo apt upgrade -y +``` + +### 安装 + +参考:[如何在 Ubuntu 20.04 上安装和配置 Fail2ban](https://www.myfreax.com/install-configure-fail2ban-on-ubuntu-20-04/) + +```bash +sudo apt install fail2ban +``` + +安装完后将自动启动,可以用`sudo systemctl status fail2ban` 查看运行状态 + +### 修改配置: + +打开`/etc/fail2ban/jail.local`: + +```bash +sudo nano /etc/fail2ban/jail.local +``` + +写入下面的内容,修改邮箱,如果端口改了,也要记得相应修改 + +```text +[DEFAULT] +destemail = your@email.here +sendername = Fail2Ban + +[sshd] +enabled = true +port = 22 + +[sshd-ddos] +enabled = true +port = 22 +``` + +重启 fail2ban: + +```bash +sudo systemctl restart fail2ban +``` + +## 5. SSL 证书相关 + +还没弄明白怎么回事,待更 + +参考: + +- 【[杂谈】防止 SSL 证书泄露你的源站 IP](https://luotianyi.vc/5056.html) +- [WEB 服务器安全指南 - 防止源站 IP 暴露](https://blog.hicasper.com/post/114.html) + +[^1]: [更改 VPS 的默认 SSH 端口 22 – 托尼的博客](https://zhucaidan.xyz/2019/12/281/) diff --git a/urara/2022-05-09-copywithin/+page.md b/urara/2022-05-09-copywithin/+page.md new file mode 100644 index 00000000..4aa56444 --- /dev/null +++ b/urara/2022-05-09-copywithin/+page.md @@ -0,0 +1,69 @@ +--- +title: JavaScript · 数组中的copyWithin方法 +created: 2022-05-08T17:13:47.671Z +summary: 一种数组内元素复制的方法 +tags: + - JavaScript +lastmod: 2022-05-09T02:27:47.533Z +--- + +> `copyWithin()` 方法浅复制数组的一部分到同一数组中的另一个位置,并返回它,不会改变原数组的长度 +> +> —— MDN + +## 简介 + +以下部分内容来自 [MDN](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin) + +### 语法: + +```js + arr.copyWithin(target[, start[, end]]) +``` + +## 参数 + +### target + +0 为基底的索引,复制序列到该位置。 + +如果是负数,`target`  将从末尾开始计算。如果 `target` 大于等于 `arr.length`,将会不发生拷贝。如果 `target` 在 `start` 之后,复制的序列将被修改以符合 `arr.length`。 + +### start + +0 为基底的索引,开始复制元素的起始位置。 + +如果是负数,`start`  将从末尾开始计算。如果  `start`  被忽略,`copyWithin`  将会从 0 开始复制。 + +### end + +0 为基底的索引,开始复制元素的结束位置。 + +`copyWithin`  将**会拷贝到该位置,但不包括 `end` 这个位置的元素**。 + +如果是负数, `end`  将从末尾开始计算。如果 `end` 被忽略,`copyWithin` 方法将会一直复制至数组结尾(默认为 `arr.length`)。 + +## 例子 + +### 源码 + +```js +const array1 = ['a', 'b', 'c', 'd', 'e'] + +// copy to index 0 the element at index 3 +console.log(array1.copyWithin(0, 3, 4)) +// expected output: Array ["d", "b", "c", "d", "e"] + +// copy to index 1 all elements from index 3 to the end +console.log(array1.copyWithin(1, 3)) +// expected output: Array ["d", "d", "e", "d", "e"] +``` + +### 可视化 + + + +上图将 target 位置用红色的部分表示,被复制的元素为蓝色。 + +1. `a = array1[0]` ,所在位置是将要被替换的 target 位置。`d = array1[3]`是复制的起始元素,复制结束在`array1[4]`之前。复制后`a`的位置被 `d`所取代。 +2. `b = array1[1]` ,所在位置是将要被替换的 target 位置,`d = array1[3]`是复制的起始元素,复制没有指定结束位置,所以一直复制到数组末尾。复制后`a`的位置被 `'d','e'`所取代。 diff --git a/urara/2022-05-23-win-sql/+page.md b/urara/2022-05-23-win-sql/+page.md new file mode 100644 index 00000000..7ac88b9b --- /dev/null +++ b/urara/2022-05-23-win-sql/+page.md @@ -0,0 +1,77 @@ +--- +title: SQL · 在 Windows 10 上安装 sqlite +created: 2022-05-23 +summary: 写给计算机小白的 sqlite 安装笔记 +tags: + - SQL +--- + +参考: [Site Unreachable](https://www.runoob.com/sqlite/sqlite-installation.html) + +## 1. 下载二进制文件 + +- 请访问  [SQLite 下载页面](http://www.sqlite.org/download.html),从 Windows 区下载预编译的二进制文件。 +- 您需要下载  **sqlite-tools-win32-\*.zip**  和  **sqlite-dll-win32-\*.zip**  压缩文件。 + +![](/2022-05-23-win-sql/2.png) + +## 2. 创建安装文件夹 + +- 在 C 盘内创建文件夹 sqlite(在别的地方应该也可以?),并在此文件夹下解压上面两个压缩文件,将得到 sqlite3.def、sqlite3.dll 和 sqlite3.exe 文件。如: + ![](/2022-05-23-win-sql/DMirANRL4FYs8Xx.png) + +## 3. 添加环境变量 + +参考:[sqlite 在 windows 下载安装,配置环境变量](https://blog.csdn.net/gymaisyl/article/details/108073278) + +首先,打开控制面板,如果找不到的话,直接搜索,例如: +![](/2022-05-23-win-sql/Bl1JjI2A6HnfQVZ.png) + +然后点击**系统与安全**,再点击 **系统** +![](/2022-05-23-win-sql/q7RaUdAYHz2lpC3.png) +![](/2022-05-23-win-sql/V87O1wdLscPbvTC.png) + +在新窗口中点击**高级系统设置** -> **环境变量** +![](/2022-05-23-win-sql/HSD6iy9nUxCEkcQ.png) + +![](/2022-05-23-win-sql/SnJePah46I7CyGF.png) + +如上图所示,在蓝色区域新建一个环境变量,此处填写一开始创建 sqlite 文件的路径,比如这里就是`C:\sqlite` + +## 4. 命令提示符中查看 sqlite3 版本 + +**什么是命令提示符?** + +> 命令提示符是大多数 Windows [操作系统中](https://zhcn.eyewated.com/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/)可用的[命令行解释器](https://zhcn.eyewated.com/%E4%BB%80%E4%B9%88%E6%98%AF%E5%91%BD%E4%BB%A4%E8%A1%8C%E8%A7%A3%E9%87%8A%E5%99%A8%EF%BC%9F/)应用程序。 +> +> 命令提示符用于执行输入的[命令](https://zhcn.eyewated.com/%E4%BB%80%E4%B9%88%E6%98%AF%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%91%BD%E4%BB%A4%EF%BC%9F/) 。 大多数这些命令用于通过脚本和[批处理文件](https://zhcn.eyewated.com/%E4%BB%80%E4%B9%88%E6%98%AFbat%E6%96%87%E4%BB%B6%EF%BC%9F/)自动执行任务,执行高级管理功能以及排除和解决某些类型的 Windows 问题。 +> +> 命令提示符被正式称为*Windows 命令处理器,*但有时也被称为*命令外壳程序*或*cmd 提示符* ,甚至称其为文件名*cmd.exe* 。 +> ——[命令提示符(它是什么以及如何使用它)](https://zhcn.eyewated.com/%E5%91%BD%E4%BB%A4%E6%8F%90%E7%A4%BA%E7%AC%A6%EF%BC%9A%E5%AE%83%E6%98%AF%E4%BB%80%E4%B9%88%E4%BB%A5%E5%8F%8A%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8%E5%AE%83/) + +我的理解就是用代码的方式操作电脑系统 + +**如何打开命令提示符:** +![](/2022-05-23-win-sql/oL7n6rta35UAODl.png) + +打开后输入`sqlite3` ,出现下面的文字就是安装成功了 +![](/2022-05-23-win-sql/qNgBIvzLQJX126b.png) + +## 常用命令行 + +- 需要在文件夹里运行 +- `cd` 的时候按 tab 可以自动填充文件名 (VS Code 里面按 command) + +| 命令 | 功能 | +| ---------------------- | ------------------------------------------------------------------------------------------- | +| `ls`(win 用 `dir`) | 展示当前文件夹文件 | +| `cd` | 改变当前文件夹(change directory) 按 tab 可以自动填充 | +| `cd..` | 去到上个层级的文件夹 | +| `clear` | 清除命令行记录 | +| `mkdir` | 创建新文件夹(make directory) | +| `touch`(win 用 `edit`) | 创建新文件(可以一次性创建多个) | +| `mv` | 移动文件,第一个参数是要移动的文件,第二个是目的地,如 `mv index.html ../` 为移动到上一层级 | +| `rmdir` | 删除空文件夹(remove directory) | +| `rm -R` | 删除文件夹(R-recursively) | +| `pwd` | 当前所在位置 | +| `rm`(win 用 `del`) | 删除文件 | diff --git a/urara/2022-05-25-git/+page.md b/urara/2022-05-25-git/+page.md new file mode 100644 index 00000000..84f0a86a --- /dev/null +++ b/urara/2022-05-25-git/+page.md @@ -0,0 +1,92 @@ +--- +title: Git · 常用操作笔记 +created: 2022-05-25 +summary: 每次更新博客进行的操作以及常见错误处理 +tags: + - Git +--- + +**资料:** + +- [GIT CHEAT SHEET](https://education.github.com/git-cheat-sheet-education.pdf) +- [45 个 Git 经典操作场景,专治不会合代码](https://mp.weixin.qq.com/s/BzdgZXyM1UaNCUCXySL9Rw) +- [版本控制(Git) - 计算机教育中缺失的一课](https://missing-semester-cn.github.io/2020/version-control/) +- [战壕里面的 Git(Git In The Trenches)](http://cbx33.github.io/gitt/intro.html) + +## 每次更新博客进行的操作 + +### 1. 追踪所有文件 + +(除了 gitignore 里面的),也可以单独加 + +`git add -A` + +### 2. 提交上传信息 + +`git commit -m '一些信息,如fixed something etc'` + +### 3. push 到 Github + +`git push origin main` + +等待一会儿就好了,如果不行,换个网或者关掉 VPN 看看 + +## 常用 Git 操作 + +- `.gitignore`: 放不想传到 git repo 的文件/文件夹 +- 当内容改动很多的时候,最好开一个 branch +- VSCode 文件后面的字母: + - U:untrack + - M: modified + - A : on track +- 一般不在`main` 或`master` 修改代码,而是开一个 branch,确定好后再 merge +- 下载叫做 pull,上传是 push + +| 命令 | 作用 | +| :------------------------------------------------------------- | -------------------------------------------------- | +| `git config --global user.name "名字"` | 设置全局用户名 | +| `git config --global user.email "邮箱"` | 设置全局邮箱 | +| `git init` | 初始化仓库 | +| `git add -A` | 追踪所有文件(除了.gitignore里的),也可以单独添加 | +| `git commit -m "提交信息"` | 提交更改,-m 后跟提交信息 | +| `git status` | 查看仓库状态 | +| `git log` | 查看提交日志,按 Q 退出 | +| `git reset --hard ` | 回到特定版本 | +| `git reset --hard HEAD^` | 返回上一次改动(还没有commit) | +| `git branch` | 列出所有分支,按 Q 退出 | +| `git branch ` | 创建新分支 | +| `git merge ` | 将指定分支合并到当前分支 | +| `git checkout -b ` | 创建新分支并切换到该分支 | +| `git checkout ` | 切换到指定分支 | +| `git remote add origin https://github.com/username/repo.git` | 添加远程仓库 | +| `git pull` | 从远程仓库拉取更新 | +| `git push origin ` | 推送指定分支到远程仓库 | +| `git config --global push.default current` | 设置推送默认行为为推送当前分支到同名远程分支 [^1] | +| `git commit --amend --author="Name "` | 修改最近一次提交的作者信息 | +| `git config --global push.autoSetupRemote true` | 自动设置远程跟踪分支 | +| `git config --global http.proxy http://proxy.example.com:8080` | 设置全局 HTTP 代理[^2] | + +## 常见问题 + +下面是一些我看过的文章 + +### 版本回滚 + +- [项目中 git 怎么回退到之前的版本 & git 放弃本地修改,强制拉取更新](https://mp.weixin.qq.com/s/MCtCQg7rcokf6IrZVINF4w) +- [Git 学习笔记:版本回退](https://mp.weixin.qq.com/s/98wEvWU6OYVkPauWn-XXng) +- [如果你还不会用 git 回滚代码,那你一定要来看看](https://mp.weixin.qq.com/s/FPiSyeivTKhoAgJmORZFog) + +### 报错处理 + +- [git push 错误 failed to push some refs to 解决方法](https://blog.csdn.net/qq_39416311/article/details/102219428) +- [git 上传忽略 node_modules](https://blog.csdn.net/jiandan1127/article/details/81205530) + +### 博客相关 + +- [GitHub Pages 绑定来自阿里云的域名](https://blog.csdn.net/qq_29232943/article/details/52786603) +- [Hexo 发布到 Github 丢失 readme 和 CNAME 解决方案](https://www.cnblogs.com/LandWind/articles/8269636.html) +- [把 HUGO 博客托管到 GITHUB 上](https://www.freesion.com/article/37111127345/) + +### 其他 + +- [Github 上如何添加 LICENSE 文件?](https://www.cnblogs.com/chenmingjun/p/8555906.html) diff --git a/urara/2022-05-25-hypothesis/+page.md b/urara/2022-05-25-hypothesis/+page.md new file mode 100644 index 00000000..74de0d56 --- /dev/null +++ b/urara/2022-05-25-hypothesis/+page.md @@ -0,0 +1,133 @@ +--- +title: Hypothesis 使用小记 +created: 2022-05-25 +summary: Hypothesis同步到Obsidian / Logseq的方法 +tags: + - Logseq + - Obsidian +--- + +Hypothesis 太好用了,方便我满世界乱画写屁话(?),用它在网页上高亮,就像用荧光笔在纸上标注一样轻松 ,写标注就写在 3M 便利贴上,哪里都好贴,而且还支持用 Markdown 写,真的越用越顺手 + +它导出的笔记提供了导出的 API,可以轻松同步到 Obsidian / Logseq,真是平易近人呢! + +我的使用例子:![](/2022-05-25-hypothesis/657e30351066c4a3.png) + +我在 Obsidian 中导出的笔记: +![](/2022-05-25-hypothesis/0bf1f9770192c362.png) + +一些基础的部分我会省略掉,详情可以看这篇文章:[开源、可定制的网页批注工具——Hypothesis](https://type.cyhsu.xyz/2020/10/hypothesis-tutorial/) + +在下面这些操作之前,需要先注册一个 Hypotheis 账号,并安装浏览器扩展: + +- 注册:[Get started.](https://web.hypothes.is/start/#) +- Chrome 扩展:[Hypothesis - Web & PDF Annotation](https://chrome.google.com/webstore/detail/hypothesis-web-pdf-annota/bjfhmglciegochdpefhhlphglcehbmek) + 然后在浏览器扩展中登陆。 + +## 同步到 Logseq + +Logseq 我用得不多,如果有写错的,欢迎给我提建议~ + +### 1. 打开插件系统开关 + +(如果打开了可以省略这个) + +![](/2022-05-25-hypothesis/Snipaste_2022-05-25_21-14-43.png) + +如果在国内连接插件市场,最好设置一下代理,不然可能装不上,具体的设置需要看一下 VPN 端口号之类的。 + +### 2. 安装 Hypothesis 插件 + +打开 Logseq 的插件市场,找到如下名为 +**Hypothesis**的插件: +![](/2022-05-25-hypothesis/Snipaste_2022-05-25_21-20-20.png) +如果一直下载不了的话,可以直接在 Github 下载:[logseq-hypothesis](https://github.com/c6p/logseq-hypothesis) + +然后在这里导入: +![](/2022-05-25-hypothesis/Snipaste_2022-05-25_21-22-41.png) + +### 3. 获取 API Token + +在这里生成一个 API Token:[Regenerate your API token](https://hypothes.is/account/developer) + +复制后点击 Logseq 右上角的这个 H 的标志: +![](/2022-05-25-hypothesis/Snipaste_2022-05-25_21-26-37.png) + +然后填入刚刚复制的 API Token 和用户名 + +![](/2022-05-25-hypothesis/Snipaste_2022-05-25_21-45-33.png) + +用户名跟 Hypothesis 这里显示的一样,比如我的就是 Sevicheeee +![](/2022-05-25-hypothesis/Snipaste_2022-05-25_21-32-17.png) + +### 4. 同步笔记 + +点击 `Fetch Latest Notes` 会拉取最新的笔记 + +如果选择了指定页面,然后点`Add page notes to graph`,会自动生成一篇相应的笔记,比如: +![](/2022-05-25-hypothesis/Snipaste_2022-05-25_21-47-28.png) + +### 5. 修改笔记模板 + +如果想修改笔记模板的话,可以在`setting`中修改: +![](/2022-05-25-hypothesis/Snipaste_2022-05-25_21-48-58.png) + +## 同步到 Obsidian + +### 1. 安装 Hypothesis 插件 + +如图所示: +![](/2022-05-25-hypothesis/Snipaste_2022-05-25_21-51-44.png) + +Github: [obsidian-hypothesis-plugin](https://github.com/weichenw/obsidian-hypothesis-plugin) + +### 2. API 配置 + +打开插件设置,点击右上角的`Connect`, 输入你的 API Token 并保存,如果没有获取的话,请在这里获取:[Regenerate your API token](https://hypothes.is/account/developer) + +![](/2022-05-25-hypothesis/Snipaste_2022-05-25_21-53-41.png) + +可以在这里选择笔记保存的位置: +![](/2022-05-25-hypothesis/Snipaste_2022-05-25_21-56-38.png) + +其中`Use Domain Folders` 是按域名来划分文件结构,如果没有打开的话就是默认一篇笔记一个 md 文档,如下图红框所示就是打开了这个,下面蓝色的就是没打开时的输出结构 +![](/2022-05-25-hypothesis/Snipaste_2022-05-25_21-58-17.png) + +### 3. 笔记模板配置 + +可以在右边的文本框内设置笔记输出格式 +![](/2022-05-25-hypothesis/Snipaste_2022-05-25_22-00-11.png) +说实话,我没有怎么看懂 Orz, 然后这是我的模板: + +```js +{% if is_new_article %}# {{title}} + +## Metadata +{% if author %}- Author: [{{author}}]({{authorUrl}}){% endif %} +- Title: {{title}} +{% if url %}- Reference: {{url}}{% endif %} +- Category: #source/article🗞{% endif %} +- Tags: + +{% if is_new_article -%}## Highlights{%- endif %} +{% for highlight in highlights -%}- {{highlight.text}} +{% if highlight.tags | length %} - Tags: {% for tag in highlight.tags -%}#{{tag| replace(" ", "-")}} {%- endfor %}{%- endif %} +{% if highlight.annotation %} - Annotation: {{highlight.annotation}}{%- endif -%}{%- endfor -%} +``` + +效果: +![](/2022-05-25-hypothesis/Snipaste_2022-05-25_22-03-03.png) + +### 4. 更新笔记 + +点击右边这个标志就可以更新笔记了~也可以在设置里打开启动时自动抓取的设置 +![](/2022-05-25-hypothesis/Snipaste_2022-05-25_22-04-44.png) + +## 订阅 Hypothesis 的 RSS + +- 文档:[Atom & RSS Feeds for Annotations](https://web.hypothes.is/help/atom-rss-feeds-for-annotations/) +- 工具:[Subscribe to Hypothesis web annotations](https://diegodlh.github.io/hfeed/) + +## 其他参考 + +- [我的 Obsidian 使用经验 - 程序员的喵](https://catcoding.me/p/obsidian-for-programmer/) diff --git a/urara/2022-05-26-write-a-page-template/+page.md b/urara/2022-05-26-write-a-page-template/+page.md new file mode 100644 index 00000000..f9f73a98 --- /dev/null +++ b/urara/2022-05-26-write-a-page-template/+page.md @@ -0,0 +1,300 @@ +--- +title: 为博客写一个Project showcase 页面 +created: 2022-05-26 +summary: 第一次Pull Request的经历 +tags: + - Svelte + - Open Source +--- + +这两天为博客写了一个 Project 的页面用来放我的作品,这里记录一下我是怎么写(模仿)的,我对 Svelte 语法的了解不多,没有特别深入学习,只是在官方看了下文档和用了下他们的 [交互式教程](https://www.sveltejs.cn/tutorial/basics) ,编码的过程是一边学习一边模仿慢慢摸索的,虽然最终没有 merge 到 repo 中,但我觉得整个过程都蛮兴奋的。 + +既然有了博客,那我肯定是要写一下这个过程的。 + +## 1. 分析需求 + +我想要的是一个独立的 Page,而不是一个 Post 页面,最后把它放在导航栏里面。 +想要有以下这几个功能: + +- 技术栈分类 +- 项目类别筛选 +- 项目展示 + +主要有这些信息的展示: + +- 项目标题 +- 项目图片 +- 项目描述 +- 技术栈 +- 项目类别 + +## 2. 画原型图 + +明确了需求后,参考了几个项目平台的布局,在 [Whimsical](https://whimsical.com/) 上画了原型图如下: +![](https://s2.loli.net/2022/05/26/8kMa6LPrgUEC7Xb.png) + +目前还没有做上面 Tag 的分类功能,之后可能会做吧 + +## 2. 创建组件样式 CSS + +为了统一风格,我在博客现有框架里四处搜寻可用的组件样式,想在这基础上修改,然后我找到了作者 藍 在 Tailwind Play 上的友链组件,感觉很适合,然后就直接在这个 Tailwind Play Demo 上进行了样式修改,不过此时填写的数据都是死数据,后面再进行修改。 + +因为我之前没有怎么用过 Tailwind,所以是一边对照 Tailwind 文档修改的,然后 Tailwind Play 上的代码提示功能真的很新手友好,hover CSS class 的时候会显示具体的 CSS 原始参数,很直观。 + +![](https://s2.loli.net/2022/05/27/lFwQ8T5YUcdjDfe.png) +最后我构建的 Demo 样式如下: +[Tailwind Play](https://play.tailwindcss.com/uQwYojgpuk?layout=horizontal) + +![](https://s2.loli.net/2022/05/27/g5aYxD9mzlqpj6c.png) + +## 4. 编写组件代码 + +整个页面的构建跟 Friend 页面很像,我分析了 Friend 页面所涉及到的代码和结构,然后一点点模仿构建 Project 页面。 + +### 数据 + +首先根据需求确定传入的数据及其格式,以便后面使用 TypeScript 的提示 + +- 参考:`/src/lib/config/friends.ts` +- 新建:`/src/lib/config/projects.ts` + +```ts twoslash title="/src/lib/config/friends.ts" +export interface FriendOld { + // hCard+XFN + id: string // HTML id + rel?: string // XFN, contact / acquaintance / friend + link?: string // URL + html?: string // HTML + title?: string // 标题 + descr?: string // 描述 + avatar?: string // 头像 + name?: string // backwards compatibility +} + +export type Friend = { + id: string // HTML id + rel?: string // XHTML Friends Network + link?: string // URL + html?: string // Custom HTML + + title?: string // 标题 + name?: string // 人名 + avatar?: string // 头像 + descr?: string // 描述 + class?: { + avatar?: string // 头像类名 + img?: string // 图片类名 + } +} + +export const friends: Friend[] = [ + { + id: 'id', + rel: '', + title: '', + name: '', + link: '', + descr: '', + avatar: '' + } +] +``` + +```ts twoslash title="/src/lib/config/projects.ts" +export type Project = { + id: string + name?: string + tags?: string[] + feature?: string + description?: string + img?: string + link?: string +} + +export const projects: Project[] = [ + { + id: 'coach', + name: 'Find a Coach', + tags: ['Vue 3', 'Composition API'], + feature: 'Vue3', + description: + '既然如何, 问题的关键究竟为何? 要想清楚,科学和人文谁更有意义,到底是一种怎么样的存在。 普列姆昌德曾经提到过,希望的灯一旦熄灭,生活刹那间变成了一片黑暗。这启发了我, 那么, 我认为, 总结的来说,', + img: 'https://uneorange.oss-cn-guangzhou.aliyuncs.com/202205251801454.avif', + link: 'https://sevic.me' + } +] +``` + +### 组件 + +将 CSS 复制进去,并注入数据 + +- 参考:`/src/lib/components/extra/friend.svelte` +- 新建:`/src/lib/components/extra/project.svelte` + +```html title="/src/lib/components/extra/friend.svelte" + + +{#if friend.id === 'footer'} +