iT邦幫忙

2021 iThome 鐵人賽

DAY 18
0
自我挑戰組

Asp.Net Core 從 Post FormData 走到 輕前端 Vue系列 第 18

Day18 - 輕前端 Vue - 複雜型別 object

  • 分享至 

  • xImage
  •  

先說明一下

我用輕前端 Vue 的目的,不是把整個網站都改用輕前端,而是為了把複雜的 js 取值、給值的邏輯交由 Vue Model Binding 的機制處理,進而省下語法 !

在 Vue 這個部份來說,我還在學習中,所以文章內容不會提到該怎麼寫 Vue,但我會使用 Composition API

另外,debug 時,記得持續開啟 chrome DevTools,看看 console 是否會報錯 !


Case01

Controller 內的

  • Get Action :

    • 為了讓 Vue 起始能 Binding 成功,進入 Get 頁面時,一併給定 ViewModel 預設值 !

      [HttpGet]
      public IActionResult Case01()
      {
          return View(new ViewModel());
      }
      
  • Post Action :

    • 只要是 ajax 所指定的 Action,該 Action 的 Route 都會改為 api 開頭

    • ajax Action 的部份,因為需要改成 json 格式,所以從原本的 FromForm 改成 FromBody

      [HttpPost, Route("api/[controller]/[action]")]
      public IActionResult PostCase01([FromBody]ViewModel vm)
      {
          return Ok(vm);
      }
      

View

  • 改用輕前端,等於前後端分離,所以前端欄位名稱都要手動給定 !

  • 我會切開 C# 與 js / vue 的 coding style

  • Razor 的語法的影響限制

    • 只讓 Razor 的語法只套用至 js variable,不會套用至 js function 或 statement 內 !
    • 拆分 component 的方式,以輕前端角度來看,如果想套用 Single File Component,會造成每個頁面都會有編譯的成本,所以我改用 Razor Partial View 或是引用 js 檔 !
  • 因為 Vue 的 Model Binding 是針對 js object,所以 ajax request content type 全部改為 json 格式

  • js 套件的引用,我統一放在 _Layout.cshtml

  • 新增 JsonHelper,提供 ToJson() Extension Method !

    public static class JsonHelper
    {
        public static string ToJson<T>(this T t, bool isCamelCase = true)
        {
            var jsonSerializerOptions = new JsonSerializerOptions();
    
            if (isCamelCase)
            {
                jsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
            }
    
            return JsonSerializer.Serialize(t, jsonSerializerOptions);
        }
    }
    
  • 內容

    <div id="app" v-cloak>
        <form autocomplete="off"
              v-on:submit.prevent="submit_form">
            <p>
                <label for="id">編號:</label>
                <input type="number"
                       step="1"
                       min="0"
                       id="id"
                       v-model.number="vue_model.id" />
            </p>
            <p>
                <label for="name">姓名:</label>
                <input type="text"
                       id="name"
                       v-model="vue_model.name" />
            </p>
            <p>
                <button type="submit">送出</button>
            </p>
        </form>
    
        <p>
            <a v-bind:href="prev_url">回上一層</a>
        </p>
    </div>
    
    @section Scripts
    {
        <script>
            const app = createApp({
                setup(){
    
                    const post_url = '@Url.Action("PostCase01")';
    
                    const prev_url = '@Url.Action("Index")';
    
                    const vue_model = ref(@Html.Raw(Model.ToJson()));
    
                    const submit_form = function() {
                        fetch(post_url, {
                            method: 'POST',
                            headers: {
                                'Content-Type': 'application/json',
                            },
                            body: JSON.stringify(vue_model.value),
                        })
                        .then(response => response.json())
                        .then(data => {
                            vue_model.value = data;
                        });
                    }
    
                    return {
                        post_url,
                        prev_url,
    
                        vue_model,
                        submit_form,
                    }
                }
            });
    
            const vm = app.mount('#app');
        </script>
    }
    

執行網站後,可以看出 ajax 打回後端,取回時,直接把資料放回 js object 就好 !

換句話說,不需要從 html 把 html 控制項的 value 取出,等後端處理完畢後,再放回 html 控制項中 !

整個清爽許多了 !!


這篇先到這裡,下一篇來看 複雜型別 object + collection !


上一篇
Day17 - 進入輕前端 Vue 前的範例
下一篇
Day19 - 輕前端 Vue - 複雜型別 object + collection
系列文
Asp.Net Core 從 Post FormData 走到 輕前端 Vue30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言