<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>aiden--.log</title>
        <link>https://velog.io/</link>
        <description>DEV</description>
        <lastBuildDate>Wed, 24 May 2023 01:06:18 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>aiden--.log</title>
            <url>https://images.velog.io/images/aiden--/profile/b6a15133-9da4-46c0-a656-ad9b7d2e8923/social.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. aiden--.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/aiden--" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Dart 3.0 변경점]]></title>
            <link>https://velog.io/@aiden--/Dart-3.0-%EB%B3%80%EA%B2%BD%EC%A0%90</link>
            <guid>https://velog.io/@aiden--/Dart-3.0-%EB%B3%80%EA%B2%BD%EC%A0%90</guid>
            <pubDate>Wed, 24 May 2023 01:06:18 GMT</pubDate>
            <description><![CDATA[<p>패턴과 레코드: 
레코드는 다양한 시나리오에서 사용할 수 있으며, 데이터를 표현하는 데 레코드 유형을 사용할 수 있습니다. 이를 통해 여러 반환 값이 있는 함수를 생성할 수 있습니다. 레코드는 클래스의 가벼운 대안으로 볼 수 있으며, &#39;Map&#39;이나 &#39;List&#39;보다 타입 안정성이 높습니다. 레코드는 명명된 인수와 위치 인수(또는 둘 다)를 지원하며, 디스트럭처링을 사용하여 코드를 더욱 간소화할 수 있습니다.</p>
<pre><code>(String, int, int) getPerson(Map&lt;String, dynamic&gt; json) {
  return (
    json[&#39;name&#39;],
    json[&#39;age&#39;],
    json[&#39;height&#39;],
  );
}

final person = getPerson(json);
print(person.$1); // &#39;Andrea&#39;
print(person.$2); // 38
print(person.$3); // 184</code></pre><p>또한, 레코드는 디스트럭처링을 지원합니다. 디스트럭처링을 사용하여 반환된 값을 이렇게 분해할 수 있습니다:</p>
<pre><code>final (name, age, height) = getPerson(json);
print(name); // &#39;Andrea&#39;
print(age); // 38
print(height); // 184
</code></pre><p>향상된 switch와 if-case 문장</p>
<p>Dart 3는 switch 표현식을 도입하였습니다. 예를 들어, 이전에 switch문을 사용하여 작성했던 코드는 다음과 같이 간결하게 재작성할 수 있습니다:</p>
<pre><code>enum Move {
  up,
  down,
  left,
  right;

  Offset get offset =&gt; switch (this) {
        up =&gt; const Offset(0.0, 1.0),
        down =&gt; const Offset(0.0, -1.0),
        left =&gt; const Offset(-1.0, 0.0),
        right =&gt; const Offset(1.0, 0.0),
      };
}</code></pre><p>Sealed classes 및 기타 클래스 수정자</p>
<p>Sealed classes는 모든 가능한 경우를 처리할 수 있도록 도와줍니다. 예를 들어, 백엔드에서 반환될 수 있는 모든 인증 예외를 정의하기 위해 Sealed classe를 사용할 수 있습니다:</p>
<pre><code>sealed class AuthException implements Exception {}

class EmailAlreadyInUseException extends AuthException {
  EmailAlreadyInUseException(this.email);
  final String email;
}

class WeakPasswordException extends AuthException {}

class WrongPasswordException extends AuthException {}

class UserNotFoundException extends AuthException {}</code></pre><pre><code>String describe(AuthException exception) {
  return switch (exception) {
    EmailAlreadyInUseException(email: final email) =&gt;
      &#39;Email already in use: $email&#39;,
    WeakPasswordException() =&gt; &#39;Password is too weak&#39;,
    WrongPasswordException() =&gt; &#39;Wrong password&#39;,
    UserNotFoundException() =&gt; &#39;User not found&#39;,
  };
}</code></pre><p>클래스 키워드</p>
<p>fianl로 클래스 선언:
    extends, implement, 또는 mixin으로 사용이 불가능합니다.
    but 같은 파일에서는 가능합니다.</p>
<pre><code>final class Person{
    final String name;
    final int age;

    Person({
        required this.name,
        required this.age,
    });
}</code></pre><p>base로 클래스 선언:
    base로 선언하면 extends는 가능하지만 implement는 불가능합니다.
    base, sealed, final로 선언된 클래스만 extend가 가능합니다.</p>
<pre><code>base class Person{
    final String name;
    final int age;

    Person({
        required this.name,
        required this.age,
    });
}</code></pre><p>interface로 선언하면 implement만 가능하다.</p>
<pre><code>interface class Person{
    final String name;
    final int age;

    Person({
        required this.name,
        required this.age,
    });
}</code></pre><p>Sealed class 는 abstract이면서 final이다.
패턴매칭을 사용할 수 있도록 해준다.</p>
<pre><code>sealed class Person{};

class Idol extends Person{};
class Engineer extends Person{};
class Chef extends Person {} //아래 스위치 문에서 에러 발생

String whoIsHe(Person person) =&gt; switch(person){
    Idol i =&gt; &#39;아이돌&#39;,
       Engineer e =&gt; &#39;엔지니어&#39;,
    _ =&gt; &#39;나머지&#39; // 이런식으로 패턴을 매칭 시켜줘야된다.
};

</code></pre><p>mixin class</p>
<p>1) mixin은 extends나 with을 사용 할 수 없다. 그렇기 떄문에 mixin class 도 마찬가지로 사용불가능하다
2) 클래스는 on 키워드를 사용 할 수 없다. 그렇기 때문에 mixin class도 on 키워드를 사용 할 수 없다.</p>
<pre><code>mixin class AnimalMixin{
    String bark(){
        return &#39;멍멍&#39;;
    }
};</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[flutter app icon change]]></title>
            <link>https://velog.io/@aiden--/flutter-app-icon-change</link>
            <guid>https://velog.io/@aiden--/flutter-app-icon-change</guid>
            <pubDate>Tue, 04 Apr 2023 01:43:50 GMT</pubDate>
            <description><![CDATA[<p>flutter pub add flutter_launcher_icons --dev
flutter pub run flutter_launcher_icons:main  </p>
<p> flutter pub run flutter_native_splash:create       </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[AOT 란?]]></title>
            <link>https://velog.io/@aiden--/AOT-%EB%9E%80</link>
            <guid>https://velog.io/@aiden--/AOT-%EB%9E%80</guid>
            <pubDate>Mon, 03 Apr 2023 09:06:28 GMT</pubDate>
            <description><![CDATA[<p>AOT는 Ahead-Of-Time의 약자로, AOT 컴파일된 언어는 컴파일러에 의해 기계어로 변환되어 실행 파일로 저장됩니다. 이것은 프로그램이 실행될 때 인터프리터에 의해 실행되는 언어와 대조적입니다.</p>
<p>즉, AOT 컴파일된 언어는 프로그램이 실행되기 전에 미리 컴파일되어 기계어로 번역되므로 실행 속도가 매우 빠르고, 높은 안정성과 안전성을 제공합니다. 이러한 특징 때문에 AOT 컴파일된 언어는 보안에 민감한 애플리케이션 및 모바일 장치에서 많이 사용됩니다. 예를 들어, C, C++ 등이 AOT 컴파일된 언어입니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Dart const와 final]]></title>
            <link>https://velog.io/@aiden--/Dart-%EA%B8%B0%EB%B3%B8%EC%96%B8%EC%96%B4</link>
            <guid>https://velog.io/@aiden--/Dart-%EA%B8%B0%EB%B3%B8%EC%96%B8%EC%96%B4</guid>
            <pubDate>Mon, 03 Apr 2023 09:05:22 GMT</pubDate>
            <description><![CDATA[<p>const 는 마치 final과 같다. =false</p>
<p>Flutter에서 const와 final은 모두 불변(immutable) 변수를 선언하는 키워드입니다. 그러나 둘 사이에는 몇 가지 중요한 차이점이 있습니다.</p>
<p>const: const 키워드로 선언된 변수는 컴파일 타임 상수(compile-time constant)입니다. 즉, 변수가 선언될 때 해당 값이 결정되며, 이후에는 값을 변경할 수 없습니다. const로 선언된 변수는 반드시 리터럴(literal) 값을 가져야 합니다.</p>
<p>final: final 키워드로 선언된 변수는 런타임 상수(runtime constant)입니다. 즉, 변수가 초기화될 때 결정되며, 이후에는 값을 변경할 수 없습니다. final로 선언된 변수는 리터럴 값을 가져야 할 필요는 없으며, 다른 변수나 표현식의 결과를 할당할 수 있습니다.</p>
<p>또한, const는 클래스, 메서드, 생성자 및 변수에서 사용할 수 있지만, final은 변수, 클래스 멤버 변수 및 로컬 변수에서만 사용할 수 있습니다.</p>
<p>예를 들어, 다음과 같이 const와 final을 사용하여 변수를 선언할 수 있습니다.</p>
<pre><code>const pi = 3.14; // const 변수 선언
final currentTime = DateTime.now(); // final 변수 선언</code></pre><p>위 코드에서 pi는 컴파일 타임 상수이므로, 다른 값으로 재할당할 수 없습니다. 반면에, currentTime은 런타임 상수이므로 초기화할 때 결정되며, 이후에는 값을 변경할 수 없습니다.</p>
<p>따라서, const와 final은 모두 불변 변수를 선언하는 키워드이지만, 상수의 값을 결정하는 시점이나 변수를 사용할 수 있는 범위 등에서 차이점이 있습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[web3 지갑연동 인증]]></title>
            <link>https://velog.io/@aiden--/web3-%EC%A7%80%EA%B0%91%EC%97%B0%EB%8F%99-%EC%9D%B8%EC%A6%9D</link>
            <guid>https://velog.io/@aiden--/web3-%EC%A7%80%EA%B0%91%EC%97%B0%EB%8F%99-%EC%9D%B8%EC%A6%9D</guid>
            <pubDate>Tue, 21 Feb 2023 23:58:47 GMT</pubDate>
            <description><![CDATA[<p><a href="https://www.toptal.com/ethereum/one-click-login-flows-a-metamask-tutorial">https://www.toptal.com/ethereum/one-click-login-flows-a-metamask-tutorial</a></p>
<p><a href="https://ko.docs.klaytn.foundation/content/dapp/json-rpc/api-references/personal#personal_sign">https://ko.docs.klaytn.foundation/content/dapp/json-rpc/api-references/personal#personal_sign</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Metamask Mobile deep-links]]></title>
            <link>https://velog.io/@aiden--/Metamask-Mobile-deep-links</link>
            <guid>https://velog.io/@aiden--/Metamask-Mobile-deep-links</guid>
            <pubDate>Wed, 15 Feb 2023 08:08:04 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>모바일 메타마스크 앱에서 인앱 브라우저를 열때 지정한 링크로 바로 열 수 있는가</p>
</blockquote>
<ul>
<li>결론 : 현재까지의 리서치 및 테스트 결과로는 메타마스크 앱을 여는 것까지만 가능했다.
  우리 사이트로 이동 시키러면 다시 메타마스크 앱의 브라우저를 열어서 url을 입력 하게해야한다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Metamask Mobile 리서치]]></title>
            <link>https://velog.io/@aiden--/Metamask-Mobile-%EB%A6%AC%EC%84%9C%EC%B9%98</link>
            <guid>https://velog.io/@aiden--/Metamask-Mobile-%EB%A6%AC%EC%84%9C%EC%B9%98</guid>
            <pubDate>Tue, 14 Feb 2023 11:38:32 GMT</pubDate>
            <description><![CDATA[<ol>
<li><p>Cordova, Capacitor
모바일 하이브리드 앱 프레임워크의 일종입니다. 이것들을 이용하여 웹 앱을 모바일 앱으로 빌드하고, 메타마스크와 연동하는 방법
어떤 에러가 발생할지 알 수 없어서 제외.</p>
</li>
<li><p>WalletConnect 
탈중앙화 애플리케이션(DApp)과 지갑 애플리케이션을 안전하게 연결하기 위한 개방형 프로토콜입니다. 이 프로토콜을 사용하면, 사용자는 안전하게 자신의 지갑을 DApp과 연동하여, 자신의 디지털 자산을 관리하고 거래를 수행할 수 있습니다.
v2로 업데이트되면서 일부 기능 사용불가
일반 유저들이 한번 더 연결해야되는 단계가 추가됩니다.</p>
</li>
<li><p>deep-link 이용하여 인앱 브라우저를 열어서 사용
메타마스크가 설치되어있다면 바로 앱을 열수있습니다.</p>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[RSA SubtleCrypto]]></title>
            <link>https://velog.io/@aiden--/RSA-SubtleCrypto</link>
            <guid>https://velog.io/@aiden--/RSA-SubtleCrypto</guid>
            <pubDate>Wed, 25 May 2022 01:14:28 GMT</pubDate>
            <description><![CDATA[<p>타입스크립트에서 crypto 모듈이 임포드가 안되는 현상이 발생하였음.
백엔드에서 OAEPPadding으로 암호화 하기를 요구. 
이러한 복합적인 상황이 발생하여서 직접 암호화를 하기로 결정.
될 수 있으면 라이브러리를 사용하십시오.</p>
<blockquote>
<p>ArrayBuffer
ArrayBuffer는 바이트로 구성된 배열로, 다른 언어에서는 종종 &quot;바이트 배열&quot;이라고 부릅니다. ArrayBuffer에 담긴 정보를 직접 수정하는 것은 불가능하지만, 대신 형식화 배열이나 DataView 객체를 통해 버퍼를 특정 형식으로 나타내고, 이를 통해 버퍼의 내용을 읽거나 쓸 수 있습니다.
<a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer">https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer</a></p>
</blockquote>
<p>데이터를 넣을때 ArrayBuffer 형태로 넣어야한다. return값도 ArrayBuffer로 나온다.
key는 받아서 CryptoKey형태로 넣어야된다.</p>
<pre><code>function str2ab(str: any) {
    const buf = new ArrayBuffer(str.length);
    const bufView = new Uint8Array(buf);
    for (let i = 0, strLen = str.length; i &lt; strLen; i++) {
      bufView[i] = str.charCodeAt(i);
    }
    return buf;
  }

  const pemEncodedKey = `-----BEGIN PUBLIC KEY-----
  -----END PUBLIC KEY-----`;

  function importRsaKey(pem: any) {
    // fetch the part of the PEM string between header and footer
    const pemHeader = &quot;-----BEGIN PUBLIC KEY-----&quot;;
    const pemFooter = &quot;-----END PUBLIC KEY-----&quot;;
    const pemContents = pem.substring(
      pemHeader.length,
      pem.length - pemFooter.length
    );
    // base64 decode the string to get the binary data
    const binaryDerString = window.atob(pemContents);
    // convert from a binary string to an ArrayBuffer
    const binaryDer = str2ab(binaryDerString);

    return window.crypto.subtle.importKey(
      &quot;spki&quot;,
      binaryDer,
      {
        name: &quot;RSA-OAEP&quot;,
        hash: &quot;SHA-1&quot;,
      },
      true,
      [&quot;encrypt&quot;]
    );
  }

  async function encryptMessage(publicKey: any) {
    const data = str2ab(jsonData);
    const ciphertext = await importRsaKey(publicKey);
    return window.crypto.subtle.encrypt(
      {
        name: &quot;RSA-OAEP&quot;,
      },
      ciphertext,
      data
    );
  }
   const encryptData = await encryptMessage(pemEncodedKey);

  function importPrivateRsaKey(pem: any) {
    // fetch the part of the PEM string between header and footer
    const pemHeader = &quot;-----BEGIN PRIVATE KEY-----&quot;;
    const pemFooter = &quot;-----END PRIVATE KEY-----&quot;;
    const pemContents = pem.substring(
      pemHeader.length,
      pem.length - pemFooter.length
    );
    // base64 decode the string to get the binary data
    const binaryDerString = window.atob(pemContents);
    // convert from a binary string to an ArrayBuffer
    const binaryDer = str2ab(binaryDerString);

    return window.crypto.subtle.importKey(
      &quot;pkcs8&quot;,
      binaryDer,
      {
        name: &quot;RSA-OAEP&quot;,
        hash: &quot;SHA-1&quot;,
      },
      true,
      [&quot;decrypt&quot;]
    );
  }
  const privateKey = `-----BEGIN PRIVATE KEY-----
  -----END PRIVATE KEY-----`;
  async function decryptMessage(ciphertext: any) {
    const pk = await importPrivateRsaKey(privateKey);
    return window.crypto.subtle.decrypt(
      {
        name: &quot;RSA-OAEP&quot;,
      },
      pk,
      ciphertext
    );
  }
  const decryptData = await decryptMessage(encryptData); 

</code></pre><p>  참고 <a href="https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto">https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto</a></p>
<p><del>MDN은 신이다</del></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[회원가입 구현]]></title>
            <link>https://velog.io/@aiden--/%ED%9A%8C%EC%9B%90%EA%B0%80%EC%9E%85-%EA%B5%AC%ED%98%84</link>
            <guid>https://velog.io/@aiden--/%ED%9A%8C%EC%9B%90%EA%B0%80%EC%9E%85-%EA%B5%AC%ED%98%84</guid>
            <pubDate>Wed, 18 May 2022 09:34:32 GMT</pubDate>
            <description><![CDATA[<p>vue를 통해 회원가입을 진행중.</p>
<p>회원가입 플로우
회원 정보 -&gt; 휴대폰 인증-&gt; 회원가입 완료.</p>
<p>문제점. 회원 정보를 받은뒤 휴대폰인증을 할때 nice본인인증을하고 난 뒤에 돌아오면 vuex가 초기화되면서 처음에 받은 회원정보가 날아가는 문제가 존재함.</p>
<p>시도 1. 잠시동안 로컬스토리지에 저장. 로컬스토리지에 저장하는일은 절대없다.</p>
<p>해결책 1. 회원정보를 nice쪽에 보내놓는다. 인증이 끝나면 인증정보와 같이 다시 받아온다. </p>
<p>해결책 2. 팝업창을 띄워서 처리를 한뒤에 원래 페이지로 데이터와 함께 넘어온다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[로그인 실패시 서버에러메세지 받아서 그대로 보여주기]]></title>
            <link>https://velog.io/@aiden--/%EB%A1%9C%EA%B7%B8%EC%9D%B8-%EC%8B%A4%ED%8C%A8%EC%8B%9C-%EC%84%9C%EB%B2%84%EC%97%90%EB%9F%AC%EB%A9%94%EC%84%B8%EC%A7%80-%EB%B0%9B%EC%95%84%EC%84%9C-%EA%B7%B8%EB%8C%80%EB%A1%9C-%EB%B3%B4%EC%97%AC%EC%A3%BC%EA%B8%B0</link>
            <guid>https://velog.io/@aiden--/%EB%A1%9C%EA%B7%B8%EC%9D%B8-%EC%8B%A4%ED%8C%A8%EC%8B%9C-%EC%84%9C%EB%B2%84%EC%97%90%EB%9F%AC%EB%A9%94%EC%84%B8%EC%A7%80-%EB%B0%9B%EC%95%84%EC%84%9C-%EA%B7%B8%EB%8C%80%EB%A1%9C-%EB%B3%B4%EC%97%AC%EC%A3%BC%EA%B8%B0</guid>
            <pubDate>Thu, 12 May 2022 00:11:20 GMT</pubDate>
            <description><![CDATA[<ol>
<li><p>첫번째로 시도한 방법은 vuex에 넣어서 vuex에 메세지가 있으면 에러 메세지를 출력하는 방법
실패 -&gt; vuex에 메세지가 들어가서 오류 메세지까지 출력이 되는것을 확인했으니 첫번째 클릭때 메세지가 들어가고 한번 더 클릭을 해야 메세지를 출력해준다. 이것을 바로 출력하려고 했으나 실패</p>
</li>
<li><p>두번째로 시도해볼 방법 따로 컴포넌트 만들어서 해결시도중 -&gt; 실패</p>
<p> 한번만 실행해서는 메세지가 바로 안뜬다 한번더 실행 시켜서 바로 나오게 수정한다.</p>
</li>
<li><p>ref=&quot;formRef&quot;로 form에 접근해서 validate을 한번더 실행해줘서 해결.</p>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[모바일 화면에서 가로 스크롤 문제]]></title>
            <link>https://velog.io/@aiden--/%EB%AA%A8%EB%B0%94%EC%9D%BC-%ED%99%94%EB%A9%B4%EC%97%90%EC%84%9C-%EA%B0%80%EB%A1%9C-%EC%8A%A4%ED%81%AC%EB%A1%A4-%EB%AC%B8%EC%A0%9C</link>
            <guid>https://velog.io/@aiden--/%EB%AA%A8%EB%B0%94%EC%9D%BC-%ED%99%94%EB%A9%B4%EC%97%90%EC%84%9C-%EA%B0%80%EB%A1%9C-%EC%8A%A4%ED%81%AC%EB%A1%A4-%EB%AC%B8%EC%A0%9C</guid>
            <pubDate>Wed, 11 May 2022 02:33:23 GMT</pubDate>
            <description><![CDATA[<pre><code>&lt;meta
   name=&quot;viewport&quot;
   content=&quot;width=device-width,initial-scale=1.0, maximum-scale=1, user-scalable=no&quot;
/&gt;
// 추가 부분 maximum-scale=1, user-scalable=no
&lt;style&gt;
html,
body {
  max-width: 100%;
  overflow-x: hidden;
}
&lt;/style&gt;

</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[전체동의 체크박스]]></title>
            <link>https://velog.io/@aiden--/%EC%A0%84%EC%B2%B4%EB%8F%99%EC%9D%98-%EC%B2%B4%ED%81%AC%EB%B0%95%EC%8A%A4-zangdoz6</link>
            <guid>https://velog.io/@aiden--/%EC%A0%84%EC%B2%B4%EB%8F%99%EC%9D%98-%EC%B2%B4%ED%81%AC%EB%B0%95%EC%8A%A4-zangdoz6</guid>
            <pubDate>Mon, 09 May 2022 03:45:47 GMT</pubDate>
            <description><![CDATA[<pre><code>input[type=&quot;checkbox&quot;] {
  display: none;
}

input[type=&quot;checkbox&quot;] + label {
  display: inline-block;
  cursor: pointer;
  line-height: 22px;
  padding-left: 22px;
  background: url(&quot;@/assets/image/button/checkbox/icon_check.png&quot;) left/22px
    no-repeat;
}

input[type=&quot;checkbox&quot;]:checked + label {
  background-image: url(&quot;@/assets/image/button/checkbox/icon_check_active.png&quot;);
}</code></pre><pre><code> &lt;!-- &lt;a-form-item&gt;
          &lt;input
            type=&quot;checkbox&quot;
            id=&quot;all-box&quot;
            value=&quot;isAllowAllchecked&quot;
            v-model=&quot;checkAll&quot;
            @change=&quot;onCheckAllChange&quot;
          /&gt;
          &lt;label for=&quot;all-box&quot;&gt;전체 동의&lt;/label&gt;

          &lt;input
            type=&quot;checkbox&quot;
            id=&quot;box1&quot;
            value=&quot;isAllowTermsOfService&quot;
            v-model=&quot;checkedList&quot;
          /&gt;
          &lt;label for=&quot;box1&quot;&gt;[필수] 이용약관 동의&lt;/label&gt;

          &lt;input
            type=&quot;checkbox&quot;
            id=&quot;box2&quot;
            value=&quot;isAllowPersonalCreditInformation&quot;
            v-model=&quot;checkedList&quot;
          /&gt;
          &lt;label for=&quot;box2&quot;&gt;[필수] 개인 신용 정보 수집 이용 동의.&lt;/label&gt;

          &lt;input
            type=&quot;checkbox&quot;
            id=&quot;box3&quot;
            value=&quot;isAllowPersonalCreditInformation-3rd&quot;
            v-model=&quot;checkedList&quot;
          /&gt;
          &lt;label for=&quot;box3&quot;&gt;[필수] 개인 신용 정보 제3자 제공 동의.&lt;/label&gt;

          &lt;input
            type=&quot;checkbox&quot;
            id=&quot;box4&quot;
            value=&quot;isAllowMarketing&quot;
            v-model=&quot;checkedList&quot;
          /&gt;
          &lt;label for=&quot;box4&quot;&gt;[선택] 투자정보 수신 동의.&lt;/label&gt;
          {{ checkedList }}
        &lt;/a-form-item&gt; --&gt;</code></pre><pre><code>const plainOptions = [
  &quot;isAllowTermsOfService&quot;,
  &quot;isAllowPersonalCreditInformation&quot;,
  &quot;isAllowPersonalCreditInformation-3rd&quot;,
  &quot;isAllowMarketing&quot;,
];

</code></pre><pre><code>const state = reactive({
      indeterminate: false,
      checkAll: false,
      checkedList: [],
    });

    const onCheckAllChange = (e: any) =&gt; {
      Object.assign(state, {
        checkedList: e.target.checked ? plainOptions : [],
        indeterminate: false,
      });
    };
    watch(
      () =&gt; state.checkedList,
      (val) =&gt; {
        state.indeterminate = !!val.length &amp;&amp; val.length &lt; plainOptions.length;
        state.checkAll = val.length === plainOptions.length;
      }
    );

       return {
      onFinish,
      onFinishFailed,
      loginForm,
      loading,
      login,
      ...toRefs(state),
      plainOptions,
      onCheckAllChange,
    };</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[serviceworker]]></title>
            <link>https://velog.io/@aiden--/serviceworker</link>
            <guid>https://velog.io/@aiden--/serviceworker</guid>
            <pubDate>Wed, 04 May 2022 02:49:59 GMT</pubDate>
            <description><![CDATA[<p>serviceworker</p>
<p>version 0.0.0</p>
<p>메이저 버전 - 마이너 버전 - 버그픽스
마이너버전이 99가되면 메이저버전 +1</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[ssh public 키생성]]></title>
            <link>https://velog.io/@aiden--/ssh-public-%ED%82%A4%EC%83%9D%EC%84%B1</link>
            <guid>https://velog.io/@aiden--/ssh-public-%ED%82%A4%EC%83%9D%EC%84%B1</guid>
            <pubDate>Tue, 03 May 2022 06:02:40 GMT</pubDate>
            <description><![CDATA[<p>ssh-keygen</p>
<p>cd .ssh</p>
<p>ls
id_rsa     id_rsa.pub</p>
<p>cat id_rsa </p>
<p>cat id_rsa.pub </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[절대 후회를 낳지 않을 3가지 행동]]></title>
            <link>https://velog.io/@aiden--/%EC%A0%88%EB%8C%80-%ED%9B%84%ED%9A%8C%EB%A5%BC-%EB%82%B3%EC%A7%80-%EC%95%8A%EC%9D%84-3%EA%B0%80%EC%A7%80-%ED%96%89%EB%8F%99</link>
            <guid>https://velog.io/@aiden--/%EC%A0%88%EB%8C%80-%ED%9B%84%ED%9A%8C%EB%A5%BC-%EB%82%B3%EC%A7%80-%EC%95%8A%EC%9D%84-3%EA%B0%80%EC%A7%80-%ED%96%89%EB%8F%99</guid>
            <pubDate>Thu, 28 Apr 2022 02:03:37 GMT</pubDate>
            <description><![CDATA[<p>절대 후회를 낳지 않을 3가지 행동
일찍 일어나 일터로 향하고, 좋은 것들을 배우고, 선량한 사람들에게 은혜를 베푸는 것, 이 세 가지 행동은 어떤 경우에도 후회를 낳지 않는다. - 이솝</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[읽기좋은코드가 좋은 코드다 4일차]]></title>
            <link>https://velog.io/@aiden--/%EC%9D%BD%EA%B8%B0%EC%A2%8B%EC%9D%80%EC%BD%94%EB%93%9C%EA%B0%80-%EC%A2%8B%EC%9D%80-%EC%BD%94%EB%93%9C%EB%8B%A4-4%EC%9D%BC%EC%B0%A8</link>
            <guid>https://velog.io/@aiden--/%EC%9D%BD%EA%B8%B0%EC%A2%8B%EC%9D%80%EC%BD%94%EB%93%9C%EA%B0%80-%EC%A2%8B%EC%9D%80-%EC%BD%94%EB%93%9C%EB%8B%A4-4%EC%9D%BC%EC%B0%A8</guid>
            <pubDate>Mon, 25 Apr 2022 05:38:16 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[읽기 좋은 코드가 좋은 코드다. 3일차]]></title>
            <link>https://velog.io/@aiden--/%EC%9D%BD%EA%B8%B0-%EC%A2%8B%EC%9D%80-%EC%BD%94%EB%93%9C%EA%B0%80-%EC%A2%8B%EC%9D%80-%EC%BD%94%EB%93%9C%EB%8B%A4.-3%EC%9D%BC%EC%B0%A8</link>
            <guid>https://velog.io/@aiden--/%EC%9D%BD%EA%B8%B0-%EC%A2%8B%EC%9D%80-%EC%BD%94%EB%93%9C%EA%B0%80-%EC%A2%8B%EC%9D%80-%EC%BD%94%EB%93%9C%EB%8B%A4.-3%EC%9D%BC%EC%B0%A8</guid>
            <pubDate>Thu, 21 Apr 2022 03:35:07 GMT</pubDate>
            <description><![CDATA[<p>ddd</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[브라우저 랜더링 과정]]></title>
            <link>https://velog.io/@aiden--/%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80-%EB%9E%9C%EB%8D%94%EB%A7%81-%EA%B3%BC%EC%A0%95</link>
            <guid>https://velog.io/@aiden--/%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80-%EB%9E%9C%EB%8D%94%EB%A7%81-%EA%B3%BC%EC%A0%95</guid>
            <pubDate>Wed, 20 Apr 2022 06:03:46 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/aiden--/post/8ac9d652-19bf-4d43-9bef-a32b273c5390/image.png" alt=""></p>
<ol>
<li>사용자가 사용자 인터페이스에 주소표시줄에 URI를 입력하여 브라우저 엔진에 전달한다</li>
<li>브라우저 엔진은 자료 저장소에서 URI에 해당하는 자료를 찾고, 해당 자료를 쿠키로 저장했다면 그 자료를 렌더링 엔진에 전달한다</li>
<li>렌더링 엔진은 브라우저 엔진에서 가져온 자료(HTML, CSS, image 등)를 분석한다. 동시에 URI 데이터를 통신, 자바스크립트 해석기, UI 백엔드로 전파한다
또한 렌더링 엔진은 통신 레이어에 URI에 대한 추가 데이터(있다면)를 요청하고 응답할 때까지 기다린다</li>
<li>응답받은 데이터에서 HTML, CSS는 렌더링 엔진이 파싱한다</li>
<li>응답받은 데이터에서 JavaScript는 JavaScript 해석기가 파싱한다</li>
<li>JavaScript 해석기는 파싱한 결과를 렌더링 엔진에 전달하여 3번과 5번에서 파싱한 HTML의 결과인 DOM tree을 조작한다</li>
<li>조작이 완료된 DOM node(DOM tree 구성요소)는 render object(render tree 구성요소)로 변한다</li>
<li>UI 벡엔드는 render object를 브라우저 렌더링 화면에 띄워준다</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[CSR VS SSR]]></title>
            <link>https://velog.io/@aiden--/CSR-VS-SSR</link>
            <guid>https://velog.io/@aiden--/CSR-VS-SSR</guid>
            <pubDate>Wed, 20 Apr 2022 00:28:50 GMT</pubDate>
            <description><![CDATA[<p>csr
첫로딩이 느리다.
페이지 캐싱이 잘 안된다.
seo 잘 안된다.</p>
<p><img src="https://velog.velcdn.com/images/aiden--/post/4600ee19-6d6b-438c-9a00-19c1cc3e58ef/image.png" alt=""></p>
<p>출처- <a href="https://www.youtube.com/watch?v=5W72UHb-9iI">https://www.youtube.com/watch?v=5W72UHb-9iI</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[React와 Vue, Angular의 차이점은 무엇인가요?]]></title>
            <link>https://velog.io/@aiden--/React%EC%99%80-Vue-Angular%EC%9D%98-%EC%B0%A8%EC%9D%B4%EC%A0%90%EC%9D%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80%EC%9A%94</link>
            <guid>https://velog.io/@aiden--/React%EC%99%80-Vue-Angular%EC%9D%98-%EC%B0%A8%EC%9D%B4%EC%A0%90%EC%9D%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80%EC%9A%94</guid>
            <pubDate>Tue, 19 Apr 2022 16:14:59 GMT</pubDate>
            <description><![CDATA[<p>React 단방향바인딩
vue, angular 양방향 바인딩</p>
<p>양방향 바인딩이란?
model-view 에서 view가 바뀌면 model이 바뀌는것.
단방향 바인딩이란?
model-view 에서 view가 바뀌어도 model이 바뀌지않음. 추가적인 코드가 필요.</p>
]]></description>
        </item>
    </channel>
</rss>