【三十天精通Vue 3】第二十天 Vue 3的性能优化详解

news2024/11/28 11:11:32

请添加图片描述

✅创作者:陈书予
🎉个人主页:陈书予的个人主页
🍁陈书予的个人社区,欢迎你的加入: 陈书予的社区
🌟专栏地址: 三十天精通 Vue 3

文章目录

    • 引言
    • 一、Vue3 性能优化的概念
      • 1.1 为什么需要性能优化
      • 1.2 性能优化的定义
      • 1.3 性能优化的目标
    • 二、Vue3 性能优化的实践
      • 2.1 使用 KeepAlive 组件缓存组件
      • 2.2 合理使用 v-if 和 v-show
      • 2.3 避免使用过多的计算属性
      • 2.4 避免使用过多的 Watch
      • 2.5 优化列表渲染
        • 2.5.1 列表的渲染方式
        • 2.5.2 列表渲染的性能优化
      • 2.6 使用静态节点
      • 2.7 使用异步组件
      • 2.8 使用路由懒加载
      • 2.9 优化图片加载
      • 2.10 减少 HTTP 请求次数
    • 三、Vue3 性能优化的工具
      • 3.1 Vue.js devtools
      • 3.2 Webpack-bundle-analyzer
      • 3.3 Lighthouse

引言

Vue3作为一个渐进式JavaScript框架,已经被越来越多的开发者使用。尽管Vue3具有易学、易用、高效等特点,但随着业务逻辑的增加和数据量的增大,性能问题也不可避免地出现。例如,加载时间过长、渲染速度缓慢、占用过多的系统资源等问题,这些都会影响用户体验,甚至对SEO等方面产生不良影响。因此,为了提高Vue3应用程序的性能,需要进行相应的性能优化。

一、Vue3 性能优化的概念

1.1 为什么需要性能优化

Vue3应用程序随着业务逻辑的增加和数据量的增大,渲染速度逐渐变慢,这会影响用户体验和SEO等方面的效果。另外,由于Vue3应用程序是运行在浏览器中的,如果应用程序过于耗费资源,会导致浏览器崩溃或卡顿,甚至会影响其他正在运行的程序。因此,为了提高Vue3应用程序的性能,需要进行相应的性能优化。

1.2 性能优化的定义

性能优化是指通过一系列的技术手段和策略,使Vue3应用程序更快、更可靠、更稳定地运行。性能优化的目标是提高Vue3应用程序的响应速度、降低CPU和内存的占用率、减少HTTP请求次数、加快数据传输速度等,从而提高用户体验和SEO等方面的效果。

1.3 性能优化的目标

Vue3应用程序性能优化的目标可以从以下几个方面进行考虑:

  • 提高页面加载速度,减少页面渲染时间;
  • 降低CPU和内存的占用率,提高系统资源利用率;
  • 减少HTTP请求次数,提高数据传输速度;
  • 加快数据处理速度,提高用户交互效果;
  • 提高代码的可维护性和可扩展性。

二、Vue3 性能优化的实践

2.1 使用 KeepAlive 组件缓存组件

在Vue3中,可以使用KeepAlive组件来缓存组件,这样可以避免在组件切换时多次渲染同一组件,提高应用的性能。KeepAlive组件可以将不活跃的组件实例缓存起来,等到再次需要渲染时,直接使用缓存的组件实例,而不是重新创建实例并重新渲染。需要注意的是,使用KeepAlive组件需要合理地处理组件的生命周期函数,以避免出现意外的错误。

示例代码:

<template>
  <div>
    <button @click="toggleShow">Toggle Show</button>
    <keep-alive>
      <component :is="currentComponent" v-if="show"></component>
    </keep-alive>
  </div>
</template>

<script>
export default {
  data() {
    return {
      show: true,
      currentComponent: 'MyComponent'
    }
  },
  methods: {
    toggleShow() {
      this.show = !this.show
    }
  }
}
</script>

2.2 合理使用 v-if 和 v-show

在Vue3中,v-if和v-show可以用来控制组件或元素的显示和隐藏。v-if会根据条件动态地添加或删除DOM元素,而v-show只是通过CSS来控制元素的显示和隐藏。在使用这两个指令时,应根据具体情况选择合适的指令来控制元素的显示和隐藏。如果需要频繁切换元素的显示和隐藏,建议使用v-show,因为它只是修改CSS,不会造成DOM的频繁增删。而如果元素的显示和隐藏不频繁,建议使用v-if,因为它可以避免不必要的DOM渲染。

示例代码:

<template>
  <div>
    <button @click="toggleShow">Toggle Show</button>
    <div v-if="show">This is a v-if element</div>
    <div v-show="!show">This is a v-show element</div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      show: true
    }
  },
  methods: {
    toggleShow() {
      this.show = !this.show
    }
  }
}
</script>

2.3 避免使用过多的计算属性

在Vue3中,计算属性是用来对数据进行处理并生成新的数据的。计算属性的使用可以使模板更加简洁,但是如果使用过多,会导致性能问题。因为计算属性的值会在每次渲染时重新计算,如果计算的逻辑复杂,会增加渲染的时间。所以,在使用计算属性时,应该避免使用过多的计算属性,可以通过使用computed的缓存机制来提高性能。

示例代码:

<template>
  <div>
    <p>计算属性1:{{computedProp1}}</p
    <p>计算属性2:{{computedProp2}}</p>
    <p>计算属性3:{{computedProp3}}</p>
  </div>
</template>
<script>
export default {
  data() {
    return {
      list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
    };
  },
  computed: {
    // 计算属性1:遍历数组并生成新的数组
    computedProp1() {
      return this.list.map(item => item * 2);
    },
    // 计算属性2:遍历数组并生成新的数组
    computedProp2() {
      return this.list.map(item => item * 3);
    },
    // 计算属性3:遍历数组并生成新的数组
    computedProp3() {
      return this.list.map(item => item * 4);
    },
  },
};
</script>

2.4 避免使用过多的 Watch

Vue3中的watch选项也可以监听数据的变化并作出相应的处理,但是如果watch使用过多,会导致性能问题,因为每个watcher都会在数据变化时重新计算一次。所以,在使用watch时,应该避免使用过多的watch。

可以考虑使用computed属性来替代一些watcher,因为computed具有缓存机制,只有在相关依赖发生变化时才会重新计算。

示例代码:

<template>
  <div>
    <p>{{ message }}</p>
    <button @click="changeMessage">Change Message</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: "Hello World"
    };
  },
  methods: {
    changeMessage() {
      this.message = "Hello Vue3";
    }
  },
  watch: {
    message(newVal, oldVal) {
      console.log(`Message changed from ${oldVal} to ${newVal}`);
    }
  }
};
</script>

在上面的代码中,我们使用了一个watch来监听message的变化并打印日志。当我们点击按钮时,会触发changeMessage方法来改变message的值。每次message的值发生变化时,watcher都会重新计算一次,这会导致性能问题。

我们可以使用computed属性来替代watcher:

<template>
  <div>
    <p>{{ message }}</p>
    <button @click="changeMessage">Change Message</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: "Hello World"
    };
  },
  methods: {
    changeMessage() {
      this.message = "Hello Vue3";
    }
  },
  computed: {
    logMessage() {
      console.log(`Message changed to ${this.message}`);
      return this.message;
    }
  }
};
</script>

在这个例子中,我们使用了一个computed属性来代替watcher来监听message的变化。当我们点击按钮时,会触发changeMessage方法来改变message的值。每次message的值发生变化时,computed属性会重新计算一次,并打印日志。由于computed具有缓存机制,只有在相关依赖发生变化时才会重新计算,这样可以避免使用过多的watcher。

2.5 优化列表渲染

2.5.1 列表的渲染方式

在Vue3中,列表渲染可以使用v-for指令来进行。在进行列表渲染时,应该注意以下几点:

  1. 尽量不要使用v-ifv-show来控制列表项的显示或隐藏,这样会导致不必要的性能损耗。如果需要控制显示或隐藏,可以使用CSS样式或组件的props来进行。
  2. 尽量不要在列表项中使用计算属性或方法,因为它们会在每次渲染时被重新计算。如果必须使用计算属性或方法,可以考虑将其提取到列表项组件中。
  3. 如果列表项较多,可以考虑使用key属性来提高性能。key属性可以告诉Vue哪些元素是需要重新渲染的,从而减少不必要的DOM操作。key属性应该使用唯一且稳定的值来保证正确性和性能。

示例代码:

<template>
  <ul>
    <li v-for="(item, index) in list" :key="item.id">
      {{ item.name }}
    </li>
  </ul>
</template>

<script>
export default {
  data() {
    return {
      list: [
        { id: 1, name: 'item1' },
        { id: 2, name: 'item2' },
        { id: 3, name: 'item3' }
      ]
    }
  }
}
</script>

2.5.2 列表渲染的性能优化

列表渲染的性能优化可以从以下几个方面入手:

  1. 使用v-forkey属性来提高性能,可以减少不必要的DOM操作。
  2. 将列表项组件化,可以提高复用性和性能。在组件中可以使用props来接收列表项的数据,从而避免使用计算属性或方法。
  3. 对于静态列表项,可以使用v-once指令来避免不必要的DOM更新。
  4. 对于长列表,可以使用虚拟滚动来提高性能。虚拟滚动可以避免将所有列表项都渲染出来,而是只渲染可见部分和预加载部分,从而减少DOM操作和内存消耗。

示例代码:

<template>
  <ul>
    <li v-for="(item, index) in list" :key="item.id">
      {{ item.name }}
    </li>
  </ul>
</template>

<script>
export default {
  data() {
    return {
      list: [
        { id: 1, name: 'item1' },
        { id: 2, name: 'item2' },
        { id: 3, name: 'item3' }
      ]
    }
  }
}
</script>

2.6 使用静态节点

在 Vue3 中,使用静态节点可以减少不必要的渲染,从而提高性能。静态节点是指不会发生变化的节点,可以在模板编译时被预先处理,减少了运行时的计算。

在模板中,可以使用 v-once 指令将节点标记为静态节点。例如:

<template>
  <div v-once>
    <h1>静态节点</h1>
    <p>这是一个静态节点,不会随着数据的改变而重新渲染</p>
  </div>
</template>

使用 v-once 指令标记的节点会被编译为静态节点,这样就可以在组件渲染过程中只渲染一次,提高性能。

2.7 使用异步组件

在 Vue3 中,可以使用异步组件来延迟组件的加载时间,从而提高应用的性能。异步组件是指只有在需要时才会被加载的组件。可以使用 import 函数来定义异步组件。例如:

<template>
  <div>
    <async-component></async-component>
  </div>
</template>

<script>
import { defineAsyncComponent } from 'vue'

export default {
  components: {
    AsyncComponent: defineAsyncComponent(() =>
      import('./AsyncComponent.vue')
    )
  }
}
</script>

在上面的例子中,使用 defineAsyncComponent 函数定义了一个异步组件,并将其作为 components 的属性传递给了父组件。当父组件需要渲染异步组件时,会异步加载对应的组件文件。

使用异步组件可以有效地减少初始加载时的网络请求,提高应用的加载速度。同时也可以使得页面在运行时只加载需要的组件,减少不必要的资源占用。

2.8 使用路由懒加载

在 Vue3 中,使用路由懒加载可以减少初始加载时的网络请求,从而提高应用的性能。路由懒加载是指只有在需要时才会被加载的路由组件。可以使用 import 函数来定义路由懒加载。例如:

const routes = [
  {
    path: '/',
    name: 'Home',
    component: () => import('@/views/Home.vue')
  },
  {
    path: '/about',
    name: 'About',
    component: () => import('@/views/About.vue')
  }
]

在上面的例子中,使用 import 函数定义了一个路由懒加载,并将其作为 component 的属性传递给了路由。当路由需要加载对应的组件时,会异步加载对应的组件文件。

使用路由懒加载可以有效地减少初始加载时的网络请求,提高应用的加载速度。同时也可以使得页面在运行时只加载需要

2.9 优化图片加载

在Vue3中,可以使用懒加载的方式来优化图片加载,即当图片进入可视区域时再加载图片。这样可以避免一次性加载大量的图片,降低页面加载时间,提高用户体验。可以使用vue-lazyload插件来实现懒加载。

示例代码:

安装vue-lazyload插件:

npm install vue-lazyload --save

在main.js中引入并使用插件:

import Vue from 'vue'
import VueLazyload from 'vue-lazyload'

Vue.use(VueLazyload)

在组件中使用:

<template>
  <div>
    <img v-lazy="imgUrl" alt="图片">
  </div>
</template>

<script>
export default {
  data() {
    return {
      imgUrl: 'https://xxx.com/xxx.jpg'
    }
  }
}
</script>

2.10 减少 HTTP 请求次数

减少HTTP请求次数可以加快页面加载速度,提高用户体验。可以通过合并和压缩静态资源、使用CSS Sprites、使用字体图标等方式来减少HTTP请求次数。

示例代码:

使用CSS Sprites:

将多张小图片合并成一张大图片,然后通过CSS设置背景图位置和大小来显示不同的图片,这样可以减少HTTP请求次数。

// 将多张小图片合并成一张大图片,命名为sprite.png
// 在CSS中设置背景图位置和大小
.icon-1 {
  background-image: url('sprite.png');
  background-position: 0px 0px;
  width: 20px;
  height: 20px;
}
.icon-2 {
  background-image: url('sprite.png');
  background-position: -20px 0px;
  width: 20px;
  height: 20px;
}

使用字体图标:

将需要的图标制作成字体文件,然后在CSS中通过设置字体和字体大小来显示不同的图标,这样也可以减少HTTP请求次数。

// 使用FontAwesome字体图标
// 在CSS中设置字体和字体大小
.icon-1:before {
  font-family: FontAwesome;
  content: "\f007";
  font-size: 20px;
}
.icon-2:before {
  font-family: FontAwesome;
  content: "\f019";
  font-size: 20px;
}

三、Vue3 性能优化的工具

3.1 Vue.js devtools

Vue.js devtools是一个非常实用的浏览器扩展程序,可以帮助我们更好地调试和优化Vue应用程序。Vue.js devtools提供了以下功能:

  • 组件树:可以查看组件层次结构,调试组件之间的关系。
  • 数据:可以查看和修改组件的数据状态。
  • 事件:可以查看组件触发的事件。
  • 溯源:可以查看组件的创建和更新时的代码路径。
  • 性能:可以查看组件的性能数据,如渲染时间、更新次数等。

你可以在以下链接中下载并安装 Vue.js devtools:

  • Chrome 扩展:https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd
  • Firefox 扩展:https://addons.mozilla.org/en-US/firefox/addon/vue-js-devtools/
  • Edge 扩展:https://microsoftedge.microsoft.com/addons/detail/vuejs-devtools/djdcbmfacaaocbggdappklicjkgoflig

通过Vue.js devtools,我们可以更快速地定位和解决Vue应用程序的问题,提高开发效率和用户体验。

3.2 Webpack-bundle-analyzer

Webpack-bundle-analyzer是一个Webpack插件,可以分析和可视化Webpack打包后的bundle文件,帮助我们更好地理解和优化应用程序的性能。

你可以在以下链接中下载并安装 Webpack-bundle-analyzer:

  • npm 官网:https://www.npmjs.com/package/webpack-bundle-analyzer
  • GitHub 仓库:https://github.com/webpack-contrib/webpack-bundle-analyzer

Webpack-bundle-analyzer可以生成一个可交互的图形化报告,展示了应用程序的各个模块、依赖关系和大小。通过这个工具,我们可以发现并解决应用程序中过大的模块或依赖,以及重复的代码等问题,优化应用程序的性能。

3.3 Lighthouse

Lighthouse是一个由Google开发的开源工具,可以评估Web应用程序的质量和性能,并提供相应的建议和指导。

你可以在以下链接中下载并安装 Lighthouse:

  • Chrome 扩展:https://chrome.google.com/webstore/detail/lighthouse/blipmdconlkpinefehnmjammfjpmpbjk
  • Node.js 模块:https://www.npmjs.com/package/lighthouse

Lighthouse可以检查应用程序的各个方面,如性能、可访问性、最佳实践、SEO等,并提供相应的评分和优化建议。通过Lighthouse,我们可以发现并解决应用程序中存在的问题,提高应用程序的性能和用户体验。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/470830.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于dsp+fpga+AD+ENDAC的半导体运动台高速数据采集电路仿真设计(四)

整个调试验证与仿真分析分三个步骤&#xff1a;第一步是进行 PCB 检查及电气特性测试&#xff0c;主 要用来验证硬件设计是否正常工作&#xff1b;第二步进行各子模块功能测试&#xff0c;包括高速光纤串行 通信的稳定性与可靠性测试&#xff0c; A/D 及 D/A 转换特性测…

26从零开始学Java之如何对数组进行排序与二分查找?

作者&#xff1a;孙玉昌&#xff0c;昵称【一一哥】&#xff0c;另外【壹壹哥】也是我哦 千锋教育高级教研员、CSDN博客专家、万粉博主、阿里云专家博主、掘金优质作者 前言 在上一篇文章中&#xff0c;壹哥给大家讲解了数组的扩容、缩容及拷贝方式。接下来在今天的文章中&…

深眸科技|深度学习、3D视觉融入机器视觉系统,实现生产数智化

随着“中国制造2025”战略加速落实&#xff0c;制造业生产线正在加紧向智能化、自动化和数字化转型之路迈进。而人工智能技术的兴起以及边缘算力持续提升的同时&#xff0c;机器视觉及其相关技术也在飞速发展&#xff0c;并不断渗透进工业领域&#xff0c;拓展应用场景的同时&a…

Apache Druid中Kafka配置远程代码执行漏洞(MPS-2023-6623)

漏洞描述 Apache Druid 是一个高性能的数据分析引擎。 Kafka Connect模块曾出现JNDI注入漏洞(CVE-2023-25194)&#xff0c;近期安全研究人员发现Apache Druid由于支持从 Kafka 加载数据的实现满足其利用条件&#xff0c;攻击者可通过修改 Kafka 连接配置属性进行 JNDI 注入攻…

软件架构中间件技术

中间件的定义 其实中间件是属于构件的一种。是一种独立的系统软件或服务程序&#xff0c;可以帮助分布式应用软件在不同技术之间共享资源。 我们把它定性为一类系统软件&#xff0c;比如我们常说的消息中间件&#xff0c;数据库中间件等等都是中间件的一种体现。一般情况都是…

减少 try catch ,可以这样干

软件开发过程中&#xff0c;不可避免的是需要处理各种异常&#xff0c;就我自己来说&#xff0c;至少有一半以上的时间都是在处理各种异常情况&#xff0c;所以代码中就会出现大量的try {...} catch {...} finally {...}代码块&#xff0c;不仅有大量的冗余代码&#xff0c;而且…

d3.js学习笔记①创建html文档

本人之前从未学过HTML、CSS、JavaScript&#xff0c;然而我导是做前端的&#xff0c;要求我必须在三周内掌握d3.js&#xff0c;我只能从0学起并以此记录自己的学习过程。 首先对这三种语言有一个初步的认识&#xff1a;HTML是用于搭建网页框架&#xff0c;CSS是美化网页的&…

软件设计师考试——计算机网络、系统安全分析和设计部分

计算机网路 七层模型 OSI/RM七层模型 网络技术标准与协议 TCP协议 DHCP协议 DNS协议 计算机网络的分类——拓扑结构 按分布范围&#xff1a; 局域网城域网广域网因特网 按拓扑结构&#xff1a; 总线型星型环型 网络规划与设计 逻辑网络设计 物理网络设计 分层设计 IP地址…

VirboxLM-免服务版授权码,快速实现一机一码

一、产品介绍 ​ 授权码是由深盾科技开发的一款软件保护及授权管理产品 ​&#xff0c;一方面要保护软件代码不被逆向&#xff0c;另一方面要控制软件的授权使用。软件用户只需要输入授权码&#xff08;由数字和字母组成的一串字符&#xff09;&#xff0c;激活授权码后即可使…

这年头,谁还在「贩卖」生活方式?

【潮汐商业评论/原创】 “我已经很久没有追寻过品牌购物了”Anna如是说。 如今的Anna对商品的选择往往会考虑性价比以及简洁的外观&#xff0c;去品牌化、简单已经成为其新的生活方式。 日本作者三浦展在《第四消费时代》一书中提到&#xff0c;在第三消费社会&#xff0c;新…

Java版本企业工程项目管理系统平台源码(三控:进度组织、质量安全、预算资金成本、二平台:招采、设计管理)

工程项目管理软件&#xff08;工程项目管理系统&#xff09;对建设工程项目管理组织建设、项目策划决策、规划设计、施工建设到竣工交付、总结评估、运维运营&#xff0c;全过程、全方位的对项目进行综合管理 工程项目各模块及其功能点清单 一、系统管理 1、数据字典&#…

Android 获取奔溃crash的日志(adb logcat或者dropbox)

1.通过adb logcat 来获取&#xff1a; 使用场景&#xff1a;测试或者开发小伙伴 抓取。 先执行adb logcat -c 清理缓存日志 接着&#xff0c;抓取当前时间段开始的日志: adb logcat -v time >D:/crash.log 也可以抓取指定进程的日志&#xff1a; adb logcat -v time | fi…

利用POSIX多线程API函数进行多线程开发

本书文字内容源自 <<linux C/C服务器开发实践>> 支持正版图书&#xff0c;测试代码根据测试目的&#xff0c;可自行修改测试。 前言 在用POSIX多线程API函数进行开发之前&#xff0c;我们首先要熟悉这些API函数。常见的与线程有关的基本API函数见下表 使用这些A…

亚马逊云科技综合解决方案助力美的智能化,成本节省30%

很多人都有和客服打交道的体验&#xff0c;而这种体验大概率不佳&#xff0c;人工客服迟迟不应&#xff0c;解答问题也不精准&#xff0c;糟糕的客服体验对于面向消费者的企业来说亦是一大难题&#xff0c;严重者甚至会导致客户流失、评价滑坡等后果&#xff0c;作为知名科技电…

FileInputStream.read和FileChannel.read的区别

FileChannel怎么来的 FileChannel channel new FileInputStream("").getChannel() FileChannel的read()方法 channel.read(byteBuffer) 实现类FileChannelImpl 首先映入眼帘的就是非常熟悉的synchronized关键字&#xff0c; private final Object positionLock ne…

宏基因组组装 | 就现在!做出改变!!

微生态研究的核心难点是什么&#xff01; 基因组组装&#xff01; 从宏基因组数据中组装获得细菌的完整基因组&#xff08;complete MAGs&#xff09;是微生物组研究的长期目标&#xff0c;但基于NGS的宏基因组测序和组装方法是无法实现完整的细菌基因组组装的。即便是红极一…

appium-app测试-环境搭建手机和adb设置

1、手机设置&#xff08;Android手机-readMI k50&#xff09;&#xff1a; 1.1开发者模式设置 入口&#xff1a;设置–我的设备–全部参数与信息&#xff1b; 连续点击MIUI版本7下&#xff0c;进入开发者模式 1.2、开发者选项设置 入口&#xff1a;设置–更多设置–开发者选项…

np.convolve(x,h, mode=‘##‘)的使用

用法&#xff1a; np.convolve(a,v,mode) a代表卷积数据&#xff0c;v卷积核大小&#xff0c;mode卷积方式&#xff0c;mode卷积方式有三种 same full valid mode可能的三种取值情况&#xff1a; full’ 默认值&#xff0c;返回每一个卷积值&#xff0c;长度是NM-1,在卷积的…

MyBatis:使用 MyBatis 实现增删改查、各种配置解析

文章目录 MyBatis&#xff1a;Day 01一、简介二、第一个 MyBatis 程序1. 步骤2. 注意 三、增、删、改、查四、扩展1. Map2. 模糊查询 五、配置解析&#xff08;参考手册&#xff09;1. 环境配置&#xff1a;environments2. 属性优化&#xff1a;properties3. 类型别名&#xff…

中国厨房更净一步:一场科技“下凡”带来的方太式浪漫

世界上恐怕没有任何一个民族&#xff0c;比中国人对美食的情结更悠远了。 正如《菜根谭》里说的&#xff0c;“醲肥辛甘非真味&#xff0c;真味只是淡&#xff1b;神奇卓异非至人&#xff0c;至人只是常”。 寻常人家的一蔬一饭&#xff0c;是厨房里的幸福记忆&#xff0c;也承…