1. 程式人生 > >ASP.NET Core + Vue 小專案:構造自己的線上 Markdown 筆記本應用

ASP.NET Core + Vue 小專案:構造自己的線上 Markdown 筆記本應用

ASP.NET Core + Vue 小專案:構造自己的線上 Markdown 筆記本應用

目錄

  • 概要
  • 知識點
  • 完整示例圖
  • 程式碼與資原始檔
  • 流程步驟

 

概要

  基於 MVP 最小可行性產品設計理念,我們先完成一個可以使用,並具備基本功能的 Markdown 筆記本應用,再進行逐步完善。

 

知識點

  本文會指導初學者如何運用 Vue 的計算屬性、雙向繫結、指令、生命週期鉤子,還有 localStorage 和非同步請求等知識點。

 

完整示例圖

   

程式碼與資原始檔

   https://github.com/liqingwen2015/MarkdownDemo

  為了避免網路原因造成的問題,文中所使用的第三方庫(可自己去官方下載最新版,文章使用的是當前釋出時間最新版本的 js 檔案)以及 css 檔案都下載好並且已經放入裡面。

 

流程步驟

  1.先構建一個基本的 html 檔案,並引入核心 js 庫。

  這裡需要引入的第三方庫為 vue.js、marked.js。

<html>

<head>
    <title></title>
    <!-- 引入樣式檔案 -->
    <link rel="stylesheet" href="index.css" />
</head>

<body>
    <!-- 引入 js 庫 -->
    <script src="/lib/vue.js"></script>
    <
script src="/lib/marked.js"></script> <!-- js 程式碼 --> <script src="index.js"></script> </body> </html>

 

  因為考慮到專案主要劃分為兩塊,左邊是書寫區域,右邊為預覽區域,<body> 塊程式碼修改為:

<body>
    <!-- 引入 js 庫 -->
    <script src="lib/vue.js"></script>
    <script src="lib/marked.js"></script>

    <div id="app">
        <!-- 主區域:書寫 -->
        <section class="main"></section>

        <!-- 預覽區域 -->
        <aside class="preview"></aside>
    </div>

    <!-- js 程式碼 -->
    <script src="index.js"></script>
</body>

 

  修改 js 程式碼:建立 Vue 例項,並將其掛載到 DOM 元素上。

new Vue({
    el: '#app'
})

 

  【備註】上面的掛載方式是比較常見的一種,我們也可以使用 app.$mount('#app') 進行掛載。

 

  2.接下來我們使用 Vue 的雙向繫結機制控制輸入的內容和預覽的內容。

  修改 html:

<body>
    <!-- 引入 js 庫 -->
    <script src="lib/vue.js"></script>
    <script src="lib/marked.js"></script>

    <div id="app">
        <!-- 主區域:書寫 -->
        <section class="main">
            <textarea v-model="editor"></textarea>
        </section>

        <!-- 預覽區域 -->
        <aside class="preview">
            {{editor}}
        </aside>
    </div>

    <!-- js 程式碼 -->
    <script src="index.js"></script>
</body>

 

  修改 js,增加資料屬性:

new Vue({
    el: '#app',
    data() {
        return {
            editor: '編輯器'
        }
    }
})

 

  現在,開啟 index.html 頁面,在瀏覽器頁面中的左側進行輸入就可以在預覽視窗中同步看到輸入後的情況。

 

  3.接下來,我們需要對輸入的內容經過 Markdown 形式轉換,在這裡,我們使用 Vue 的計算屬性來進行優化渲染 Markdown 的實時預覽

  修改 js:

new Vue({
    // 掛載
    el: '#app',
    
    // 資料
    data() {
        return {
            editor: '編輯器'
        }
    },

    // 計算屬性
    computed: {
        editorPreview() {
            return marked(this.editor);
        }
    }
})

 

  修改 <body>,使用 v-html 指令取代 {{ }},以這種方式來渲染 HTML 元素。

<body>
    <!-- 引入 js 庫 -->
    <script src="lib/vue.js"></script>
    <script src="lib/marked.js"></script>

    <div id="app">
        <!-- 主區域:書寫 -->
        <section class="main">
            <textarea v-model="editor"></textarea>
        </section>

        <!-- 預覽區域 -->
        <aside class="preview" v-html="editorPreview"> </aside>
    </div>

    <!-- js 程式碼 -->
    <script src="index.js"></script>
</body>

 

  執行效果圖

 

  4.儲存內容

  目前,如果關閉了瀏覽器或者對頁面進行了重新整理,所有內容都會丟失。所以,我們目前使用 localStorage  的方式進行資料的儲存操作。

  現在產生了一個疑問:應該什麼時候進行儲存呢?

  我們現在使用 Vue 的偵聽器功能來對資料的改動進行儲存操作,因為它可以監聽到 editor 的每一改動操作,意思是每次輸入操作都會觸發偵聽器裡面的方法。

  修改 js:

new Vue({
    // 掛載
    el: '#app',

    // 資料
    data() {
        return {
            editor: '編輯器'
        }
    },

    // 計算屬性
    computed: {
        editorPreview() {
            return marked(this.editor);
        }
    },

    // 偵聽器
    watch: {
        editor(val) {
            localStorage.setItem('editor', this.editor);
        }
    }
})

 

  那麼現在又產生了新的疑問:應該怎樣才能夠在每次進入這個頁面時顯示之前儲存的資訊呢?

  現在,我們通過利用 Vue 的生命週期鉤子(目前使用 created 鉤子)來進行資料的讀取及恢復。

  修改 js:

new Vue({
    // 掛載
    el: '#app',

    // 資料
    data() {
        return {
            editor: '編輯器',
            key: {
                editor: 'editor'
            }
        }
    },

    // 計算屬性
    computed: {
        editorPreview() {
            return marked(this.editor);
        }
    },

    // 偵聽器
    watch: {
        editor(val) {
            localStorage.setItem(this.key.editor, this.editor);
        }
    },

    // 生命週期鉤子
    created() {
        this.editor = localStorage.getItem(this.key.editor) || '第一次使用 Markdown 筆記本';
    }
})

 

  【備註】在進行修改 js 後,editor 屬性第一次載入的時候可能為 null,這會導致整個應用出錯,所以這裡採用了預設值。

 

  5.localStorage 畢竟不是永久儲存的方式,這裡我使用一種較為簡單的方式,儲存方法替換為非同步請求到 WebApi 介面儲存到資料庫的方式

  修改 html,引入 axios 庫:

<script src="lib/axios.min.js"></script>

 

  同時,修改 js,增加兩個 Http 請求的方法,獲取和儲存:

new Vue({
    // 掛載
    el: '#app',

    // 資料
    data() {
        return {
            editor: '',
            key: {
                editor: 'editor'
            },
            url: 'http://localhost:34473/api/markdown'  // 需要替換成自己的 API 路徑
        }
    },

    // 計算屬性
    computed: {
        editorPreview() {
            return marked(this.editor);
        }
    },

    // 偵聽器
    watch: {
        editor(val) {
            //localStorage.setItem(this.key.editor, this.editor);
            this.save();
        }
    },

    // 生命週期鉤子
    created() {
        this.load();
        // this.editor = localStorage.getItem(this.key.editor) || '第一次使用 Markdown 筆記本';
    },

    // 方法
    methods: {
        load() {
            var that = this;
            axios.get(that.url).then(function (result) {
                console.log(result.data);
                that.editor = result.data;
            });
        },
        save() {
            var that = this;
            axios.post(that.url, { content: that.editor }).then(function (result) { });
        }
    }
})

 

  新增的 API 控制器 MarkdownController.cs 的內容如下:

    [Route("api/[controller]")]
    [ApiController]
    public class MarkdownController : ControllerBase
    {
        public static MarkdownViewModel MarkdownViewModel = new MarkdownViewModel()
        {
            Content = "我的第一個 Markdown 應用"
        };

        [HttpGet]
        public ActionResult<string> Get()
        {
            return MarkdownViewModel.Content;
        }

        [HttpPost]
        public void Save([FromBody] MarkdownViewModel vm)
        {
            MarkdownViewModel = vm;
        }
    }

 

  檢視模型 MarkdownViewModel.cs 的內容如下:

    public class MarkdownViewModel
    {
        public string Content { get; set; }
    }

 

  【備註】需要自行進行 WebApi 的跨域配置,演示時進行了忽略配置  

  【備註】示例程式碼可從 https://github.com/liqingwen2015/MarkdownDemo 下載

 

【切換閱讀方式】https://www.jianshu.com/p/a17033ca91d9
【參考】Vue.js 2 Web Development Projects