Js object array 多條件篩選且條件可能為空

 最近在工作上遇到需要多條件篩選,且條件為空就不進行判斷,花了一點時間才研究出怎麼做

以下是解法

const originItems =
[{id:1, live:true, name:"test1",color:"red",size:"large"},
{id:2, live:true,name:"test2",color:"blue",size:"large"},
{id:3, live:true,name:"test3",color:"green",size:"medium"},
{id:4, live:false, name:"test4",color:"red",size: "small"},
{id:5, live:false, name:"test5",color:"blue",size: "small"},
{id:6, live:false, name:"test6",color:"green",size:"medium"}];

const sort = {live: true, color: "", size:"large"}

const result = originItems.filter( (o) =>
(!sort.live || o.live === sort.live) && (!sort.color || o.color === sort.color)
&& (!sort.size || o.size === sort.size)
)

console.log(result)

結果如下:

  1. length: 2

useEffect的三種dependency差異


第一種方式因為傳入的dependency是empty array

所以只會執行一次 

useEffect(() =>{

console.log("Hi)

},[])



第二種方式當每一次dependency變動時就會執行一次useEffect
useEffect(() =>{

console.log("Hi)

},[dependency])


第三種方式會變成無限迴圈...慎用
useEffect(() =>{

console.log("Hi)

},)

Js轉換時間格式為YYYY-MM-DD HH:MM:SS

身為前後端都要寫的工程師,時間處理總是會碰到的

以下是簡單的方法將Js 的Date 轉為 YYYY-MM-DD HH:MM:SS 格式的寫法

const d = new Date()
const formatedTimestamp = (d)=> {
const date = d.toISOString().split('T')[0];
const time = d.toTimeString().split(' ')[0];
return `${date} ${time}`
}

Css Combinators

Css Combinators 有以下四種


  • descendant selector (space)
  • child selector (>)
  • adjacent sibling selector (+)
  • general sibling selector (~)

以這個html為例,html都是巢狀,所以是一層包一層的結果,如果我們想要選擇下層的標籤內容,可以使用descendant selector  語法是:在上層跟下層中間加上一個”空白”


<!DOCTYPE html>
<html>
<head>
<style>
div p {
background-color: yellow;
}
</style>
</head>
<body>

<h2>Descendant Selector</h2>

<p>The descendant selector matches all elements that are descendants of a specified element.</p>

<div>
<p>Paragraph 1 in the div.</p>
<p>Paragraph 2 in the div.</p>
<section><p>Paragraph 3 in the div.</p></section>
</div>

<p>Paragraph 4. Not in a div.</p>
<p>Paragraph 5. Not in a div.</p>

</body>
</html>

output 





將style更換成child selector如下
<style>
div > p {
background-color: yellow;
}
</style>

可以發現畫面paragraph3沒有變成黃色


因為
paragraph3外面多了一層<section> 所以沒辦法直接被child selector 選擇



再將style更改如下
div + p {
background-color: yellow;
}


我們這邊用adjacent sibling selector,這會選擇指定相鄰的元素,在<div>後面的<p>被選擇了
</div>

<p>Paragraph 4. Not in a div.</p>
所以只有paragraph4被選中


最後是general sibling selector,只要相同層級並且順序在自己後面,就可以使用
<div>
<p>Paragraph 1 in the div.</p>
<p>Paragraph 2 in the div.</p>
<section><p>Paragraph 3 in the div.</p></section>
</div>

<p>Paragraph 4. Not in a div.</p>
<p>Paragraph 5. Not in a div.</p>
如圖,paragraph4跟paragraph5都跟div同個層級,又在div後面,所以會被選中




Css Selector

 範例如下

index.html

<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>uHost</title>
<link rel="shortcut icon" href="favicon.png">
<link rel="stylesheet" href="index.css">
</head>

<body>
<main>
<section>
<h1>Get the freedom you deserve.</h1>
</section>

<section class="test_class">
<h1 class="test_class_h1">Use class</h1>
</section>

<section id="test_id">
<h1 id="test_id_h1">Use id</h1>
</section>

<button disabled>Use attribute</button>
</main>
</body>

</html>


index.css

section{
background-color: bisque;
}
h1{
color: aqua;
}

.test_class{
background-color: cornsilk;
}

.test_class_h1{
color: aquamarine;
}

#test_id{
background-color: black;
}

#test_id_h1{
color: aliceblue;
}

button[disabled]{
color: aquamarine;
}


section 代表選擇所有 section element
.test_class 代表選擇所有class為test_class的element
#test_id 代表選擇所有id為test_id的element
button[disabled] 代表選擇所有 attribute有disabled的 button




terminal 基本操作 + git (二)

快速複習一下上一章教過的指令









以上的步驟是:
創造一個叫second.txt的檔案 --> 編輯second.txt --> 加入stage --> commit 到repository

之後輸入git log

可以看到我們操作的歷史紀錄

每一個commit後面都會有一串id
可以試著下指令 git checkout 第一個commit的id (以我這邊的例子就是972b76e15fb15bcc88ff0be7ec2da43df2745b92)
這時候就代表到了第一次commit時的status
用ls查看會發現只剩一開始commit的檔案
用git log查看會發現log也恢復到第一次commit的樣子






然後再輸入 git checkout master(這是我們的branch名稱)
就可以回復原狀了







git branch 指令可以讓你查看所有branch 如果前面有*代表目前的branch
git branch branchname以branchname 創造一個新的branch




也可以使用git checkout -b branchname(以branchname 創造一個新的branch並且直接checkout到該branch)



然後在剛剛建立的third_branch新增檔案並commit

用ls指令時可以看到有三個檔案
但切換回master branch後再下ls就可以看到只剩兩個檔案
因為third.txt 是我們在third_branch 新增的,所以master branch不會有這個檔案


如果想要讓master也有這個檔案
就要使用merge指令

這樣就成功讓master branch 有了 third.txt
















terminal 基本操作 + git (一)

 ls:列出目前資料夾內的檔案與資料夾






mkdir:創造資料夾

cd:移動到資料夾



移動到我們剛創造的git-basics資料夾後輸入code . 

就可以直接在這個資料夾開啟vs code



輸入git init,在目錄建立.git資料夾






輸入git status 可以看到目前git的狀態

目前還沒有任何的commit  





之後輸入touch test.txt 新增一個叫做test.txt的檔案

再輸入vim test.txt 使用vim來編輯檔案



進入vim以後畫面會像這樣









請按下i 進入編輯模式 這時畫面左下角會有一個insert










就可以開始輸入文字了

在畫面輸入 Hello World!

之後按下  esc 就可以看到左下角的insert不見了









這時輸入 :進入命命模式









再輸入wq 

w表示寫入

q 表示離開

按下enter就可以了









回到terminal後

輸入open text.txt



就會看到我們剛剛創的 test.txt   出來了









再輸入一次git status

可以看到untracked files 內有我們剛剛建立的test.txt





接著輸入   git add test.txt把檔案加入stage

再查看一次status    就可以看到已經加入stage了






加入stage後,還需要commit的指令才能把檔案加入到repository

所以再輸入 git commit -m "這次commit的註解"





可以看到檔案已經被commit到repository了

p.s.如果覺得terminal   太長可以輸入  "clear" 就會清空所有內容









First App in React+Typescript

在CMD輸入以下指令

mkdir type_react_demo

cd type_react_demo

npm init

之後會跳出這些選項 都直接按Enter就好

package name: (type_react_demo)

version: (1.0.0)

description: demoproject_typescript_react

entry point: (index.js)

test command:

git repository:

keywords:

author:

license: (ISC)

About to write to C:\Users\samchen\typereact\type_react_demo\package.json:


{

  "name": "type_react_demo",

  "version": "1.0.0",

  "description": "demoproject_typescript_react",

  "main": "index.js",

  "scripts": {

    "test": "echo \"Error: no test specified\" && exit 1"

  },

  "author": "",

  "license": "ISC"

}


繼續輸入以下指令

npm i -D webpack webpack-cli

mkdir src

code .

用code .會打開VS CODE編輯器 自動載入這個Folder

之後在src內建立一個index.js

內容就直接console.log("Hello world")即可

然後到package.json修改scripts內容如下

  "scripts": {
    "build": "webpack --mode production"
  },

然後在CMD輸入 npm run build

應該就能看到webpack 編譯並執行我們的index.js檔




在src內新增一個index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>React Plus TypeScript</title>
  </head>
  <body>
    <script src="./main.js"></script>
  </body>
</html>

之後在CMD輸入指令

npm i -D html-webpack-plugin

在資料夾type_react_demo目錄下新增webpack.config,js

const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html',
      filename: 'index.html',
    }),
  ],
};

之後修改package.json的內容

  "scripts": {
    "build": "webpack --mode production",
    "start": "webpack-dev-server --open --mode development"
  },

CMD執行 npm install --save-dev webpack-dev-server

npm start

之後就會看到瀏覽器跳出localhost:8080

按F12 





可以看到我們的HelloWorld出現

最後再加入.gitnore檔案到type_react_demo目錄


node_modules
dist
.DS_Store


CMD輸入npm i -D typescript ts-loader

一樣在資料夾type_react_demo目錄下新增tsconfig.json

並輸入以下內容

{
  "compilerOptions": {
    "target": "es6", //指定編譯生成的JS版本
    "module": "es6", //指定生成哪種模組
    "strict": true, //採用嚴格模式  
    "esModuleInterop": true, //兼容模組導入的方式
    "skipLibCheck": true,
    "noEmit": true,
    "sourceMap": true,
    "moduleResolution": "Node",
    "resolveJsonModule": true
  },
  "include": [
    "./src/**/*"
  ]
}

把之前創的webpack.config.js修改為以下內容

const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/index.ts',
  resolve: {
    extensions: ['.js', '.ts', '.tsx'],
  },
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        loader: 'ts-loader',
        exclude: /node_modules/,
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html',
      filename: 'index.html',
    }),
  ],
};


然後把index.js刪掉 加入index.ts

function log(str: string) {
  console.log(str);
}

log('Hello World!!!');



在CMD輸入

npm i -D @babel/core @babel/preset-env @babel/preset-typescript

新增.babelrc

{
  "presets": ["@babel/preset-env", "@babel/preset-typescript"],
  "plugins": ["@babel/plugin-proposal-class-properties"]
}


修改webpack的設定如下

module: {
    rules: [
      {
        test: /\.tsx?$/,
        loader: 'babel-loader',
        exclude: /node_modules/,
      },
    ],
  },


在CMD輸入 npm i -D @babel/plugin-proposal-class-properties


修改package.json如下

{
  "name": "type_react_demo",
  "version": "1.0.0",
  "description": "demoproject_typescript_react",
  "main": "index.js",
  "scripts": {
    "build": "npm run type-check && webpack --mode production",
    "start": "webpack-dev-server --open --mode development",
    "type-check": "tsc"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@babel/core": "^7.17.10",
    "@babel/plugin-proposal-class-properties": "^7.16.7",
    "@babel/preset-env": "^7.17.10",
    "@babel/preset-typescript": "^7.16.7",
    "html-webpack-plugin": "^5.5.0",
    "ts-loader": "^9.3.0",
    "typescript": "^4.6.4",
    "webpack": "^5.72.0",
    "webpack-cli": "^4.9.2",
    "webpack-dev-server": "^4.9.0"
  }
}


接下來就是下載React

在CMD輸入

npm i -S react react-dom

npm i -D @types/react @types/react-dom

在tsconfig內的compileroptions加入

    "jsx": "react",


把原本的index.ts刪除

另外新增一個index.tsx

import React from 'react';
import ReactDOM from 'react-dom';

const App = () => {
  return <div>Hello World</div>;
};

ReactDOM.render(<App />, document.getElementById('root'));

index.html也要跟著改

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>React Plus TypeScript</title>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>

在babelrc內加入以下設定

    "@babel/preset-react",


最後修改webpack內entry的路徑

entry: './src/index.tsx',

修改完後執行npm start




就可以看到Hello World

專案的環境也都設定好了


之後在src建立一個data資料夾並在data資料夾內建立一個pizza.json

[
  {
    "id": 1,
    "name": "Napoletana",
    "description": "Fresh tomatoes and mozzarella cheese.",
    "price": 14.99
  },
  {
    "id": 2,
    "name": "Marinara",
    "description": "Fresh tomatoes, extra virgin olive oil, oregano and garlic.",
    "price": 14.99
  },
  {
    "id": 3,
    "name": "Caprese",
    "description": "Fresh mozzarella, tomatoes, basil and balsamic vinegar.",
    "price": 14.99
  },
  {
    "id": 4,
    "name": "Margherita",
    "description": "Fresh tomatoes, mozzarella cheese, fresh basil, salt and extra-virgin olive oil.",
    "price": 14.99
  }
]

在src建立一個component資料夾並在此資料夾內建立Pizza.tsx 與App.tsx

Pizza.tsx

import React from 'react';

// 定義Pizza的介面
interface Pizza {
  id: number;
  name: string;
  description: string;
  price: number;
}

// 定義Props的介面
interface Props {
  pizza: Pizza;
}

// React.FC<Props> 代表型別是Functional Component, 泛型的型別是Pizza
const Pizza: React.FC<Props> = ({ pizza }) => {
  return (
    <li>
      <h2>{pizza.name}</h2>
      <p>{pizza.description}</p>
      <p>{pizza.price}</p>
    </li>
  );
};

export default Pizza;


App.tsx

import React from 'react'
import Pizza from './Pizza';
import pizzas from "../data/pizza.json"

const App = () => {
  return (<ul>
    {pizzas.map((eachPizza) =>{
      return <Pizza key = {eachPizza.id} pizza = {eachPizza}/>
    })}
  </ul>)
};

export default App


外面的index.tsx修改如下

  import React from 'react';
  import ReactDOM from 'react-dom';
  import App from './components/App';

  ReactDOM.render(<App />, document.getElementById('root'));


執行npm start就可以看到內容了