Case challenge - MVVM framework understanding and practice

1. Background introduction

Recently, I am working on the MVVM architecture of the new version of the project combined with the specific implementation of the business. I have had many exchanges and communications with the leaders before and after, and changed the code of the fifth version starting from a simple example of the business. Finally, a relatively complete version of the template code that meets the MVVM architecture and business requirements is output. Through this case challenge, I have a deeper understanding of the MVVM architecture than before, and record and clarify my own gains through the blog summary.

2. What is the MVVM architecture?

MVVM (Model-View-ViewModel) is a medium architecture pattern that decouples the user interface (view) of the application from the back-end logic (model). It achieves separation by introducing a ViewModel.

In the MVVM architectural pattern, **Model (Model)** represents the data and business logic of the application (interacting with the back-end server, retrieving data from the data source and processing and manipulating it), **View (View)* * is the visual part of the user interface responsible for displaying data and receiving user input. **View Model (ViewModel)** is the middle layer between the model and the view, which is responsible for handling the communication and interaction between the view and the model, that is, converting the model data into a form usable by the view, and handling the user interaction events of the view.

1. Architecture diagram

insert image description here
The view model connects the view and the model through the binding mechanism to keep them in sync. When the data of the model changes, the view model will notify the view to update. When the user performs operations on the view, the view model passes these operations to the model for processing.

2. Summary of MVVM concept

Model: Represents the data and business logic of the application, usually interacting with back-end data sources
View: Responsible for displaying the user interface and interacting with users
View model: The bridge connecting the view and the model, responsible for converting model data into a usable form for the view , and handle user interaction events for the view.

3. Implement the framework of VM

We can see that the core of the MVVM framework is the view model (ViewModel), the bridge connecting the view and the model, responsible for converting the model data into a form usable by the view, and handling the user interaction events of the view.

There are currently many frameworks that can be used to implement the ViewModel part of the MVVM architecture:
such as Vue.js, Angular, React, knockout.js

3. Understand the MVVM framework through cases

Requirement : Now there is a multiple-choice question on the page, and the data displayed on the page includes title, content, and multiple options.
Now the user answers the question, selects an option and submits it to call the answering interface on the backend.

The main implementation idea is to correctly display the data required on the front-end interface on the page. After the user answers the question, get the user's answer information and convert it into the data structure required by the back-end.

Data sources displayed on the page:

// 定义数据模型
        const questionData ={
    
    
                            questionnaireGrainId: 111,
                            title: '1.1.1.3 调查问卷:《Python语言的特点》,时间:0.5min',
                            content: '题目:下列选项中,不属于Python语言特点的是( )',
                            optionList: [
                                {
    
    
                                    optionId: 333,
                                    questionnaireGrainId: 111,
                                    optionContent: '苹果',
                                    
                                },
                                {
    
    
                                    optionId: 334,
                                    questionnaireGrainId: 111,
                                    optionContent: '橡胶',
                                    
                                },
                                {
    
    
                                    optionId: 335,
                                    questionnaireGrainId: 111,
                                    optionContent: '香蕉',
                                    
                                },
                                {
    
    
                                    optionId: 336,
                                    questionnaireGrainId: 111,
                                    optionContent: '梨',
                            
                                }
                            ]
                        };

Page effect:
insert image description here
an example of the data structure required by the backend:

{
    
    
  "questionnaireGrainId": 111,
  "questionnaireOptionParticipation": [
    {
    
    
      "optionId": "333"
    },
    {
    
    
      "optionId": "334"
    }
  ]
}

1. Programs that do not use the MVVM architecture

Overall code:

<!DOCTYPE html>
<html>
<head>
    <title>多选题示例</title>
</head>
<body>
    
    <!-- 绑定数据的容器 -->
        <div id="app">
        </div>
        <button type="button" onclick="submitAnswers()">提交</button>

    <script>
        // 定义数据模型
        const questionData ={
    
    
                            questionnaireGrainId: 111,
                            title: '1.1.1.3 调查问卷:《Python语言的特点》,时间:0.5min',
                            content: '题目:下列选项中,不属于Python语言特点的是( )',
                            optionList: [
                                {
    
    
                                    optionId: 333,
                                    questionnaireGrainId: 111,
                                    optionContent: '苹果',
                                    
                                },
                                {
    
    
                                    optionId: 334,
                                    questionnaireGrainId: 111,
                                    optionContent: '橡胶',
                                    
                                },
                                {
    
    
                                    optionId: 335,
                                    questionnaireGrainId: 111,
                                    optionContent: '香蕉',
                                    
                                },
                                {
    
    
                                    optionId: 336,
                                    questionnaireGrainId: 111,
                                    optionContent: '梨',
                            
                                }
                            ]
                        };
        
        
        //后端需要的数据结构
        const questionnaireParticipation = {
    
    
          questionnaireGrainId: null,
          questionnaireOptionParticipation: [],
        };

        
            // 获取容器元素
            const appContainer = document.getElementById('app');
            
            // 创建标题元素并添加到容器中
            const titleElement = document.createElement('h1');
            titleElement.textContent = questionData.title;
            appContainer.appendChild(titleElement);
            
            // 创建内容元素并添加到容器中
            const contentElement = document.createElement('p');
            contentElement.textContent = questionData.content;
            appContainer.appendChild(contentElement);

            
            // 创建复选框元素并添加到容器中
            questionData.optionList.forEach(option => {
    
    
                const checkbox = document.createElement('input');
                checkbox.type = 'checkbox';
                checkbox.name = 'optionList';
                checkbox.value = option.optionId;
        
                const label = document.createElement('label');
                label.appendChild(checkbox);
                label.appendChild(document.createTextNode(option.optionContent));
                label.appendChild(document.createElement('br'));
        
                appContainer.appendChild(label);
            });

        //用户答题方法
        function submitAnswers() {
    
    
            // 获取所有被选中的选项
            const optionsData=[];
            const optionElems = document.querySelectorAll('input');

            // 将选项的值存入数组中
            optionElems .forEach(elem => {
    
    
                if (elem.checked) {
    
    
                const optionId = elem.value;
                optionsData.push({
    
    optionId});
                }
                
            });

            console.log(`用户选择的选项为:`,optionsData);

        // 遍历选项数据,赋值到后端需要的数据结构中
        for (let i = 0; i < optionsData.length; i++) {
    
    

        questionnaireParticipation.questionnaireGrainId=questionData.questionnaireGrainId;
        questionnaireParticipation.questionnaireOptionParticipation.push(optionsData[i])
        
        }
        console.log("questionnaireParticipation数据结构",questionnaireParticipation);
        // 将 questionnaireParticipation 数组转换为 JSON 字符串
        let questionnaireParticipationDataJson = JSON.stringify(questionnaireParticipation);

        // 在控制台中打印 JSON 字符串
        console.log(questionnaireParticipationDataJson);

    
    
    }
    </script>
</body>
</html>

Example of the data structure printed out:

{
    
    
  "questionnaireGrainId": 111,
  "questionnaireOptionParticipation": [
    {
    
    
      "optionId": "334"
    },
    {
    
    
      "optionId": "335"
    }
  ]
}

2. Programs using the MVVM architecture

Here, the VM is implemented by using the VUE framework.

<!DOCTYPE html>
<html>
    <head>
        <title>多选题示例</title>
            <!-- 引入 Vue.js -->
            <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
    </head>
    <body>
        <!-- 绑定 Vue.js 实例 -->
            <div id="app">
                <h2>{
    
    {
    
     question.title }}</h2>
                <p>{
    
    {
    
     question.content }}</p>
                <form>
                    <label v-for="option in question.optionList" :key="option.optionId"  >
                        <input type="checkbox" v-model="questionnaireParticipation.questionnaireOptionParticipation" :value="{
    
    
                            optionId:option.optionId
                        }">
                        {
    
    {
    
     option.optionContent }}
                    </label><br>
                    <button type="button" @click="submitAnswers">提交</button>
                </form>
            </div>
        
    </body>
    <!-- 引入 Vue.js 实例脚本 -->
    <script src="questionnaire-articipation-app.js"></script>
</html>


// 定义数据模型
const questionData ={
    
    
                    questionnaireGrainId: 111,
                    title: '1.1.1.3 调查问卷:《Python语言的特点》,时间:0.5min',
                    content: '题目:下列选项中,不属于Python语言特点的是( )',
                    optionList: [
                        {
    
    
                            optionId: 333,
                            questionnaireGrainId: 111,
                            optionContent: '苹果',
                            
                        },
                        {
    
    
                            optionId: 334,
                            questionnaireGrainId: 111,
                            optionContent: '橡胶',
                            
                        },
                        {
    
    
                            optionId: 335,
                            questionnaireGrainId: 111,
                            optionContent: '香蕉',
                            
                        },
                        {
    
    
                            optionId: 336,
                            questionnaireGrainId: 111,
                            optionContent: '梨',
                    
                        }
                    ]
                };

        //第四版
        new Vue({
    
    
            el: '#app',
            data: {
    
    
                question:questionData,
                
                questionnaireParticipation: {
    
    
                  questionnaireGrainId:questionData.questionnaireGrainId,
                  questionnaireOptionParticipation:[],
                  }
            },
            methods: {
    
    
                
                submitAnswers: function() {
    
    
                    //调用后端接口..............
                    
                    //打印数据结构
                    let actorDataJson = JSON.stringify(this.questionnaireParticipation);
                           // 在控制台中打印 JSON 字符串
                           console.log(actorDataJson);
                }
            }
        });

Example of the data structure printed out:

{
    
    
  "questionnaireGrainId": 111,
  "questionnaireOptionParticipation": [
    {
    
    
      "optionId": 333
    },
    {
    
    
      "optionId": 334
    }
  ]
}

Supplement : The above program using the MVVM architecture, its V is the rendered html code, without business logic (such as: multi-select boxes, buttons, events triggered by corresponding objects) VM: monitor V, M to process the business logic that V needs to do
, Decide to render that M data to that V, and select that M for business processing
M: js code, front-end data carrier, send http request to the backend through axios component

3. Contrast

  1. The most intuitive feeling from the above two versions of the code is that the code of the program using the MVVM architecture is more concise and the hierarchy is clearer. It is divided into three layers, view layer, model layer, and view model layer (provided by vue here).

  2. From the above code, it can be seen that the program using the MVVM architecture has no data structure conversion step in the code (convert the data answered by the user into the data structure required by the back-end program), but what data the user chooses , directly through the VM is the data structure I need on the back end. The VM does the part of data interaction and uses {} symbols to define objects.

  3. The program using the MVVM architecture decouples the view from the model. Compared with the program that does not implement the MVVM architecture, then my V and my M can achieve high reuse, similar businesses, etc., all use This set of M.

Four. Summary

  1. Through this case challenge, I have a further understanding of the MVVM architecture, combining theory with practice, and need to communicate with and consult with experts.
  2. At present, I only have some understanding of the MVVM architecture, and in the future, I need to practice and think deliberately in project practice. At present, it lays the premise for understanding the MVVM architecture.

Guess you like

Origin blog.csdn.net/wangwei021933/article/details/130940610