寫得很好,順利完成!
很好!順利通過!
很好!順利完成!
OK,順利通過!
寫得很好!網頁很漂亮!順利通過!
寫得很好!順利完成!
畫面整齊、漂亮,寫得很好!順利通過!
寫得很好,順利通過!
寫得很好,順利通過!繼續保持!
OK,順利過關!
有 bug,看我前面留言~
有 bug,多個待辦的時候,後面的已完成按鈕,點擊後,文字不對喔!
OK 花了不少時間,我終於研究完了 主要問題出在這裡 ``` data() { return { weightChart: null, // ...others } }, ``` 放在 data 這邊的,會被引進 vue 的 reactivity 機制 但是,我們並不希望 weightChart 被 vue 監聽、自動更新 我們希望透過 `this.weightChart.update()` 手動更新,也就是我們自己管理相關 state,然後手動去觸發更新 這種情況,把 weightChart 移到 data 外面即可,就變成普通的物件屬性,不會具有 reactivity ``` weightChart: null, data() { return { // ...others } }, ``` 執行之後會發現,「新增」沒問題了,但是「刪除」依然有問題 繼續觀察程式碼,可能有關的是這裡 ``` this.weightChart = new Chart(this.$refs.weightChartDOM, { type: 'line', data: { labels: this.dates, datasets: [{ label: '體重', data: this.weights, borderWidth: 1 }] }, }); ``` labels 與 datasets 期待的是陣列資料 使用 `console.log(this.dates)` 觀察變數型別,會發現我們傳進去的是帶有 vue reactivity 功能的 data(vue 使用 proxy 實作) Chart.js 內部可能也有在監聽 `變數` 變化的機制,所以衝突 來試著把這邊的 reactivity 也拿掉。方法有很多種,我這邊用最土炮的一種:轉成 JSON 字串再轉回來 ``` this.weightChart = new Chart(this.$refs.weightChartDOM, { type: 'line', data: { labels: JSON.parse(JSON.stringify(this.dates)), datasets: [{ label: '體重', data: JSON.parse(JSON.stringify(this.weights)), borderWidth: 1 }] }, }); ``` 除此之外,在新增、刪除的最後 ``` this.weightChart.data.labels = this.dates this.weightChart.data.datasets[0].data = this.weights this.weightChart.update() ``` 也一併改掉,讓事情單純一點:我們都按照 Chart.js 期待的資料型態去傳 ``` this.weightChart.data.labels = JSON.parse(JSON.stringify(this.dates)) this.weightChart.data.datasets[0].data = JSON.parse(JSON.stringify(this.weights)) this.weightChart.update() ``` 大功告成!解決問題! --- ### 備註一 就跟其他眾多解法一樣:以上這做法,也只算是 workaround 因為我們沒有興趣深入研究 Chart.js 監聽 labels 跟 datasets 的變化機制 (通常只有 senior developers 會在這時候想深入進去搞懂) 既然都是 workaround,就隨便找個方法搞定就是了,解法不一定很有道理(我們根本沒有100%搞懂) ### 備註二 proxy 型別,一般來說,會跟普通的資料型別相容 也就是說,通常把 vue reactivity 狀態,直接傳給第三方套件,根本沒問題! 不需要這樣 JSON 轉來轉去的!這是一個剛好 vue 跟第三方套件衝突的特例! ### 備註三 實務上,這種高互動的 UI library,都會自己出一套框架版本的,先處理掉地雷 實務上以使用框架版本為主,所以不會太常碰到這種需要 workaround 的情況(但偶爾還是會遇到) 本課的原意是故意不用框架版本,練習看看手動整合,沒想到真的踩到地雷 (但是也好,也是一種練習) ### 備註四 在前端框架領域,整合框架 `狀態` 與 `html 元件`、`第三方外部元件` 時,有兩種哲學 第一種哲學就是通通由框架處理好,這種元件稱之為 `controlled components`。開發元件時比較吃力,但使用元件時比較輕鬆 第二種哲學就是,自己手動管理外部元件的狀態,這種元件稱之為 `uncontrolled components`。開發元件時比較輕鬆,但使用元件時比較吃力 可以 google 搜尋 `controlled components vs uncontrolled components`,看不懂沒關係,有更多使用套件的經驗之後,會開始看懂我在講什麼
看了幾篇 stackoverflow 大家的分享,都是使用 `workaround` 來描述解決方法 也就是這個 vuejs 跟 chartjs 的衝突,有點尷尬、難以漂亮解決 並不能根本解決,但能避開問題,有替代的解決方法
看到這貼文,我研究了快一小時,我也卡關了,我也看不出為甚麼,哈哈 我 google 搜尋 `chartjs vue RangeError: Maximum call stack size exceeded` 發現這問題很多人遇到,算是一種地雷 會說是「地雷」是因為,光看你寫的程式碼,很合理,感覺根本沒什麼問題 但遇到的人都會耗上大量時間,才知道是 chartjs 底層或者 vuejs 底層有什麼「奇怪」的注意事項 程式開發就是這樣,有時候問題很不直觀。踩雷之後,就學個經驗,多踩就不怕了 我再找時間研究一下,有心得再跟大家說 (實務上,這種高互動的 UI library,都會自己出一套框架版本的,先處理掉地雷,實務上以使用框架版本為主)
寫得很好!UI/UX 也很棒!順利完成!
這是 jsfiddle 首頁,沒東西顯示喔~
寫得很好!UI/UX 非常漂亮!順利完成!
我打開是空白頁面,環境設定好像有問題
很好,順利完成!
OK,順利通過! 不需要一次通通搞懂,有機會再鑽研、練習更多即可!
的確都是很好用的特別屬性!
chrome extension 值得玩一玩!
寫得很好,順利完成!繼續保持!
可以了,順利通過! 不需要一次通通搞懂,有機會再鑽研、練習更多即可!
關鍵字 `setup a personal blog with github pages` `github pages 教學`
Looks good!
寫得很好!遠超過本課所期待的標準!非常出色!
別擔心,寫得很好!順利通過! 發問的話,請在「討論專區」為主,我統一在那邊回答!
我把標題的前面,改成系列數字囉~
順利過關!
精選技術文章、免費程式設計資源、以及業界重要新聞!
也歡迎訂閱 YouTube 頻道,觀看每週二晚間的《CodeLove Talk》直播節目,一起討論軟體開發相關的話題!