当前位置: 首页 > article >正文

蓝桥杯18584-个人消息同步

蓝桥杯18584-个人消息同步


文章目录

      • **蓝桥杯18584-个人消息同步**
    • **1. 题目介绍**
    • **2. 项目结构**
    • **3. 目标**
          • **目标 1:完善 `store/messageStore.js`**
          • **目标 2:完善 `component/NavBar.js`**
          • **目标 3:完善 `views/Message.js`**
    • **4. 代码实现**
          • **`store/messageStore.js`**
          • **`component/NavBar.js`**
          • **`views/Message.js`**
    • **5. 运行效果**
    • **6. 知识扩展 axios和fetch**
      • **1. `fetch`**
        • **特点**
        • **基本用法**
        • **使用 `async/await`**
        • **设置请求选项**
      • **2. `axios`**
        • **特点**
        • **基本用法**
        • **使用 `async/await`**
        • **设置请求选项**
        • **拦截器**
        • **取消请求**
      • **3. `fetch` 和 `axios` 的对比**
      • **4. 选择使用场景**
      • **总结**
      • **4. 选择使用场景**
      • **总结**

1. 题目介绍

在大部分面向 C 端的页面中,当用户登录后,通常会推送个人用户的消息。为了在多个组件中共享和同步这些消息数据,通常会使用状态管理工具来存储和管理这些数据。在 Vue2 中,常用的状态管理工具是 Vuex,而在 Vue3 中,推荐使用 Pinia。

本题的目标是使用 Vue3 + Pinia 来实现个人消息的同步功能。具体任务包括:

  1. store/messageStore.js 中完成数据请求,并将请求到的消息数据存储到 Pinia 的状态管理中。
  2. component/NavBar.js 中动态显示消息的数量。
  3. views/Message.js 中动态渲染消息列表。

2. 项目结构

项目的目录结构如下:

复制

├── component
│   ├── Loading.js
│   └── NavBar.js
├── css
├── data.json
├── images
├── index.html
├── lib
├── main.js
├── store
│   └── messageStore.js
└── views
    └── Message.js
  • component:组件文件夹,包含 Loading.jsNavBar.js
  • css:样式文件夹。
  • data.json:模拟的消息数据文件。
  • images:图片文件夹。
  • index.html:主页面。
  • lib:项目依赖的文件夹。
  • main.js:主程序入口。
  • store/messageStore.js:Pinia 状态管理文件。
  • views:页面文件夹,包含 Message.js

在这里插入图片描述

3. 目标

目标 1:完善 store/messageStore.js
  • 任务

    • store/messageStore.js 中,完成数据请求(请求地址必须使用提供的常量 MockUrl)。
    • 将请求回来的数据中的消息数组存放到 messageState 中。
  • 数据格式

    {
        "code": 200,
        "data": [
            {
                "msg_id": "643fbb014fc3aacc730bfa8c",
                "label": "系统消息",
                "content": "❗️❗️❗️【会员升级通知】4月21日大动作!会员体系全新升级,新增14项权益!所有训练营,蓝桥杯备赛课、蓝桥IT人才培养计划、...",
                "send_at": "2023-04-19 17:57:21"
            },
            // ... 其他消息
        ]
    }
    

    在这里插入图片描述

  • 实现步骤

    1. 使用 fetchaxios 发起请求,获取 data.json 中的数据。
    2. data.data 中的消息数组存储到 messageState 中。
目标 2:完善 component/NavBar.js
  • 任务

    • 在导航栏的铃铛图标上方动态显示消息的数量。
    • 使用 messageState 的长度来显示消息数量。
    • 在这里插入图片描述
  • 实现步骤

    1. messageStore 中获取 messageState
    2. 在模板中使用 {{ messageStore.messageState.length }} 动态显示消息数量。
目标 3:完善 views/Message.js
  • 任务

    • 使用 messageState 中的数据动态渲染消息列表。
    • 单条消息的模板已提供,直接使用 v-for 遍历 messageState 并渲染。
    • 在这里插入图片描述
  • 实现步骤

    1. onMounted 钩子中调用 getUserMessage 方法获取消息数据。
    2. 使用 v-for 遍历 messageState,渲染每条消息。

4. 代码实现

store/messageStore.js
import { defineStore } from 'pinia';
import { ref } from 'vue';

export const useMessageStore = defineStore('message', () => {
   
    const messageState = ref([]);
    // 定义请求地址 MockUrl
    const  MockUrl ='./data.json'; 
    let getUserMessage =async () =>{
       // TODO:待补充代码
       const ref=await axios(MockUrl);
       messageState.value=ref.data.data;
       // TODO:END
    } 
   
    return {
        messageState, getUserMessage
    }
})
component/NavBar.js
import { reactive, ref } from "vue";
import { useMessageStore } from "../store/messageStore.js";

const NavBar = {
    setup() {
        const messageStore = useMessageStore();
        const headerData = reactive({
            headerArr: ["学习", "蓝桥杯", "考证", "讨论区", "校企版"],
        });
        const isShowPop = ref(true);

        return {
            headerData,
            messageStore,
            isShowPop,
        };
    },
    template: `
    <div class="header-container">
        <div class="main-header">
            <div class="menu-container">
                <a href="" class="header-brand">
                    <img class="logo" src="./images/logo.png" />
                </a>
                <div class="menu-content">
                    <div
                        class="menu-item"
                        v-for="(item, index) in headerData.headerArr"
                        :key="index"
                    >
                        <a href="" class="menu-link">
                            <span class="menu-text">{{ item }}</span>
                        </a>
                    </div>
                </div>
            </div>
            <div class="auth-container">
                <a href="" class="vip-link">
                    <div class="vip-link-content">
                        <img alt="" src="./images/vip.png" />
                        <span>会员</span>
                    </div>
                </a>
                <div :class="[{'show-message-box':isShowPop},'exit']">
                    <div class="flex">
                        <span href="" class="user-message">
                        // TODO:待补充代码 目标 2 
                            <div class="tip">{{ messageStore.messageState.length }}</div>
                            <img class="pointer" src="./images/message.png" alt="" />
                        </span>
                    </div>
                    <div class="message-popover">
                        <div class="msg-popover-header">
                            <div class="msg-header-title pointer active">学习消息</div>
                            <div class="msg-header-title pointer">蓝桥杯消息</div>
                            <div class="msg-header-title pointer">订单系统消息</div>
                        </div>
                        <div class="msg-container">
                            <div class="msg-content singe-line" v-for="msg in messageStore.messageState" :key="msg.msg_id">{{ msg.content }}</div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    `,
};

export default NavBar;
views/Message.js

javascript

复制

import { ref, onMounted } from "vue";
import { useMessageStore } from "../store/messageStore.js";
const Message = {
  template: `
    <div class="message-container" >
        <section class="system-message flex justify-start items-center">
            <span class="ml-10px">系统自动清理一年前的已读消息</span>
        </section>
        <section class="flex justify-start items-center mt-20px">
            <div class="message-type-button active-message">学习消息</div>
            <div class="message-type-button">蓝桥杯消息</div>
            <div class="message-type-button">订单系统消息</div>
        </section>
        <loading v-if="isLoading"/>
        <template v-else>
             <!-- TODO: 待修改代码 目标 3 -->
             <!-- 单条消息模板 start-->
                 <div class="message-content-wrapper mt-20px"  v-for="i in messageStore.messageState" :key="i.msg_id">
                    <div class="message-list">
                        <div class="message-item">
                            <div class="message-content">
                                <div class="message-cate">
                                    <span class="label label-success font-14">{{i.label}}</span>
                                </div>
                                <div class="message-main-content">
                                {{i.content}}
                                </div>
                            </div>
                            <div class="msg-create-time text-right">
                                <small> {{i.send_at}} </small>
                            </div>
                        </div>
                    </div>
                </div>
               <!-- 单条消息模板 end-->
        <template>
    </div>    
    `,
  setup() {
    const messageStore = useMessageStore();
    const isLoading = ref(false);
    onMounted(async () => {
      isLoading.value = true;
      await messageStore.getUserMessage();
      isLoading.value = false;
    });

    return { isLoading, messageStore };
  },
};
export default Message;


5. 运行效果

  1. 目标 1:消息数据成功请求并存储到 messageState 中。
  2. 目标 2:导航栏的铃铛图标上方动态显示消息数量。
  3. 目标 3:消息列表页面动态渲染消息内容。

6. 知识扩展 axios和fetch

1. fetch

fetch 是浏览器原生提供的用于发起网络请求的 API,基于 Promise 实现。它是现代 JavaScript 中推荐使用的网络请求工具。

特点
  1. 原生支持
    • fetch 是浏览器原生 API,无需额外安装库。
    • 在现代浏览器中广泛支持(IE 不支持)。
  2. 基于 Promise
    • 使用 Promise 处理异步操作,支持 async/await
  3. 简单易用
    • 语法简洁,易于上手。
  4. 默认不携带 Cookie
    • 默认情况下,fetch 不会发送或接收 Cookie。如果需要,需要显式设置 credentials: 'include'
  5. 错误处理
    • fetch 只有在网络错误时才会拒绝 Promise(如网络断开)。
    • 对于 HTTP 错误(如 404 或 500),fetch 不会自动拒绝,需要手动检查 response.ok
基本用法
fetch('https://api.example.com/data')
  .then(response => {
    if (!response.ok) {
      throw new Error('网络请求失败');
    }
    return response.json(); // 解析 JSON 数据
  })
  .then(data => {
    console.log('请求成功:', data);
  })
  .catch(error => {
    console.error('请求失败:', error);
  });
使用 async/await
async function fetchData() {
  try {
    const response = await fetch('https://api.example.com/data');
    if (!response.ok) {
      throw new Error('网络请求失败');
    }
    const data = await response.json();
    console.log('请求成功:', data);
  } catch (error) {
    console.error('请求失败:', error);
  }
}
设置请求选项
fetch('https://api.example.com/data', {
  method: 'POST', // 请求方法
  headers: {
    'Content-Type': 'application/json', // 请求头
  },
  body: JSON.stringify({ key: 'value' }), // 请求体
  credentials: 'include', // 携带 Cookie
})
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error(error));

2. axios

axios 是一个基于 Promise 的 HTTP 客户端,可以在浏览器和 Node.js 中使用。它是一个第三方库,提供了更多高级功能和更好的错误处理。

特点
  1. 跨平台支持
    • 可以在浏览器和 Node.js 中使用。
  2. 自动转换数据
    • 自动将请求和响应的数据转换为 JSON。
  3. 更好的错误处理
    • 对于 HTTP 错误(如 404 或 500),axios 会自动拒绝 Promise。
  4. 请求和响应拦截器
    • 支持拦截器,可以在请求发送前或响应到达前进行统一处理。
  5. 取消请求
    • 支持取消请求的功能。
  6. 默认携带 Cookie
    • 默认情况下,axios 会发送和接收 Cookie。
基本用法
axios.get('https://api.example.com/data')
  .then(response => {
    console.log('请求成功:', response.data);
  })
  .catch(error => {
    console.error('请求失败:', error);
  });
使用 async/await
async function fetchData() {
  try {
    const response = await axios.get('https://api.example.com/data');
    console.log('请求成功:', response.data);
  } catch (error) {
    console.error('请求失败:', error);
  }
}
设置请求选项
axios.post('https://api.example.com/data', { key: 'value' }, {
  headers: {
    'Content-Type': 'application/json',
  },
  withCredentials: true, // 携带 Cookie
})
  .then(response => console.log(response.data))
  .catch(error => console.error(error));
拦截器
// 请求拦截器
axios.interceptors.request.use(config => {
  console.log('请求发送前:', config);
  return config;
}, error => {
  return Promise.reject(error);
});

// 响应拦截器
axios.interceptors.response.use(response => {
  console.log('响应到达前:', response);
  return response;
}, error => {
  return Promise.reject(error);
});
取消请求
const source = axios.CancelToken.source();

axios.get('https://api.example.com/data', {
  cancelToken: source.token,
})
  .then(response => console.log(response.data))
  .catch(error => {
    if (axios.isCancel(error)) {
      console.log('请求被取消:', error.message);
    } else {
      console.error('请求失败:', error);
    }
  });

// 取消请求
source.cancel('请求被用户取消');

3. fetchaxios 的对比

特性fetchaxios
原生支持否(需要安装)
跨平台支持仅浏览器浏览器和 Node.js
自动转换 JSON需要手动调用 response.json()自动转换
错误处理需要手动检查 response.ok自动处理 HTTP 错误
拦截器不支持支持请求和响应拦截器
取消请求不支持支持
默认携带 Cookie需要设置 credentials: 'include'默认携带
语法简洁性较简洁更简洁(功能更丰富)

4. 选择使用场景

  • fetch
    • 适合简单的请求场景,尤其是现代浏览器环境。
    • 不需要额外安装库,减少项目依赖。
  • axios
    • 适合需要更强大功能的场景,如拦截器、取消请求、自动错误处理等。
    • 在需要兼容旧版浏览器或 Node.js 环境中使用。

总结

  • fetch 是浏览器原生 API,简单易用,适合现代浏览器环境。
    | 支持请求和响应拦截器 |
    | 取消请求 | 不支持 | 支持 |
    | 默认携带 Cookie | 需要设置 credentials: 'include' | 默认携带 |
    | 语法简洁性 | 较简洁 | 更简洁(功能更丰富) |

4. 选择使用场景

  • fetch
    • 适合简单的请求场景,尤其是现代浏览器环境。
    • 不需要额外安装库,减少项目依赖。
  • axios
    • 适合需要更强大功能的场景,如拦截器、取消请求、自动错误处理等。
    • 在需要兼容旧版浏览器或 Node.js 环境中使用。

总结

  • fetch 是浏览器原生 API,简单易用,适合现代浏览器环境。
  • axios 是一个功能更强大的第三方库,适合需要高级功能的场景

http://www.kler.cn/a/567964.html

相关文章:

  • 红黑树和 STL —— set和map 【复习笔记】
  • STM32CubeMx DRV8833驱动
  • C++里面四种强制类型转换
  • ES如何打印DSL
  • Oracle 认证为有哪几个技术方向
  • Java基础语法练习34(抽象类-abstract)(抽象类最佳实践-模版设计模式)
  • 数据挖掘中特征发现与特征提取的数学原理
  • 十、Spring Boot:Spring Security(用户认证与授权深度解析)
  • Cherry Studio + 火山引擎 构建个人AI智能知识库
  • 智慧园区后勤单位消防安全管理:安全运营和安全巡检
  • Postgresql高可用之Pacemaker+Corosync
  • 【前端基础】Day 2 CSS层叠样式表
  • Spring Boot 中 @Repository 注解全析
  • 文件上传漏洞绕过WAF
  • 【docker好用系列】llama-factory环境配置
  • Qt中如果槽函数运行时间久,避免阻塞主线程的做法
  • GPT-4.5 怎么样?如何升级使用ChatGPTPlus/Pro? GPT-4.5设计目标是成为一款非推理型模型的巅峰之作
  • 【nextjs官方demo】Chapter 6连接数据库报错
  • 深入解析React性能优化三剑客:React.memo、useMemo与useCallback
  • Go语言学习笔记(七)——标准库