2020年12月25日 星期五

React api 管理及應用 axios

    最近剛拿到 React 的 offer ,惡補一下,看六角的洧杰老師的文章提到最好是七成舊,三成新才比較容易聚焦問題避免整組壞光光不知道從何改起,或是進步太少,之前用 Vue Promise 處理 API 駕輕就熟,直到看到 Mike 的文章跟面試真的有人問有幾十隻 API 分散在不同 component 要怎麼處理,才拿這篇出來救駕,今天來實作如何用建立一個 JS 檔案的方式管理 API。

首先先建立拿來管理 API 的檔案 api.js

然後 import axios

import axios from 'axios';

建立不同大分類以及 baseUrl

const sixUrl = axios.create({
  baseURL: 'https://course-ec-api.hexschool.io/'
})

每個大分類下的不同分支 API

export const productList = () => sixUrl.get(`api/${uuid}/ec/products`)

uuid 是 get 六角 API 用的就不貼了,可依照各 API 權限控管進行調整。

回到需要使用的頁面,import api.js,並且選擇有 export 的 API

import { productList } from "./api";

透過 async await 完成 getData

function Home() {
  async function getData () {
    try {
      const item = await productList()
      console.log(item)
    } catch (err) {
      console.log(err)
    }
  }
  console.log(getData())
  return (
    <div>
      <h2>Home</h2>
    </div>
  );
}

console.log(item) 有資料就成功啦,基礎用法就到這邊,接下來要研究如何與 hook 一起使用作畫面更新。


參考資料:

Mike 的文章

2020年12月11日 星期五

Vue 使用 vue-drag-drop 完成 Drag & Drop

 Drag & Drop 就是網站的拖曳效果,今天要達成的目標就是有兩個區域A及B,裡面有資料,

把資料拖曳到任一個區域都可以在該區域新增資料,並刪除原區域內的資料。透過 HTML 的

拖放 API,設定多而且 DOM 的長度可觀。


原理簡略的說: Drag 是可拖動的物件,Drop 是可放置的區域,透過今天使用的套件,可以使 

Drag 帶著資料去觸發 Drop 的事件,達成放置資料或其他操作。


import VueDragDrop from 'vue-drag-drop';
Vue.use(VueDragDrop);

先 import 跟 use,官方文件有一個範例,比較接近 Basic list support ,不過這個範例有幾個需要

改變的地方,第一個是兩個區域不能總貼在一起,再來是如何讓排列順序是有序的,範例中

使用 .sort 進行陣列重排,我希望跟積木一樣可以使用者將資料移到那就把資料放在那。


<template>
<div>
  <div class="container">
    <div class="row">
      <div class="col-3">
        <div class="drop">
          <div v-for="(item, i) in testList[0]" :key="i">
            <drop @drop="drop1(item, ...arguments)">
              <drag class="drag"
                :transfer-data="{ item: item, list: testList[0], example: 'lists' }">
                {{ item }}
              </drag>
            </drop>
          </div>
        </div>
      </div>
      <div class="col-9">
        <div class="drop">
          <div v-for="(item, i) in testList[1]" :key="i">
            <drop @drop="drop2(item, ...arguments)">
              <drag class="drag"
                :transfer-data="{ item: item, list: testList[1], example: 'lists' }">
                {{ item }}
              </drag>
            </drop>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>
</template>


template 使用 bootstrap 進行簡單的排版,左右有兩個框,分別放置 testList[0] 跟 testList[1] 的

陣列,裡面的資料稍微用 CSS 讓資料變清楚,不同的區域基本方法是相同只是觸發區域

不一樣,可以看到每個 item 有一個 drop 讓 drag 可被放上去,也有 drag 讓 item 可被拖曳,

<drag> 以及<drop> 標籤就是 vue-drag-drop 套件替你省下了無數的 DOM 指令。


@drop(item, ...arguments) 方法是官方推薦的,表示當 drag 被放進 drop 時觸發的方法,第一個參數是 drop 所在的元素,第二個參數是 drag 額外帶的 data。 drag攜帶資料的方法:

<drag class="drag"
                :transfer-data="{ item: item, list: testList[1], example: 'lists' }">

利用 :transfer-data,攜帶 drag 的 item ,所在的 array ,或其他。


最後處理方法,只要清楚 drag 在哪? drop 在哪? 那哪裡應該放置新資料或刪除已移動的資料就是小事了。splice(索引, 從索引之後刪除幾項, 加入的資料)。


methods: {
    drop1 (item, data) {
      const testlist = data.list
      // drag 所在的陣列
      this.testList[0].splice(this.testList[0].indexOf(item), 0, data.item)
      // 接收的 drop 新增 item
      testlist.splice(testlist.indexOf(data.item), 1)
      // 刪除原陣列的 item
    },
    drop2 (item, data) {
      const testlist = data.list
      // drag 所在的陣列
      this.testList[1].splice(this.testList[1].indexOf(item), 0, data.item)
      // 接收的 drop 新增 item
      testlist.splice(testlist.indexOf(data.item), 1)
      // 刪除原陣列的 item
    }
  }


成品圖:兩個區域為了清晰加了一個固定大小的框,所以如果全部資料都在同一個區域會爆版,自行調整 CSS 即可。




參考資料:

MDN

vue-drag-drop 文件

2020年12月7日 星期一

vue-chart.js 及 Chart.js 在 Vue 中製作圖表

 Chart.js 是個可以方便製作圖表的 JavaScript library,可以在 HTML 中產生一個 canvas 物件產生

圖表。這篇以線圖舉例。


首先先 npm 安裝

npm install vue-chartjs chart.js --save


 Chart.js 的基本寫法是 new Chart,綁定一個 ID,裡面有三個參數:圖表類型( examle: line )、

資料內容 ( data )、選項( option ),HTML 中的 canvas 物件可以直接設定大小,但今天用 Vue,

所以要看看有什麼不同。


首先用 Vue 渲染的 canvas 是不能有 template 的,意味著通常要用 components 方式載入,不然整個畫面只有圖,使用 .vue 或 .js 檔案皆可,筆者比較習慣用 .vue。先製作空白圖表的 components。

在components 資料夾下新增 Chart.vue


import { 圖表種類 } in 'vue-chartjs';
extends: 圖表種類,
使用 mounted 得到資料後繪圖,圖表種類已經 import 過了,所以剩下 data、option 兩個參數。
一張圖表可以輸入不同的資料匯出不同的線圖,所以用 props 讓空白的表接收父組件的數據。

接下來回到父組件:

import 子組件 + components 子組件

import Chart from '../components/Chart.vue';
components: {
    Chart,
  },

template 放入組件的部分:

<template>
  <div>
    <div class="container">
      <div class="row">
        <div class="col-6">
          <chart v-if="loaded"
            :chartdata="chartdata"
            :options="options">
          </chart>
        </div>
      </div>
    </div>
  </div>
</template>


筆者有用 bootstrap 框架,這樣可以控制子組件,也就是圖表的大小,將 data 與 option 傳入組件,
為什麼要加上 v-if ?因為組件得到數據之後,"不會"重新繪圖
所以要透過確認有得到數據才繪圖。


json 格式的 data,沒有 API ,用 json-server 模擬從 API 得到資料,npm install -g json-server,用 VSCode ctrl+`打開終端機,然後 json-server --watch 想要觀測的檔案,沒取名照教學是db.json,npm install --save axios vue-axios 用來串接 API,別忘了 main.js 要加入 Vue.use(VueAxios, axios) 。


資料格式:

 data() {
    return {
      chartdata: {
        labels: [],
        datasets: [
          {
            label: '0050',
            fill: false,
            backgroundColor: 'rgba(188,96,147,1)',
            borderColor: 'rgba(212,85,49,1)',
            pointBackgroundColor: 'rgba(41,56,69,1)',
            data: [],
          },
        ],
      },
      options: {
        title: {
          display: true,
          fontSize: 24,
          text: '2020/11 0050 價格走勢',
        },
      },
      loaded: false,
    };
  },


chartdata 與 option 都必須是物件,chartdata 裡面就是 data,有兩個屬性,第一個 lebal 是 x 軸的值,是陣列,而 y 軸的值放在 datasets 的 data 下面。

將 json server 的數據陣列加入,並在 create 階段載入:

created() {
    this.getData();
  },
  methods: {
    getData() {
      const api = 'http://localhost:3000/0050';
      this.$http.get(api).then((res) => {
        this.chartdata.labels = res.data[0].Date;
        this.chartdata.datasets[0].data = res.data[0].Price;
        this.loaded = true;
        this.$forceUpdate();
      }).catch((error) => {
        if (error) {
          console.log(error);
        }
      });
    },
  },


中間有混入一個 loaded ,就是剛剛提到的拿來判斷是否收到數據,啟動子組件的繪圖。

最後就是剩下看文件找適合的選項把標題跟圖表畫的美美的。


附上 json 的結構,這個表是從證交所下載 .csv 並手動重製,x 軸為時間,y 軸為當天價格:



 


參考資料:

https://www.chartjs.org/

https://vue-chartjs.org/

https://dylan237.github.io/json-server.html

2020年12月4日 星期五

npm報錯:code ENOENT

 Google了一下發現是 npm 不知為何找不到正確的路徑,解決方法是

將 node_modules 資料夾刪除,再重新 npm install,之後就恢復正常了。


嘗試過 npm cache clear、npm install 有安裝過的套件、更新 Node.js 及 Vue Cli。


參考資料:

https://blog.csdn.net/weixin_43170297/article/details/96436565

https://stackoverflow.com/questions/17990647/npm-install-errors-with-error-enoent-chmod/23446110

https://juejin.cn/post/6864809486675574792

2020年12月2日 星期三

初學 TypeScript,型別註記的方法

 TypeScript 是強型別語言,相對於 JavaScript 的弱型別,例如 1 可以是 number ,也可以是 '1' 字串,如果是外部資料甚至是自己筆誤會得出錯誤結果而不自知。


TypeScript 簡單的定義型別的方法是用 : ,例如:

let name: string = 'Jack';


物件的定義:

let account: {name: string, password: string} = {

  name: 'Jack',

  password: 'abc4567',

};


函式的定義:


let addition = function(param1:number, param2:number) {

  return param1 + param2;

};


使用 type 作出一組型別定義,使用方法跟上述一樣接在:後面:

type accountInfo = {

  account: string,

  password: string,

  nickname: string,

  birth: Date,

  subscribed: boolean,

};


在 TypeScript 覆寫物件屬性值會有一個問題是必須完全覆寫,但以帳號資料或購物資料表單為例,實務上常常會有許多選填,因此需要選用註記?。


type accountInfo = {

  account: string,

  password: string,

  nickname?: string,

  birth?: Date,

  subscribed?: boolean,

};


let accountData: accountInfo = {

  account: 'Jack',

  password: 'abc1234',

}

雖然缺少了 nickname...等三個屬性沒有完全覆寫,但可以通過 TypeScript 的檢驗,筆記資料較為精簡,原文有詳細及深入的範例探討,有鐵人賽文章及實體書可選看。

參考資料:讓 TypeScript 成為你全端開發的 ACE! Day1~Day9

2020年11月29日 星期日

在 Windows 使用 Vue cli ,Vue2 + TypeScript

 首先安裝 Node.js

 官網

windows 使用 win + R ,輸入 cmd 叫出命令提示字元,接著確認 Node.js 有無安裝成功,輸入

node -v。


有出現 Node.js 的版本號就可以進行下一步安裝 Vue Cli,在命令提示字元輸入 npm install -g @vue/cli。


一樣確認版本,輸入 vue -V。


最後可以選擇用指令或是 UI 來操作,我習慣用 UI ,可以不用一直打 npm run serve,在命令提示字元輸入 vue ui 打開 vue cli 的 UI。




正要用 Hexo 做部落格放自己的文章,所以就取叫 blog ,用 Github 可以順便把下面初始化 Git 倉庫打勾,下一步。



這一頁的設定就比較多:
  • Babel 是轉譯 ES6 語法...等等向下相容用。
  • TypeScript 是 JavaScript 強型別的改進,正要順便練習所以加入。
  • Router 是作 SPA 用的路由,如果重視 SEO, 一種是不用 Router,一種是加入 Nuxt.js。
  • Vuex 是不同路由之間轉傳資料的倉庫。
  • CSS Pre-processors 是 CSS 預處理器,筆者習慣用 SASS 所以要選,沒選也可以之後再加入。
  • Lint 是規範,ESLint 多一些,從善如流選起來。
  • Unit Testing 單元測試,寫簡單的小測試可以用,選一下。



選擇詳細的自訂選項,筆者比較常用 SASS 、ESLint、Jest,選好就可以按新增嚕。

首頁:



任務:



任務這邊會有常用的需要指令,開發時的編譯、部屬、測試...等等,當然也可以再導入 CI/CD 

工具,先介紹到這,順便幫自己回憶一下 Vue Cli 的安裝與操作。










2020年11月20日 星期五

初學 Vuex

        Vuex 就是比較大型的儲存庫的概念,裡面存儲的數據可以傳給各個 .vue 檔,也可以傳

回來,規模大小是 Vuex(比較有規範跟方法) > store(開一個js檔案存) > eventbus(內外元件)。


首先安裝,筆者是用 Vue Cli 開發,用 npm 安裝,當然 yarn 也可以。

npm install vuex --save

在 main.js 中使用

import Vuex from 'vuex'

Vue.use(Vuex)

new Vue 裡加入 store,ES6 中 store: store 可以簡寫。



同樣在 main.js 中建立倉庫。


state 是儲存資料的地方,可以很多筆,跟 store 差異最大的地方是:改變 state 的資料時,必須

使用 mutation 裡的方法,例如 store.commit('increment', 10),方法可以加入參數,所以上式就

可以將 count + 10。


在另外一個 .vue 檔實際讀改數據。

頁面還有其他東西,所以 <template> 部分標籤跟 method 的 } 有興趣嘗試的自行補上,count 

跟item 透過 this.$store.state 可以顯示為0 ,當按下按鈕觸發 addStore 的時候,利用 

this.$store.commit('mutation裡的方法',可選的參數),來更改 state 裡的資料。

目前只看到基本用法,其他就留待日後研究。



2020年11月13日 星期五

Git Flow 與版本控制

 Git Flow 就是利用 Git 的分支功能進行開發流程管理的一種方法,Git Flow 主張利用 master 、

develop 、 hotfix 、 release 、 feature 五種分支進行管理。


master:存放穩定上線版本,並附上版本號。

develop:開發用分支,真正的主分支,要開發的功能從這個分支出去到 feature ,開發完之後也合併回 develop。

feature:開發功能時從 develop 出來,開發完合併回 develop。

release:最後測試用分支,當 develop 版本要上線時,在 release 進行測試,之後上線同時與 master、 develop 進行合併。

hotfix:如果 master 還是不幸出大事( bug ),就開 hotfix 來修,修好合併回 master 及 develop。


從上述過程中,各修正如果修好了都要同時對 master 與 develop 合併,是比較複雜,並且 

develop 看起來比較像 master 主導整個專案運作。


因此就產生了 Github Flow 與 GitLad Flow ,將關注點重新回到 master 上,新功能依然使用

新分支,開發完成合併回 master ,但上線版本時間不一定與 master 相同,因此 GitLab Flow 

主張發布版本額外創一個分支,即 develop --> master --> 上線版本分支,是對於 Git Flow 的

改進。


參考資料:

為你自己學 Git

Git三大特色之WorkFlow(工作流)

2020年11月7日 星期六

Vue Cli 使用 Vue Testing Library 作測試

 打開終端機,輸入 vue ui 先用 Vue Cli 開新專案,選項就一般的 SASS 、 Router 、 ESLint 、

還有這次的主題 Test ,然後會看到 Vue Test Utils 裝好了。然後是神Q超人來六角進行 CI/CD 

講座時的教學,npm Vue Testing Library 可以用簡單的方法 DOM 測試,容後詳述,CI自動化

部屬下篇研究,這篇先介紹寫單元測試:


測試的 JS 檔案有幾種放法:xxx.spec.js、xxx.test.js 或是放在_test_資料夾下,也可以在 

package.json 下作設定


.vue 檔作個簡單的範例:


簡單的按按鈕加一或減一,測試的目標就是按鈕或欄位是否正確。

新增 addtest.spec.js ,測試命名最好簡單直接,可以一眼明白測試什麼用的。


第一步: import 使用到的 Testing Library API ,以及需要測試的 .vue 檔。

第二步:使用 test 寫測試內容,利用 getByTestId 找到 .vue 檔的 data-testId ,選到顯示的數字

第三步: Jest 經典的斷言寫法 expect() ... .toBe ,檢查內容是否相同。

寫完後 npm test 看到勾勾就解決啦。後面還有自動產生錯誤檔的路徑跟內容...等可以延伸,

或是更複雜的測試。


卡關的部分:不會解的地方,如果用 parcel.js 下載下來 postCSS、TailwindCSS,需要 postCSS 

8.0。同樣用 parcel.js 下載,選擇 Vue、SASS、Jest,之後 npm 其他東西,最後寫好作測試的

時候,會有 Cannot find module 'babel-core' 的錯誤,再 google 尋找解法,是 babel7 之後要分開

安裝 babel-core ...等,但始終無法正確執行,找不到是 vue-jest 還是一串哪個路徑錯誤。










2020年11月4日 星期三

三向交握 (Three Way Handshake) 及未來傳輸協議發展閱讀心得

     現今主流的傳輸協議為 HTTP / TCP ,其中由於皆為明文傳輸,因此 HTTP 演進為 HTTPS ,

HTTPS 的差別就是利用加密方法來加密,並且利用信任鏈分散流量,例如 A 是可信賴的憑證發行

機構,那麼通過 A 頒發的 B、C、D ,以及 B 頒發的 E、F、G 皆可信任。


接下來說到 TCP 著名的三向交握傳輸方式,區分為客戶端和伺服器端,算是一種互相試探?

的過程。


首先客戶端向伺服器端發送第一次訊息,內容為簡單可辨識的資料 X 。


伺服器端收到 X 之後,發送第二次訊息,包含收到 X 、

傳送簡單可辨識的資料 Y 、嘗試請求資料 Z 。


最後客戶端發送第三次訊息,包含收到 Y、傳送 Z 。


    這個過程經過簡化,實際上還有傳送一些其他資訊。在參考資料中提到 HTTP/3,與 

HTTP/TCP 相比,差異最大的就是在 UDP 而非 TCP,那麼在加密以及如何省去傳輸內容增加

傳輸速度上就要關心一下。


以下解說引用自參考資料 HTTP/3 傳輸協議 - QUIC 原理簡介:「

初始交握 (Initial Handshake)

在連線的一開始,客戶端會傳送一個哈囉訊息 (CHLO, Client Hello) 到服務端,觸發服務端回傳一個代表交握未建立或是公鑰已經過期的拒絕訊息:REJ 封包,REJ 中包含四比資料:

  1. Server Config:包含服務端的長期DH公鑰 (Diffie-Hellman Public Key)
  2. Certificate Chain:用來對服務端進行認證的憑證串鏈
  3. Signature of the Server Config:經過數位簽章過的 Server Config,讓客戶端可以驗證這些資訊確實是由服務端發出。
  4. Source-Address Token:經過認證加密過後的客戶端IP資訊

在客戶端收到 REJ 後,依照 QUIC的 定義,雙方就已經完成了交握,可以開始安全的傳輸資料。這是為什麼呢?讓我們看看從 REJ 中客戶端得到了哪些資訊:

  1. 服務端的驗證:透過憑證串鏈和數位簽章,客戶端可以驗證服務端的真實性和資料的可靠性。
  2. 初始密鑰 (Initial Key):客戶端在收到 REJ 後,首先要為這次連線隨機產生一個自己的短期DH密鑰,將自己的短期密鑰和服務端的長期公鑰進行運算後,就可以得到一個初始密鑰。(這邊密鑰的交換使用的是 Diffie–Hellman key exchange,如果對這個方法不熟悉的讀者可以參考WIKI連結:Diffie–Hellman key exchange )

此篇先以 Diffie-Hellman Key 作一個斷點,還有其他作法為了速度、以及漏封包...等等的改進

機制,容後再議。


為什麼 Diffie-Hellman Key 可以產生安全的通道?以顏色來舉例:首先 A 與 B 選擇了一個起始

顏色,暫定為 C 與 A 決定其秘密顏色 AC ,B 決定其秘密顏色 BC ,然後分別將起始顏色與

秘密顏色混合 C+AC C+BC ,之後交換 C+AC 與 C+BC的結果,最後將得到的混合顏色加入

自己的秘密顏色得到最終結果, A 為 C+BC+AC、B 為 C+AC+BC,兩者相等,第三者無法

從已知資訊 C 及 C+AC 、 C+BC 推導出 AC 與 BC 的值,當然其中有些數字可以很小,有些

則要非常大,但此處只為了理解如何以簡短的流程產生出第三者無法得知的秘密。


參考資料:

一文搞懂 HTTP 和 HTTPS 是什麼?兩者有什麼差別

[30 天學會 Web 前端效能優化] 4. TCP 三向交握

HTTP/3 傳輸協議 - QUIC 原理簡介

Diffie–Hellman key exchange

2020年10月28日 星期三

CSS 臨摹熊本熊

 成果:



自己畫的最可愛,不過跟本體還是有點落差,有點企鵝感?

結構:


大概就是分成頭、身體、腳,利用 position 把手腳眼睛鼻子耳朵等拼接上去,利用一些圖層

疊加的概念,還有 CSS 旋轉語法。


附上 CSS:





transform: rotate(-30deg);











2020年10月27日 星期二

let const 寫 JavaScript 的習慣養成

        其實現在還有些情況為了相容性,會把寫好的 ES6 語法編譯回去 ES5 ,因此要了解新寫法

與舊寫法的區別實益在哪?在舊的 var 宣告法造成的雷有:

1. 提升:

var math = function () {

console.log( x );

var x = 10

}

console.log( x ) // undefined

由於 function 內有宣告,因此還是可以執行,但是實際上從上到下執行 console.log 的時候,x  還沒宣告,因此是 undefined 。

2. 全域變數:

var x = 1

var math = function (y) {

x = 10;

return x + y

};

console.log( math(3) ); // 13

console.log( x ) // 10

當 JavaScript 在 function 內找不到宣告時,就會一層一層往外找,所以最後就改了最外層的 x 。

    知道這些問題之後,其實只要養成良好的開發習慣不用 let 與 const 也無所謂,但就是加一層

保險, let 用於宣告一個「只作用在當前區塊的變數」,因此不會超出當前區塊; Const 有點像

使用 let 宣告的變數,具有區塊可視範圍。常數不能重複指定值,也不能重複宣告。


結論:為了避免變數遭到預期外的修改,變數都應該先宣告再做使用,並且盡量元件化各自

可以運作,而不是 a 去改 b 、 b 又改 c 造成難以維護與判斷更改數值的源頭。



參考資料:

MDN

008 天重新認識 JavaScript Kuro Hsu 著

2020年10月24日 星期六

Vue.js 資料傳遞, store方法

 架構大概是

A.vue 是 layout 檔案,起始頁面是 A.vue + B.vue(產品列表)的組合,現在要在 B.vue 製作一個

按鈕,可以將被點擊的產品 id 傳遞到 C.vue 的產品詳情頁面,並且跳轉路由使畫面成為 

A.vue + C.vue。



失敗經驗:一開始嘗試用 event bus 製作,但始終失敗,推測原因是其中一篇文章說到:

在 C.vue $on 的時候,B.vue已經$emit過了,時間不同,因此跟兩子組件存在同一頁面中的

互傳情況不同。



store 方法:在 src 下建立 store.js ,內容就為將來要傳遞的資料作定義。


numbers 是教學文章中的數字陣列,str是我想傳的物件資料,下方帶上更改資料用的函式。

之後分別套用在 B.vue 以及 C.vue中。

B.vue


import store.js,然後 data 內有欲傳遞的值,template 有一顆啟動 go() 的按鈕就省略不貼了,利

用 store.addStr(x, y) 將 B.vue 中 products[0] 的 id 以及 title 存在 store.js 的 state.str.id 與 

state.str.title 裡面,下面補上一個 $router.push ,接著就可以去 C.vue 了。


C.vue


在 import store.js 之後,create 階段就可以檢查資料有沒有正確載入,但要在 template 中顯示

還是需要將 store 裡的資料取出來,如上圖所示,之後在 C.vue 中這些都可以正確顯示啦!







參考資料:


2020年10月19日 星期一

JavaScript 傳值、傳址

     這個問題主要是做商品資料更新時候學到的作法:先開一個新陣列或物件儲存 API 傳回來的

資料,從簡易的邏輯來看,修改前跟修改後如果用的是同一筆資料,那修改之後就無法找回

修改前的資料。


    在 JavaScript 中,基本型別的比較是傳值,也就是:

var a = 100;  //number

var b = a; // 100 , number

console.log( a === b ) // 100 = 100

答案會是 true


但是在物件型別,也就是最常需要處理的商品資料中,是傳址,也稱作傳參考,例如:

var c = { price:100 }; //object

var d = { price:100 }; //object

console.log( c === d) // { price:100 } != { price:100 }

答案會是 false,這邊的思考可以想成是加了一個隱藏屬性地址,所以是

{ c , price:100 } != { d , price:100 },c 當然不等於 d ,所以是 false。


這會產生什麼需要注意的事情呢?當有兩個產品價格相同,然後你就快樂寫了

var e = { price:100 };

var f = e    //感覺省了一串

//然後 f 商品要改價格的時候

f .price = 80;

console.log(e); //80

console.log(f); //80

就會產生慘劇,延續上例,也就是 JavaScript 照著地址去把 e 的 price 屬性給改了,所以不同商品要乖乖做好預設值。


例外:function 的參數內的物件被重新賦值(x = y)的時候,外部變數的內容不受影響,但僅止於

此,若更改屬性仍然有效。


參考資料:

《0 陷阱!0 誤解!8 天重新認識 JavaScript!》Kuro Hsu 著

2020年10月7日 星期三

Pointer-events CSS3 在疊加圖層中點擊下層圖層

 pointer-events:auto 預設值

 pointer-events:none 可讓滑鼠點擊不生效,還有其他設置僅限SVG使用,可閱讀參考資料

文章。


這個 CSS 屬性可以在日常利用 position:relative 跟 position:absolute ,做出疊加圖層的時候,上

是漸層色彩或陰影,主要不同按鈕與連結在下層時,在上層增加這個 CSS 屬性後,就可以安心的

在下層做出主要按鈕或連結,而不會點擊到上層圖層導致點不到連結的情況,也可以使網頁結構更加穩

定。



參考資料:https://www.oxxostudio.tw/articles/201409/pointer-events.html

Vue Cli 一鍵部屬 Github Pages win10

 目標:將本地端用 Vue Cli 建立的網站 Git Push 到 Github 並且打開 GitHub Pages。

在 Vue 專案資料夾下建立 deploy.sh。

在 deploy.sh 內建立以下內容:

set -e
originUrl=$(git config --get remote.origin.url)
nowStatus=${originUrl:0:5}
echo $nowStatus
if [ $nowStatus = 'https' ]
then
  echo '傳輸方式採用 HTTPs 模式'
  echo '目前遠端分支 URL:'$originUrl
else
  echo '傳輸方式採用 SSH 模式'
  echo '目前遠端分支 URL:'$originUrl
fi
npm run build
echo '移動目錄到編譯出來的 dist 資料夾'
cd dist
git init
git add .
git commit -m "update `date +'%Y-%m-%d %H:%M:%S'`";
git push -f $originUrl master:gh-pages
cd -

儲存檔案,然後先把編譯前的檔案 Push 到 GitHub 確定不會卡驗證。

筆者是用 VSCode 完成編譯前的檔案上傳。

下載 Git 並安裝。

https://gitforwindows.org/

開啟 Git Bash ,並 cd 到專案資料夾。

輸入 sh deploy.sh  。

最後回到 GitHub 儲存庫,Setting --> GitHub Pages 開啟並把分支設在 gh-pages 上。

過一陣子應該就可以讀出利用 Vue Cli 建立的 SPA 網站了。 


參考資料:https://hsiangfeng.github.io/vue/20200214/1055437216/



2020年9月15日 星期二

在 Vue 應用 SweetAlert

      要做常見的點擊後跳出 moadl 的視窗提醒,用 alert 做關鍵字搜尋發現這個好看的套件, 
 先 npm 安裝 

 npm install -S vue-sweetalert2 

 在 main.js 作 import 

 import VueSweetalert2 from 'vue-sweetalert2'; Vue.use(VueSweetalert2); 

<template>
<button click="showAlert">Hello world</button>
</template>

<script>
export default {
  methods: {
    showAlert() {
      // Use sweetalert2
      this.$swal('Hello Vue world!!!');
    },
  },
};
</script> 

參考資料範例:

  @click 指向方法,然後在方法中簡單一行就可以使用 Sweetalert了,接下來就是更改

預設樣式, 作一些修改。 


 目前作品作的部分:

 addCart (id, quantity = 1) { const api = 

`${process.env.VUE_APP_APIPATH}api/${process.env.VUE_APP_UUID}/ec/shopping` 

 const cart = { product: id, quantity } this.$http.post(api, cart) .then((res) => { this.getCart() 

this.$swal({ icon: 'success', title: '加入購物車成功!', text: '可以繼續選購其他商品', button: 'OK' }) }) 

.catch((error) => {
 
this.$swal({ icon: 'error', title: '加入購物車失敗!', text: '請重新選購', button: 'OK' }) }) }, 


可以看到除了簡單輸入文字外,簡單的在{}內就可以設置icon、title、text

(彈出視窗中間的主要內容)、button(下面的按鈕)。 Sweetalert 內建 icon 有四種樣子,

分別是  "error"  叉叉、 "success"  打勾、 "info" 跟 "warning"  我沒用到,四種常見的 icon , 

除了簡單的樣式之外還可以加入星等評分,甚至一些更複雜的 JS 功能,不過有寫到再研究,

簡單的寥寥幾行就可以有一個漂亮的警示視窗已經很滿意了。 

 參考資料: 

https://sweetalert.js.org/guides/ 

https://www.npmjs.com/package/vue-sweetalert2

2020年9月6日 星期日

製作表單圓角框 input 前方帶 icon 的方法

 成品圖:




之前一直以為要用定位(position)的方法才能完成,直到今天在六角 slack 群看到回覆才學到

原來如此簡單。


首先基本的 HTML ,其中 all.css 是 FontAwesome 的資料夾裡面的 all.css , style 則是

自訂等等放其他設定的 CSS 檔案。


基礎表單設定,外面加個框避免太大太奇怪而已,一般的輸入框也就300-500px足以,<form>、

<button>、<input>標籤是表單的基礎內容。


placeholder="icon" 裡面是框框底下的提示字,一般就是請輸入XX或輸入N-M位數字之類的,

class 因為是簡單的例子就照位置隨便取。


<i class="fab fa-accusoft"></i> 是FontAwesome的圖案。


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="css/all.css">
    <link rel="stylesheet" href="style.css">
</head>
<body>
<div class="formWidth">
  <form class="form">
    <button type="button" class="button"><i class="fab fa-accusoft"></i></button>
    <input placeholder="icon" type="text" class="input"
  </form>
</div>
</body>
</html>

.formWidth{
    width: 300px;
}
.form{
    display: flex;
    margin: 0 10px 50px;
    border-radius: 100px;
    border: 1px solid #000;
}
.button{
    width:15%;
    border: none;
    background-color: transparent;
    padding: 5px 10px;
}

.input{
   width:85%;
   border: none;
   padding: 5px 10px;
   background-color: transparent;
}
input:focus,
button:focus {
    outline: none;
  }


一、 display:flex將上下排列的<input>跟<button>排成橫線。

如果還是兩行先做完兩步再檢討


二、 調整比例 width 跟 padding 、 magin。


三、 設定圓角跟框線:

border-radius: 100px;
    border: 1px solid #000;

四、 將<input>跟<button>背景設成透明:

因為框線是由最外層產生的,因此裡面的兩個背景會吃掉部分框線,所以要設成透明避免蓋住框線。

五、 :focus效果:

focus 效果是滑鼠點一下之後會在外圍有一個框框跟一根的指示條告訴使用者現在正在輸入或點擊的

欄位,但在此因為是外層是圓的,內圈一點之下沒改過方方的外型就露餡了,所以要改成 none。







參考資料:https://hsuchihting.github.io/css/20200723/3601848445/