{"id":318289,"date":"2021-02-19T15:01:01","date_gmt":"2021-02-19T15:01:01","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=318289"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=318289","title":{"rendered":"\u0423\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 vue \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f"},"content":{"rendered":"\n<div class=\"post__text post__text_v2\" id=\"post-content-body\">\n<p>\u0423 \u043d\u0430\u0441 \u0432 TeamHood \u0435\u0441\u0442\u044c wiki. \u0422\u0430\u043c \u0441\u043e\u0431\u0440\u0430\u043b\u0430\u0441\u044c \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044f \u0440\u0435\u043a\u043e\u043c\u043c\u0435\u043d\u0434\u0430\u0446\u0438\u0439, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435, \u043f\u043e \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u044e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0442\u044f\u0436\u0435\u043b\u043e\u0433\u043e \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434\u0430 \u043d\u0430 vue.js. \u0423\u043b\u0443\u0447\u0448\u0430\u0442\u044c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u043b\u043e\u0441\u044c, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0432 \u0441\u0438\u043b\u0443 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0438 \u043d\u0430\u0448\u0438 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u044d\u043a\u0440\u0430\u043d\u044b \u043d\u0435 \u0438\u043c\u0435\u044e\u0442 \u043f\u0430\u0433\u0438\u043d\u0430\u0446\u0438\u0438. \u0415\u0441\u0442\u044c \u043a\u043b\u0438\u0435\u043d\u0442\u044b, \u0443 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043d\u0430 \u043e\u0434\u043d\u043e\u0439 kanban\/gantt \u0434\u043e\u0441\u043a\u0435 \u0431\u043e\u043b\u044c\u0448\u0435 \u0442\u044b\u0441\u044f\u0447\u0438 \u0432\u043e\u0442 \u0442\u0430\u043a\u0438\u0445 \u0432\u043e\u0442 \u043a\u0430\u0440\u0442\u043e\u0447\u0435\u043a, \u0432\u0441\u0435 \u044d\u0442\u043e \u0434\u043e\u043b\u0436\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0431\u0435\u0437 \u043b\u0430\u0433\u043e\u0432.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/c30\/2c1\/6a8\/c302c16a8154a42a99cadd5d0496029d.gif\" width=\"780\" height=\"440\"><figcaption><\/figcaption><\/figure>\n<p>\u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043d\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0435\u0434\u043a\u043e \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u0435\u043c\u044b\u0445 \u0442\u0435\u0445\u043d\u0438\u043a \u0438\u0437 \u043d\u0430\u0448\u0435\u0439 wiki, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u043c\u043e\u0433\u0443\u0442 \u0441\u043e\u043a\u0440\u0430\u0442\u0438\u0442\u044c \u0438\u0437\u043b\u0438\u0448\u043d\u0438\u0439 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0438 \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u044c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c.<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440\u044b \u0441\u0442\u0430\u0442\u044c\u0438 \u0441\u043e\u0431\u0440\u0430\u043d\u044b \u0432 <a href=\"https:\/\/github.com\/Kasheftin\/vue-rerendering-optimization\" rel=\"noopener noreferrer nofollow\">\u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u043c \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438<\/a>. \u042d\u0442\u043e vue2 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u0445\u043e\u0442\u044f \u0432\u0441\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u0435\u043d\u043e \u0438 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u0442 \u0431\u044b\u0442\u044c \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u043c \u0434\u043b\u044f vue3. \u041f\u043e\u043a\u0430 \u0447\u0442\u043e \u043d\u0435 \u0432\u0441\u044f \u044d\u043a\u043e\u0441\u0438\u0441\u0442\u0435\u043c\u0430 vue3 production-ready. \u0412 vuex4 <a href=\"https:\/\/github.com\/vuejs\/vuex\/issues\/1934\" rel=\"noopener noreferrer nofollow\">\u0443\u0442\u0435\u043a\u0430\u0435\u0442 \u043f\u0430\u043c\u044f\u0442\u044c<\/a>, \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438 \u0442\u0430\u043c \u043f\u043e\u043a\u0430 \u0431\u0435\u0441\u0441\u043c\u044b\u0441\u043b\u0435\u043d\u043d\u043e (\u0447\u0442\u043e \u043e\u0431\u043d\u0430\u0434\u0435\u0436\u0438\u0432\u0430\u0435\u0442, \u0437\u0430\u0442\u0440\u0430\u0442\u044b \u043f\u0430\u043c\u044f\u0442\u0438 \u0442\u0430\u043c \u0432 \u0440\u0430\u0437\u044b \u043c\u0435\u043d\u044c\u0448\u0435 \u0447\u0435\u043c \u0432 vue2+vuex3). \u041f\u0440\u0438\u043c\u0435\u0440\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u044b \u043d\u0430 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u043c \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0435\u043c javascript, \u0431\u044b\u043b\u043e \u0438\u0441\u043a\u0443\u0448\u0435\u043d\u0438\u0435 \u0432\u043e\u0442\u043a\u043d\u0443\u0442\u044c vue-class-component, typescript, typed-vuex \u0438 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u0443\u044e \u043a\u0443\u0445\u043d\u044e \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u043d\u043e \u0443\u0434\u0435\u0440\u0436\u0430\u043b\u0441\u044f.<\/p>\n<h2>1. (Deep) Object Watchers<\/h2>\n<p>\u041f\u0440\u0430\u0432\u0438\u043b\u043e &#8212; \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c deep \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c watch \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432. \u0420\u0430\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u0440\u0438\u043c\u0435\u0440. \u041d\u0435\u043a\u0438\u0439 \u043c\u0430\u0441\u0441\u0438\u0432 items \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f \u0432 vuex store, \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0435\u0442\u0441\u044f, \u0432\u043e\u0437\u043b\u0435 \u043a\u0430\u0436\u0434\u043e\u0433\u043e item \u0435\u0441\u0442\u044c \u0447\u0435\u043a\u0431\u043e\u043a\u0441. \u0421\u0432\u043e\u0439\u0441\u0442\u0432\u043e isChecked \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0441\u044f \u043a \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0443, \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u043e\u0442 item, \u043e\u0434\u043d\u0430\u043a\u043e \u0435\u0441\u0442\u044c getter, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442 \u0438\u0445 \u0432\u043c\u0435\u0441\u0442\u0435:<\/p>\n<pre><code class=\"javascript\">export const state = () =&gt; ({   items: [{ id: 1, name: 'First' }, { id: 2, name: 'Second' }],   checkedItemIds: [1, 2] })  export const getters = {   extendedItems (state) {     return state.items.map(item =&gt; ({       ...item,       isChecked: state.checkedItemIds.includes(item.id)     }))   } }<\/code><\/pre>\n<p>\u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c, items \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043e\u0442\u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u044b, \u0431\u0443\u0434\u0435\u043c \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u043f\u043e\u0440\u044f\u0434\u043e\u043a. \u0427\u0442\u043e-\u0442\u043e \u0432\u0440\u043e\u0434\u0435:<\/p>\n<pre><code class=\"javascript\">export default class ItemList extends Vue {   computed: {     extendedItems () { return this.$store.getters.extendedItems },     itemIds () { return this.extendedItems.map(item =&gt; item.id) }   },   watch: {     itemIds () {       console.log('Saving new items order...', this.itemIds)      }   } }<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0447\u0435\u043a\u0431\u043e\u043a\u0441\u0430 \u0443 \u043b\u044e\u0431\u043e\u0433\u043e item \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0438\u0437\u043b\u0438\u0448\u043d\u0435\u0435 \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u043d\u0438\u0435 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u043f\u043e\u0440\u044f\u0434\u043a\u0430. \u041a\u043e\u043d\u0441\u0442\u0440\u0443\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u043e\u0432\u044b\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 &#8212; \u043d\u0430\u0441\u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u043f\u0440\u043e\u0446\u0435\u0441\u0441, \u0447\u0442\u043e \u0434\u0430\u0436\u0435 \u0432 \u044d\u0442\u043e\u043c \u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043c\u044b \u0434\u0435\u043b\u0430\u0435\u043c \u044d\u0442\u043e \u0434\u0432\u0430\u0436\u0434\u044b. \u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 checkedItemIds \u0432\u044b\u0437\u0432\u0430\u0435\u0442 \u043f\u0435\u0440\u0435\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 extendedItems (\u0438 \u043f\u0435\u0440\u0435\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u044d\u0442\u043e\u0433\u043e \u043c\u0430\u0441\u0441\u0438\u0432\u0430), \u0437\u0430\u0442\u0435\u043c \u0438\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 itemIds. \u042d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u043a\u043e\u043d\u0442\u0440\u0430-\u0438\u043d\u0442\u0443\u0438\u0442\u0438\u0432\u043d\u044b\u043c, \u0432\u0435\u0434\u044c \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u043c\u0430\u0441\u0441\u0438\u0432, \u0441\u043e\u0441\u0442\u043e\u044f\u0449\u0438\u0439 \u0438\u0437 \u0442\u0435\u0445 \u0436\u0435 \u0441\u0430\u043c\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0432 \u0442\u043e\u043c \u0436\u0435 \u0441\u0430\u043c\u043e\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0435. \u041e\u0434\u043d\u0430\u043a\u043e, \u044d\u0442\u043e \u043f\u0440\u0438\u0440\u043e\u0434\u0430 javascript, [1,2,3] != [1,2,3]. \u0414\u0435\u043c\u043e \u0437\u0434\u0435\u0441\u044c: <a href=\"https:\/\/kasheftin.github.io\/vue-rerendering-optimization\/#\/example1\" rel=\"noopener noreferrer nofollow\">example1<\/a>.<\/p>\n<p>\u0420\u0435\u0448\u0435\u043d\u0438\u0435 &#8212; \u043f\u043e\u043b\u043d\u044b\u0439 \u043e\u0442\u043a\u0430\u0437 \u043e\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f watcher \u0434\u043b\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0438 \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u0432.  \u0414\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0441\u043b\u043e\u0436\u043d\u043e\u0433\u043e watcher \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 computed \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430.  \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0435\u0441\u043b\u0438 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 <code>{id, title, userId}<\/code>\u0432 \u043c\u0430\u0441\u0441\u0438\u0432\u0435 items, \u043c\u043e\u0436\u043d\u043e \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0443:<\/p>\n<pre><code class=\"javascript\">computed: {   itemsTrigger () {      return JSON.stringify(items.map(item =&gt; ({        id: item.id,        title: item.title,        userId: item.userId      })))    } }, watch: {   itemsTrigger () {     \/\/ \u0417\u0434\u0435\u0441\u044c \u043d\u0435 \u043d\u0443\u0436\u0435\u043d JSON.parse - \u0434\u0435\u0448\u0435\u0432\u043b\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u043c this.items;    } }<\/code><\/pre>\n<p>\u041e\u0447\u0435\u0432\u0438\u0434\u043d\u043e, \u0447\u0435\u043c \u0442\u043e\u0447\u043d\u0435\u0435 \u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u0434\u043b\u044f \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u043d\u0438\u044f watcher, \u0442\u0435\u043c \u043b\u0443\u0447\u0448\u0435, \u0442\u0435\u043c \u0442\u043e\u0447\u043d\u0435\u0435 \u043e\u043d \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442. <br \/> \u041e\u0431\u044a\u0435\u043a\u0442\u043d\u044b\u0439 watcher &#8212; \u043f\u043b\u043e\u0445\u043e, deep watcher &#8212; \u0435\u0449\u0435 \u0445\u0443\u0436\u0435. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 deep \u0432 \u043a\u043e\u0434\u0435 &#8212; \u0447\u0430\u0441\u0442\u044b\u0439 \u043f\u0440\u0438\u0437\u043d\u0430\u043a \u043d\u0435\u0433\u0440\u0430\u043c\u043e\u0442\u043d\u043e\u0441\u0442\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430. \u0422\u0438\u043f\u0430 \u044f \u043d\u0435 \u043f\u043e\u043d\u0438\u043c\u0430\u044e \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u044d\u0442\u043e\u0442 \u043a\u043e\u0434, \u043a\u0430\u043a\u0438\u043c\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c\u0438 \u043e\u043d \u043e\u043f\u0435\u0440\u0438\u0440\u0443\u0435\u0442, \u043d\u043e \u0447\u0442\u043e-\u0442\u043e \u0438\u043d\u043e\u0433\u0434\u0430 \u043d\u0435 \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442, \u043d\u0430\u0432\u0435\u0448\u0443-\u043a\u0430 \u044f deep &#8212; \u043e \u0432\u0440\u043e\u0434\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442.<\/p>\n<p>\u042d\u0442\u043e \u0447\u0442\u043e-\u0442\u043e \u0443\u0440\u043e\u0432\u043d\u044f.. (\u0431\u044b\u043b \u0443 \u043c\u0435\u043d\u044f \u0438 \u0442\u0430\u043a\u043e\u0439 \u043f\u0440\u043e\u0435\u043a\u0442).. \u0432 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0435 \u043d\u0435 \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u043b\u0430 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c, \u0438 \u0432\u043c\u0435\u0441\u0442\u043e \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u0439\u0442\u0438 \u043e\u0448\u0438\u0431\u043a\u0443, \u0431\u044b\u043b \u043f\u043e\u0432\u0435\u0448\u0435\u043d $emit(&#8216;reinit&#8217;), \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0443\u0431\u0438\u0432\u0430\u043b \u0434\u0430\u043d\u043d\u044b\u0439 \u0438 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u043b \u0435\u0433\u043e \u0437\u0430\u043d\u043e\u0432\u043e \u0432 $nextTick. \u0412\u0441\u0435 \u044d\u0442\u043e \u0437\u0430\u0431\u0430\u0432\u043d\u043e \u043c\u0438\u0433\u0430\u043b\u043e.<\/p>\n<h2>2. \u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u0438 \u0447\u0435\u0440\u0435\u0437 Object.freeze<\/h2>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 Object.freeze \u043d\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0435 TeamHood \u0441\u043e\u043a\u0440\u0430\u0442\u0438\u043b\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u0435 \u043f\u0430\u043c\u044f\u0442\u0438 \u0432 2 \u0440\u0430\u0437\u0430. \u041e\u0434\u043d\u0430\u043a\u043e \u043e\u043d\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0441\u044f \u043a \u043c\u043e\u0435\u043c\u0443 \u0432\u0442\u043e\u0440\u043e\u043c\u0443 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0443, StarBright, \u0433\u0434\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f nuxt \u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0439 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433. Nuxt \u043f\u043e\u0434\u0440\u0430\u0437\u0443\u043c\u0435\u0432\u0430\u0435\u0442, \u0447\u0442\u043e \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0431\u0443\u0434\u0443\u0442 \u043e\u0442\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u0437\u0430\u0440\u0430\u043d\u0435\u0435. \u041e\u0442\u0432\u0435\u0442\u044b \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u044e\u0442\u0441\u044f \u0432 vuex store (\u0438 \u043f\u043e\u0442\u043e\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435). \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0432\u0441\u044e \u043b\u043e\u0433\u0438\u043a\u0443 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u043c\u0438 \u0438 \u043a\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0445 \u0443\u0434\u043e\u0431\u043d\u0435\u0435 \u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0432 vuex. \u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0434\u0435\u043b\u0430\u0435\u0442 this.$store.dispatch(&#8216;fetch&#8217;, \u2026), \u0430 vuex \u043e\u0442\u0434\u0430\u0435\u0442 \u043a\u0435\u0448 \u0438\u043b\u0438 \u0434\u0435\u043b\u0430\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441.<\/p>\n<p>\u0421\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u0432 vuex \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c\u0441\u044f \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043e\u0431\u044a\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0445. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0432\u0432\u043e\u0434\u0438\u043b \u0430\u0434\u0440\u0435\u0441, autocomplete \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u043b \u043c\u0430\u0441\u0441\u0438\u0432 \u0433\u043e\u0440\u043e\u0434\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u044b\u043b \u0437\u0430\u043a\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d \u0432 store \u0441 \u0446\u0435\u043b\u044c\u044e \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u0439 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438. \u0414\u0430\u043d\u043d\u044b\u0435 \u0441\u0442\u0430\u0442\u0438\u0447\u043d\u044b, \u043e\u0434\u043d\u0430\u043a\u043e vue \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0434\u0435\u043b\u0430\u0435\u0442 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u043c \u043a\u0430\u0436\u0434\u043e\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430 (\u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e). \u0412\u043e \u043c\u043d\u043e\u0433\u0438\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 \u044d\u0442\u043e \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u0432\u044b\u0441\u043e\u043a\u043e\u043c\u0443 \u0440\u0430\u0441\u0445\u043e\u0434\u0443 \u043f\u0430\u043c\u044f\u0442\u0438, \u0438 \u043b\u0443\u0447\u0448\u0435 \u043f\u043e\u0436\u0435\u0440\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c\u044e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0445 \u0441\u0432\u043e\u0439\u0441\u0442\u0432.<\/p>\n<pre><code class=\"javascript\">\/\/ \u0412\u043c\u0435\u0441\u0442\u043e state: () =&gt; ({   items: [] }), mutations: {   setItems (state, items) {     state.items = items   },   markItemCompleted (state, itemId) {     const item = state.items.find(item =&gt; item.id === itemId)     if (item) {       item.completed = true     }   } }  \/\/ \u0414\u0435\u043b\u0430\u0435\u043c state: () =&gt; ({   items: [] }), mutations: {   setItems (state, items) {     state.items = items.map(item =&gt; Object.freeze(item))   },   markItemCompleted (state, itemId) {     const itemIndex = state.items.find(item =&gt; item.id === itemId)     if (itemIndex !== -1) {       \/\/ \u041d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u0434\u0435\u043b\u0430\u0442\u044c item.completed = true (\u043e\u0431\u044a\u0435\u043a\u0442 \u0437\u0430\u043c\u043e\u0440\u043e\u0436\u0435\u043d), \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0432\u0435\u0441\u044c \u043e\u0431\u044a\u0435\u043a\u0442;       const newItem = {         ...state.items[itemIndex],         completed: true       }       state.items.splice(itemIndex, 1, Object.freeze(newItem))     }   } }<\/code><\/pre>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0437\u0434\u0435\u0441\u044c: <a href=\"https:\/\/kasheftin.github.io\/vue-rerendering-optimization\/#\/example2\" rel=\"noopener noreferrer nofollow\">example2<\/a>. \u0417\u0430\u043c\u0435\u0447\u0443, \u0447\u0442\u043e \u0437\u0430\u043c\u0435\u0440\u044f\u0442\u044c \u0440\u0430\u0441\u0445\u043e\u0434 \u043f\u0430\u043c\u044f\u0442\u0438 \u043d\u0443\u0436\u043d\u043e \u043d\u0430 build-\u0432\u0435\u0440\u0441\u0438\u0438 (\u043d\u0435 \u0432 development).<\/p>\n<h2>3. \u0424\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0435 \u0433\u0435\u0442\u0442\u0435\u0440\u044b<\/h2>\n<p>\u0418\u043d\u043e\u0433\u0434\u0430 \u044d\u0442\u043e \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u044e\u0442 \u0432 <a href=\"https:\/\/vuex.vuejs.org\/guide\/getters.html#method-style-access\" rel=\"noopener noreferrer nofollow\">\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438<\/a>. \u0424\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0435 \u0433\u0435\u0442\u0442\u0435\u0440\u044b \u043d\u0435 \u043a\u0435\u0448\u0438\u0440\u0443\u044e\u0442\u0441\u044f. \u0412\u043e\u0442 \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0434\u0435\u043b\u0430\u0442\u044c items.find \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430:<\/p>\n<pre><code class=\"javascript\">\/\/ Vuex:  getters: {   itemById: (state) =&gt; (itemId) =&gt; state.items.find(item =&gt; item.id === itemId) } ... \/\/ Some &lt;Item :item-id=\"itemId\" \/&gt; component: computed: {   item () { return this.$store.getters.itemById(this.itemId) } }<\/code><\/pre>\n<p>\u0412\u043e\u0442 \u044d\u0442\u043e \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442 \u043e\u0431\u044a\u0435\u043a\u0442 itemsByIds \u043f\u0440\u0438 \u043f\u0435\u0440\u0432\u043e\u043c \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0438 \u0438 \u0437\u0430\u043a\u0435\u0448\u0438\u0440\u0443\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<pre><code class=\"javascript\">getters: {   itemByIds: (state) =&gt; state.items.reduce((out, item) =&gt; {     out[item.id] = item     return out   }, {}) } \/\/ Some &lt;Item :item-id=\"itemId\" \/&gt; component: computed: {   item () { return this.$store.getters.itemsByIds[this.itemId] } }<\/code><\/pre>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0437\u0434\u0435\u0441\u044c: <a href=\"https:\/\/kasheftin.github.io\/vue-rerendering-optimization\/#\/example3\" rel=\"noopener noreferrer nofollow\">example3<\/a>.<\/p>\n<h2>4. \u0413\u0440\u0430\u043c\u043e\u0442\u043d\u043e\u0435 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043d\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b<\/h2>\n<p>\u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b &#8212; \u043a\u043b\u044e\u0447\u0435\u0432\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u044d\u043a\u043e\u0441\u0438\u0441\u0442\u0435\u043c\u044b vue. \u041f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430 \u0438 \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u0435\u0432 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f (shouldComponentUpdate) \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043b\u044f \u0441\u0442\u0440\u043e\u0438\u0442\u0435\u043b\u044c\u0441\u0442\u0432\u0430 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u041f\u0435\u0440\u0432\u043e\u0435 \u0437\u043d\u0430\u043a\u043e\u043c\u0441\u0442\u0432\u043e \u0441 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c\u0438 \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442 \u043d\u0430 \u0438\u043d\u0442\u0443\u0438\u0442\u0438\u0432\u043d\u043e-\u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u0443\u0440\u043e\u0432\u043d\u0435: \u0435\u0441\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u043a\u0430\u043a\u0438\u0445-\u0442\u043e \u043e\u0434\u043d\u043e\u0442\u0438\u043f\u043d\u044b\u0445 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432, \u0442\u043e\u0433\u0434\u0430 \u043d\u0430\u0432\u0435\u0440\u043d\u043e\u0435 \u0434\u043b\u044f \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u043b\u0443\u0447\u0448\u0435 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442.<\/p>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e, \u043a\u0440\u043e\u043c\u0435 \u0441\u043c\u044b\u0441\u043b\u043e\u0432\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b &#8212; \u044d\u0442\u043e \u043c\u043e\u0449\u043d\u044b\u0439 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c, \u0434\u0430\u044e\u0449\u0438\u0439 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c \u043d\u0430\u0434 \u0433\u0440\u0430\u043d\u0443\u043b\u044f\u0440\u043d\u043e\u0441\u0442\u044c\u044e \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0439, \u044d\u0442\u043e \u0448\u0442\u0443\u043a\u0430, \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0432\u043b\u0438\u044f\u044e\u0449\u0430\u044f \u043d\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c. \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0442\u0430\u043a\u043e\u0439 (\u0443\u0436\u0430\u0441\u043d\u044b\u0439) \u043a\u043e\u0434:<\/p>\n<pre><code class=\"javascript\">\/\/ Store: export const getters = {   extendedItems (state) {     return state.items.map(item =&gt; ({       ...item,       isChecked: state.checkedItemIds.includes(item.id)     }))   },   extendedItemsByIds (state, getters) {     return getters.extendedItems.reduce((out, extendedItem) =&gt; {       out[extendedItem.id] = extendedItem       return out     }, {})   } }  \/\/ App.vue: &lt;ItemById for=\"id in $store.state.ids\" :key=\"id\" :item-id=\"id \/&gt;  \/\/ Item.vue: &lt;template&gt;   &lt;div&gt;{{ item.title }}&lt;\/div&gt; &lt;\/template&gt;  &lt;script&gt; export default {   props: ['itemId'],   computed: {     item () { return this.$store.getters.extendedItemsByIds[this.itemId] }   },   updated () {     console.count('Item updated')   } } &lt;\/script&gt;<\/code><\/pre>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0440\u0430\u0431\u043e\u0442\u044b \u0437\u0434\u0435\u0441\u044c: <a href=\"https:\/\/kasheftin.github.io\/vue-rerendering-optimization\/#\/example4p1\" rel=\"noopener noreferrer nofollow\">example4p1<\/a>. \u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u043b\u044e\u0431\u043e\u0433\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u043e\u0434\u043d\u043e\u0433\u043e item \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0432\u0441\u0435\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 &lt;Item&gt;. \u041f\u0440\u0438\u0447\u0438\u043d\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0438 &lt;Item&gt; \u0441\u0441\u044b\u043b\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u043e\u0431\u044a\u0435\u043a\u0442 extendedItemsByIds, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0435\u0440\u0435\u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u0437\u0430\u043d\u043e\u0432\u043e \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u043b\u044e\u0431\u043e\u0433\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u043b\u044e\u0431\u043e\u0433\u043e item. <\/p>\n<p>\u041a\u0430\u0436\u0434\u044b\u0439 vue \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 &#8212; \u044d\u0442\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043e\u0442\u0434\u0430\u0435\u0442 virtual DOM \u0438 \u043a\u0435\u0448\u0438\u0440\u0443\u0435\u0442 \u0435\u0433\u043e (memoization). \u0412\u0445\u043e\u0434\u043d\u044b\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u0444\u0443\u043d\u043a\u0446\u0438\u0438 &#8212; \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 &#8212; \u043e\u0442\u043b\u0435\u0436\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 dry run \u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u0442 \u0438\u0437 \u0441\u0441\u044b\u043b\u043e\u043a \u043d\u0430 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0432 props \u0438 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0442\u0438\u043f\u0430 $store. \u0415\u0441\u043b\u0438 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 &#8212; \u043f\u043e\u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043d\u043e \u0440\u0430\u0432\u043d\u044b\u0439 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c\u0443 \u043d\u043e\u0432\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442, \u043a\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0435 \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442.<\/p>\n<p>\u0418\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 store \u043d\u0435\u0443\u0434\u0430\u0447\u043d\u0430\u044f. \u041c\u044b \u043d\u0430\u0447\u0430\u043b\u0438 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c normalizr \u043f\u043e\u0434\u0445\u043e\u0434, \u043d\u043e \u043d\u0435 \u0434\u043e\u0434\u0435\u043b\u0430\u043b\u0438. \u0423\u0434\u043e\u0431\u043d\u0435\u0435 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0443 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u043c \u043c\u0430\u0441\u0441\u0438\u0432\u0435 ids. \u0422\u0430\u043a \u0436\u0435, \u0432\u043c\u0435\u0441\u0442\u043e \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0432\u0441\u0435\u0445 \u0441\u0432\u043e\u0439\u0441\u0442\u0432 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0432 getter, \u043b\u0443\u0447\u0448\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u0432\u0435\u0441\u044c \u043e\u0431\u044a\u0435\u043a\u0442. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0442\u0430\u043a:<\/p>\n<pre><code class=\"javascript\">\/\/ Store: export const state = () =&gt; ({   ids: [],   itemsByIds: {},   checkedIds: [] })  export const getters = {   extendedItems (state, getters) {     return state.ids.map(id =&gt; ({       id,       item: state.itemsByIds[id],       isChecked: state.checkedIds.includes(id)     }))   } }  export const mutations = {   renameItem (state, { id, title }) {     const item = state.itemsByIds[id]     if (item) {       state.itemsByIds[id] = Object.freeze({         ...item,         title       })     }   },   setCheckedItemById (state, { id, isChecked }) {     const index = state.checkedIds.indexOf(id)     if (isChecked &amp;&amp; index === -1) {       state.checkedIds.push(id)     } else if (!isChecked &amp;&amp; index !== -1) {       state.checkedIds.splice(index, 1)     }   } }  \/\/ Item.vue: computed: {   item () {     return this.$store.state.itemsByIds[this.itemId]   },   isChecked () {     return this.$store.state.checkedIds.includes(this.itemId)   } }<\/code><\/pre>\n<p>\u0417\u0430\u043c\u0435\u0442\u0438\u043c, \u0447\u0442\u043e \u043c\u0443\u0442\u0430\u0446\u0438\u044f renameItem \u043d\u0435 \u043f\u0435\u0440\u0435\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442 state.itemsByIds, \u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u043e\u0442\u0442\u0443\u0434\u0430. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 rename \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e: <a href=\"https:\/\/kasheftin.github.io\/vue-rerendering-optimization\/#\/example4p2\" rel=\"noopener noreferrer nofollow\">example4p2<\/a>. \u041e\u0434\u043d\u0430\u043a\u043e isChecked \u0432\u0441\u0435 \u0440\u0430\u0432\u043d\u043e \u0441\u0441\u044b\u043b\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0432\u0435\u0441\u044c state.checkedIds (\u0438\u0449\u0435\u0442 \u0442\u0430\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435), \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0447\u0435\u043a\u0431\u043e\u043a\u0441 \u043f\u043e-\u043f\u0440\u0435\u0436\u043d\u0435\u043c\u0443 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u043f\u043e\u043b\u043d\u044b\u0439 \u0440\u0435\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u0432\u0441\u0435\u0445 &lt;Item&gt;.<\/p>\n<p>\u042d\u0442\u0430 \u043e\u0448\u0438\u0431\u043a\u0430 \u0443\u0439\u0434\u0435\u0442, \u0435\u0441\u043b\u0438 \u0432 \u043a\u0430\u0436\u0434\u044b\u0439 &lt;Item&gt; \u0433\u0440\u0430\u043d\u0443\u043b\u044f\u0440\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0433\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b:<\/p>\n<pre><code class=\"javascript\">&lt;Item   v-for=\"extendedItem in extendedItems\"   :key=\"extendedItem.id\"   :item=\"extendedItem.item\"   :is-checked=\"extendedItem.isChecked\" \/&gt;<\/code><\/pre>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0437\u0434\u0435\u0441\u044c: <a href=\"https:\/\/kasheftin.github.io\/vue-rerendering-optimization\/#\/example4p3\" rel=\"noopener noreferrer nofollow\">example4p3<\/a>.<\/p>\n<h2>5. \u041f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 IntersectionObserver<\/h2>\n<p>\u041e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0430 \u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e DOM-\u0434\u0435\u0440\u0435\u0432\u0430 \u0442\u043e\u0440\u043c\u043e\u0437\u0438\u0442 \u0441\u0430\u043c\u0430 \u043f\u043e \u0441\u0435\u0431\u0435. \u041c\u044b \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0442\u0435\u0445\u043d\u0438\u043a \u0434\u043b\u044f \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043d\u0430 gantt \u0441\u0445\u0435\u043c\u0430\u0445 \u0440\u0430\u0437\u043c\u0435\u0440\u044b \u0438 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0431\u043b\u043e\u043a\u043e\u0432 \u0437\u0430\u0440\u0430\u043d\u0435\u0435 \u0440\u0430\u0441\u0447\u0438\u0442\u0430\u043d\u044b, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e, \u0447\u0442\u043e \u043f\u043e\u043f\u0430\u0434\u0430\u0435\u0442 \u0432 viewport. \u041d\u0435\u0432\u0438\u0434\u0438\u043c\u044b\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u043d\u0435 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u044e\u0442\u0441\u044f. \u0412 \u0434\u0440\u0443\u0433\u0438\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 \u0440\u0430\u0437\u043c\u0435\u0440\u044b \u0437\u0430\u0440\u0430\u043d\u0435\u0435 \u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b, \u0442\u043e\u0433\u0434\u0430 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u043f\u0440\u0438\u0435\u043c \u0441 intersection observer. \u0412 vuetify \u0435\u0441\u0442\u044c v-intersect \u0434\u0438\u0440\u0435\u043a\u0442\u0438\u0432\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438, \u043e\u0434\u043d\u0430\u043a\u043e \u043e\u043d\u0430 \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 IntersectionObserver \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0441\u0432\u043e\u0439 \u0431\u0438\u043d\u0434\u0438\u043d\u0433, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 \u0434\u043b\u044f \u0441\u043b\u0443\u0447\u0430\u044f, \u043a\u043e\u0433\u0434\u0430 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u043c\u043d\u043e\u0433\u043e.<\/p>\n<p>\u0412\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u043c \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c: <a href=\"https:\/\/kasheftin.github.io\/vue-rerendering-optimization\/#\/example5\" rel=\"noopener noreferrer nofollow\">example5<\/a>. \u0422\u0430\u043c 100 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 (\u043d\u0430 \u044d\u043a\u0440\u0430\u043d\u0435 \u043f\u043e\u043c\u0435\u0449\u0430\u0435\u0442\u0441\u044f 10), \u0432 \u043a\u0430\u0436\u0434\u043e\u043c \u043c\u0438\u0433\u0430\u0435\u0442 \u0442\u044f\u0436\u0435\u043b\u0430\u044f \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0430, \u0437\u0430\u043c\u0435\u0440\u044f\u0435\u0442\u0441\u044f \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0430 \u043c\u0435\u0436\u0434\u0443 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u043c \u043c\u0438\u0433\u0430\u043d\u0438\u0435\u043c \u0438 \u0440\u0430\u0441\u0447\u0435\u0442\u043d\u044b\u043c. \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043e\u0434\u0438\u043d \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 IntersectionObserver \u0438 \u043f\u0440\u043e\u0431\u0440\u043e\u0441\u0438\u043c \u0435\u0433\u043e \u0447\u0435\u0440\u0435\u0437 \u0434\u0438\u0440\u0435\u043a\u0442\u0438\u0432\u0443 \u0432\u043e \u0432\u0441\u0435 \u0443\u0437\u043b\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c.\u0412\u0441\u0435, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u043e\u0442 \u0434\u0438\u0440\u0435\u043a\u0442\u0438\u0432\u044b &#8212; \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u043e\u043c IntersectionObserver:<\/p>\n<pre><code class=\"javascript\">export default {   inserted (el, { value: observer }) {     if (observer instanceof IntersectionObserver) {       observer.observe(el)     }     el._intersectionObserver = observer   },   update (el, { value: newObserver }) {     const oldObserver = el._intersectionObserver     const isOldObserver = oldObserver instanceof IntersectionObserver     const isNewObserver = newObserver instanceof IntersectionObserver     if (!isOldObserver &amp;&amp; !isNewObserver) || (isOldObserver &amp;&amp; (oldObserver === newObserver)) {       return false     }     if (isOldObserver) {       oldObserver.unobserve(el)       el._intersectionObserver = undefined     }     if (isNewObserver) {       newObserver.observe(el)       el._intersectionObserver = newObserver     }   },   unbind (el) {     if (el._intersectionObserver instanceof IntersectionObserver) {       el._intersectionObserver.unobserve(el)     }     el._intersectionObserver = undefined   } }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e, \u043a\u0430\u043a\u0438\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0441\u043f\u0438\u0441\u043a\u0430 \u043d\u0435 \u0432\u0438\u0434\u043d\u044b, \u0432\u043e\u043f\u0440\u043e\u0441, \u043a\u0430\u043a \u0438\u0445 \u043e\u0431\u043b\u0435\u0433\u0447\u0430\u0442\u044c. \u041c\u043e\u0436\u043d\u043e, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u0440\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043a\u0430\u043a\u0438\u0435-\u0442\u043e vue \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435, \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0442\u044f\u0436\u0435\u043b\u044b\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f \u043d\u0430 \u043b\u0435\u0433\u043a\u0443\u044e \u0437\u0430\u0433\u043b\u0443\u0448\u043a\u0443. \u041e\u0434\u043d\u0430\u043a\u043e \u0432\u0430\u0436\u043d\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c, \u0447\u0442\u043e \u0441\u043b\u043e\u0436\u043d\u044b\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0441\u043b\u043e\u0436\u043d\u043e \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0442\u044c. \u041f\u0440\u0438 \u0431\u044b\u0441\u0442\u0440\u043e\u043c \u0441\u043a\u0440\u043e\u043b\u0438\u043d\u0433\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0437\u0430\u0442\u0443\u043f\u0438\u0442 \u0438\u0437-\u0437\u0430 \u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0439 \u0438 \u0434\u0435\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0439. \u041f\u0440\u0430\u043a\u0442\u0438\u043a\u0430 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442, \u0447\u0442\u043e \u0445\u043e\u0440\u043e\u0448\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441\u043a\u0440\u044b\u0442\u0438\u0435 \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 css:<\/p>\n<pre><code class=\"javascript\">&lt;template&gt;   &lt;div      v-for=\"i in 100\"      :key=\"i\"      v-node-intersect=\"intersectionObserver\"     class=\"rr-intersectionable\"   &gt;     &lt;Heavy \/&gt;   &lt;\/div&gt; &lt;\/template&gt;  &lt;script&gt; export default {   data () {     return {       intersectionObserver: new IntersectionObserver(this.handleIntersections)     }   },   methods: {     handleIntersections (entries) {       entries.forEach((entry) =&gt; {         const className = 'rr-intersectionable--invisible'         if (entry.isIntersecting) {           entry.target.classList.remove(className)         } else {           entry.target.classList.add(className)         }       })     }   } } &lt;\/script&gt;  &lt;style&gt; .rr-intersectionable--invisible .rr-heavy-part   display: none &lt;\/style&gt;<\/code><\/pre>\n<h2>\u0421\u0441\u044b\u043b\u043a\u0438<\/h2>\n<ul>\n<li>\n<p>\u0418\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432: <a href=\"https:\/\/kasheftin.github.io\/vue-rerendering-optimization\/\" rel=\"noopener noreferrer nofollow\">https:\/\/kasheftin.github.io\/vue-rerendering-optimization\/<\/a><\/p>\n<\/li>\n<li>\n<p>\u0412\u0441\u0435 \u0434\u0435\u043c\u043e: <a href=\"https:\/\/github.com\/Kasheftin\/vue-rerendering-optimization\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/Kasheftin\/vue-rerendering-optimization<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/codeburst.io\/caution-using-watchers-for-objects-in-vue-ecafb0af6493\" rel=\"noopener noreferrer nofollow\">Caution using watchers for objects in vue<\/a><\/p>\n<\/li>\n<\/ul>\n<\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/543298\/\"> https:\/\/habr.com\/ru\/post\/543298\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text_v2\" id=\"post-content-body\">\n<p>\u0423 \u043d\u0430\u0441 \u0432 TeamHood \u0435\u0441\u0442\u044c wiki. \u0422\u0430\u043c \u0441\u043e\u0431\u0440\u0430\u043b\u0430\u0441\u044c \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044f \u0440\u0435\u043a\u043e\u043c\u043c\u0435\u043d\u0434\u0430\u0446\u0438\u0439, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435, \u043f\u043e \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u044e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0442\u044f\u0436\u0435\u043b\u043e\u0433\u043e \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434\u0430 \u043d\u0430 vue.js. \u0423\u043b\u0443\u0447\u0448\u0430\u0442\u044c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u043b\u043e\u0441\u044c, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0432 \u0441\u0438\u043b\u0443 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0438 \u043d\u0430\u0448\u0438 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u044d\u043a\u0440\u0430\u043d\u044b \u043d\u0435 \u0438\u043c\u0435\u044e\u0442 \u043f\u0430\u0433\u0438\u043d\u0430\u0446\u0438\u0438. \u0415\u0441\u0442\u044c \u043a\u043b\u0438\u0435\u043d\u0442\u044b, \u0443 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043d\u0430 \u043e\u0434\u043d\u043e\u0439 kanban\/gantt \u0434\u043e\u0441\u043a\u0435 \u0431\u043e\u043b\u044c\u0448\u0435 \u0442\u044b\u0441\u044f\u0447\u0438 \u0432\u043e\u0442 \u0442\u0430\u043a\u0438\u0445 \u0432\u043e\u0442 \u043a\u0430\u0440\u0442\u043e\u0447\u0435\u043a, \u0432\u0441\u0435 \u044d\u0442\u043e \u0434\u043e\u043b\u0436\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0431\u0435\u0437 \u043b\u0430\u0433\u043e\u0432.<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043d\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0435\u0434\u043a\u043e \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u0435\u043c\u044b\u0445 \u0442\u0435\u0445\u043d\u0438\u043a \u0438\u0437 \u043d\u0430\u0448\u0435\u0439 wiki, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u043c\u043e\u0433\u0443\u0442 \u0441\u043e\u043a\u0440\u0430\u0442\u0438\u0442\u044c \u0438\u0437\u043b\u0438\u0448\u043d\u0438\u0439 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0438 \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u044c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c.<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440\u044b \u0441\u0442\u0430\u0442\u044c\u0438 \u0441\u043e\u0431\u0440\u0430\u043d\u044b \u0432 <a href=\"https:\/\/github.com\/Kasheftin\/vue-rerendering-optimization\" rel=\"noopener noreferrer nofollow\">\u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u043c \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438<\/a>. \u042d\u0442\u043e vue2 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u0445\u043e\u0442\u044f \u0432\u0441\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u0435\u043d\u043e \u0438 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u0442 \u0431\u044b\u0442\u044c \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u043c \u0434\u043b\u044f vue3. \u041f\u043e\u043a\u0430 \u0447\u0442\u043e \u043d\u0435 \u0432\u0441\u044f \u044d\u043a\u043e\u0441\u0438\u0441\u0442\u0435\u043c\u0430 vue3 production-ready. \u0412 vuex4 <a href=\"https:\/\/github.com\/vuejs\/vuex\/issues\/1934\" rel=\"noopener noreferrer nofollow\">\u0443\u0442\u0435\u043a\u0430\u0435\u0442 \u043f\u0430\u043c\u044f\u0442\u044c<\/a>, \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438 \u0442\u0430\u043c \u043f\u043e\u043a\u0430 \u0431\u0435\u0441\u0441\u043c\u044b\u0441\u043b\u0435\u043d\u043d\u043e (\u0447\u0442\u043e \u043e\u0431\u043d\u0430\u0434\u0435\u0436\u0438\u0432\u0430\u0435\u0442, \u0437\u0430\u0442\u0440\u0430\u0442\u044b \u043f\u0430\u043c\u044f\u0442\u0438 \u0442\u0430\u043c \u0432 \u0440\u0430\u0437\u044b \u043c\u0435\u043d\u044c\u0448\u0435 \u0447\u0435\u043c \u0432 vue2+vuex3). \u041f\u0440\u0438\u043c\u0435\u0440\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u044b \u043d\u0430 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u043c \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0435\u043c javascript, \u0431\u044b\u043b\u043e \u0438\u0441\u043a\u0443\u0448\u0435\u043d\u0438\u0435 \u0432\u043e\u0442\u043a\u043d\u0443\u0442\u044c vue-class-component, typescript, typed-vuex \u0438 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u0443\u044e \u043a\u0443\u0445\u043d\u044e \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u043d\u043e \u0443\u0434\u0435\u0440\u0436\u0430\u043b\u0441\u044f.<\/p>\n<h2>1. (Deep) Object Watchers<\/h2>\n<p>\u041f\u0440\u0430\u0432\u0438\u043b\u043e &#8212; \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c deep \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c watch \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432. \u0420\u0430\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u0440\u0438\u043c\u0435\u0440. \u041d\u0435\u043a\u0438\u0439 \u043c\u0430\u0441\u0441\u0438\u0432 items \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f \u0432 vuex store, \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0435\u0442\u0441\u044f, \u0432\u043e\u0437\u043b\u0435 \u043a\u0430\u0436\u0434\u043e\u0433\u043e item \u0435\u0441\u0442\u044c \u0447\u0435\u043a\u0431\u043e\u043a\u0441. \u0421\u0432\u043e\u0439\u0441\u0442\u0432\u043e isChecked \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0441\u044f \u043a \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0443, \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u043e\u0442 item, \u043e\u0434\u043d\u0430\u043a\u043e \u0435\u0441\u0442\u044c getter, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442 \u0438\u0445 \u0432\u043c\u0435\u0441\u0442\u0435:<\/p>\n<pre><code class=\"javascript\">export const state = () =&gt; ({   items: [{ id: 1, name: 'First' }, { id: 2, name: 'Second' }],   checkedItemIds: [1, 2] })  export const getters = {   extendedItems (state) {     return state.items.map(item =&gt; ({       ...item,       isChecked: state.checkedItemIds.includes(item.id)     }))   } }<\/code><\/pre>\n<p>\u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c, items \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043e\u0442\u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u044b, \u0431\u0443\u0434\u0435\u043c \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u043f\u043e\u0440\u044f\u0434\u043e\u043a. \u0427\u0442\u043e-\u0442\u043e \u0432\u0440\u043e\u0434\u0435:<\/p>\n<pre><code class=\"javascript\">export default class ItemList extends Vue {   computed: {     extendedItems () { return this.$store.getters.extendedItems },     itemIds () { return this.extendedItems.map(item =&gt; item.id) }   },   watch: {     itemIds () {       console.log('Saving new items order...', this.itemIds)      }   } }<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0447\u0435\u043a\u0431\u043e\u043a\u0441\u0430 \u0443 \u043b\u044e\u0431\u043e\u0433\u043e item \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0438\u0437\u043b\u0438\u0448\u043d\u0435\u0435 \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u043d\u0438\u0435 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u043f\u043e\u0440\u044f\u0434\u043a\u0430. \u041a\u043e\u043d\u0441\u0442\u0440\u0443\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u043e\u0432\u044b\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 &#8212; \u043d\u0430\u0441\u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u043f\u0440\u043e\u0446\u0435\u0441\u0441, \u0447\u0442\u043e \u0434\u0430\u0436\u0435 \u0432 \u044d\u0442\u043e\u043c \u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043c\u044b \u0434\u0435\u043b\u0430\u0435\u043c \u044d\u0442\u043e \u0434\u0432\u0430\u0436\u0434\u044b. \u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 checkedItemIds \u0432\u044b\u0437\u0432\u0430\u0435\u0442 \u043f\u0435\u0440\u0435\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 extendedItems (\u0438 \u043f\u0435\u0440\u0435\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u044d\u0442\u043e\u0433\u043e \u043c\u0430\u0441\u0441\u0438\u0432\u0430), \u0437\u0430\u0442\u0435\u043c \u0438\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 itemIds. \u042d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u043a\u043e\u043d\u0442\u0440\u0430-\u0438\u043d\u0442\u0443\u0438\u0442\u0438\u0432\u043d\u044b\u043c, \u0432\u0435\u0434\u044c \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u043c\u0430\u0441\u0441\u0438\u0432, \u0441\u043e\u0441\u0442\u043e\u044f\u0449\u0438\u0439 \u0438\u0437 \u0442\u0435\u0445 \u0436\u0435 \u0441\u0430\u043c\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0432 \u0442\u043e\u043c \u0436\u0435 \u0441\u0430\u043c\u043e\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0435. \u041e\u0434\u043d\u0430\u043a\u043e, \u044d\u0442\u043e \u043f\u0440\u0438\u0440\u043e\u0434\u0430 javascript, [1,2,3] != [1,2,3]. \u0414\u0435\u043c\u043e \u0437\u0434\u0435\u0441\u044c: <a href=\"https:\/\/kasheftin.github.io\/vue-rerendering-optimization\/#\/example1\" rel=\"noopener noreferrer nofollow\">example1<\/a>.<\/p>\n<p>\u0420\u0435\u0448\u0435\u043d\u0438\u0435 &#8212; \u043f\u043e\u043b\u043d\u044b\u0439 \u043e\u0442\u043a\u0430\u0437 \u043e\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f watcher \u0434\u043b\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0438 \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u0432.  \u0414\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0441\u043b\u043e\u0436\u043d\u043e\u0433\u043e watcher \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 computed \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430.  \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0435\u0441\u043b\u0438 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 <code>{id, title, userId}<\/code>\u0432 \u043c\u0430\u0441\u0441\u0438\u0432\u0435 items, \u043c\u043e\u0436\u043d\u043e \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0443:<\/p>\n<pre><code class=\"javascript\">computed: {   itemsTrigger () {      return JSON.stringify(items.map(item =&gt; ({        id: item.id,        title: item.title,        userId: item.userId      })))    } }, watch: {   itemsTrigger () {     \/\/ \u0417\u0434\u0435\u0441\u044c \u043d\u0435 \u043d\u0443\u0436\u0435\u043d JSON.parse - \u0434\u0435\u0448\u0435\u0432\u043b\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u043c this.items;    } }<\/code><\/pre>\n<p>\u041e\u0447\u0435\u0432\u0438\u0434\u043d\u043e, \u0447\u0435\u043c \u0442\u043e\u0447\u043d\u0435\u0435 \u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u0434\u043b\u044f \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u043d\u0438\u044f watcher, \u0442\u0435\u043c \u043b\u0443\u0447\u0448\u0435, \u0442\u0435\u043c \u0442\u043e\u0447\u043d\u0435\u0435 \u043e\u043d \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442. <br \/> \u041e\u0431\u044a\u0435\u043a\u0442\u043d\u044b\u0439 watcher &#8212; \u043f\u043b\u043e\u0445\u043e, deep watcher &#8212; \u0435\u0449\u0435 \u0445\u0443\u0436\u0435. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 deep \u0432 \u043a\u043e\u0434\u0435 &#8212; \u0447\u0430\u0441\u0442\u044b\u0439 \u043f\u0440\u0438\u0437\u043d\u0430\u043a \u043d\u0435\u0433\u0440\u0430\u043c\u043e\u0442\u043d\u043e\u0441\u0442\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430. \u0422\u0438\u043f\u0430 \u044f \u043d\u0435 \u043f\u043e\u043d\u0438\u043c\u0430\u044e \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u044d\u0442\u043e\u0442 \u043a\u043e\u0434, \u043a\u0430\u043a\u0438\u043c\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c\u0438 \u043e\u043d \u043e\u043f\u0435\u0440\u0438\u0440\u0443\u0435\u0442, \u043d\u043e \u0447\u0442\u043e-\u0442\u043e \u0438\u043d\u043e\u0433\u0434\u0430 \u043d\u0435 \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442, \u043d\u0430\u0432\u0435\u0448\u0443-\u043a\u0430 \u044f deep &#8212; \u043e \u0432\u0440\u043e\u0434\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442.<\/p>\n<p>\u042d\u0442\u043e \u0447\u0442\u043e-\u0442\u043e \u0443\u0440\u043e\u0432\u043d\u044f.. (\u0431\u044b\u043b \u0443 \u043c\u0435\u043d\u044f \u0438 \u0442\u0430\u043a\u043e\u0439 \u043f\u0440\u043e\u0435\u043a\u0442).. \u0432 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0435 \u043d\u0435 \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u043b\u0430 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c, \u0438 \u0432\u043c\u0435\u0441\u0442\u043e \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u0439\u0442\u0438 \u043e\u0448\u0438\u0431\u043a\u0443, \u0431\u044b\u043b \u043f\u043e\u0432\u0435\u0448\u0435\u043d $emit(&#8216;reinit&#8217;), \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0443\u0431\u0438\u0432\u0430\u043b \u0434\u0430\u043d\u043d\u044b\u0439 \u0438 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u043b \u0435\u0433\u043e \u0437\u0430\u043d\u043e\u0432\u043e \u0432 $nextTick. \u0412\u0441\u0435 \u044d\u0442\u043e \u0437\u0430\u0431\u0430\u0432\u043d\u043e \u043c\u0438\u0433\u0430\u043b\u043e.<\/p>\n<h2>2. \u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u0438 \u0447\u0435\u0440\u0435\u0437 Object.freeze<\/h2>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 Object.freeze \u043d\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0435 TeamHood \u0441\u043e\u043a\u0440\u0430\u0442\u0438\u043b\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u0435 \u043f\u0430\u043c\u044f\u0442\u0438 \u0432 2 \u0440\u0430\u0437\u0430. \u041e\u0434\u043d\u0430\u043a\u043e \u043e\u043d\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0441\u044f \u043a \u043c\u043e\u0435\u043c\u0443 \u0432\u0442\u043e\u0440\u043e\u043c\u0443 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0443, StarBright, \u0433\u0434\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f nuxt \u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0439 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433. Nuxt \u043f\u043e\u0434\u0440\u0430\u0437\u0443\u043c\u0435\u0432\u0430\u0435\u0442, \u0447\u0442\u043e \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0431\u0443\u0434\u0443\u0442 \u043e\u0442\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u0437\u0430\u0440\u0430\u043d\u0435\u0435. \u041e\u0442\u0432\u0435\u0442\u044b \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u044e\u0442\u0441\u044f \u0432 vuex store (\u0438 \u043f\u043e\u0442\u043e\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435). \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0432\u0441\u044e \u043b\u043e\u0433\u0438\u043a\u0443 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u043c\u0438 \u0438 \u043a\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0445 \u0443\u0434\u043e\u0431\u043d\u0435\u0435 \u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0432 vuex. \u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0434\u0435\u043b\u0430\u0435\u0442 this.$store.dispatch(&#8216;fetch&#8217;, \u2026), \u0430 vuex \u043e\u0442\u0434\u0430\u0435\u0442 \u043a\u0435\u0448 \u0438\u043b\u0438 \u0434\u0435\u043b\u0430\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441.<\/p>\n<p>\u0421\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u0432 vuex \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c\u0441\u044f \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043e\u0431\u044a\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0445. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0432\u0432\u043e\u0434\u0438\u043b \u0430\u0434\u0440\u0435\u0441, autocomplete \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u043b \u043c\u0430\u0441\u0441\u0438\u0432 \u0433\u043e\u0440\u043e\u0434\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u044b\u043b \u0437\u0430\u043a\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d \u0432 store \u0441 \u0446\u0435\u043b\u044c\u044e \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u0439 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438. \u0414\u0430\u043d\u043d\u044b\u0435 \u0441\u0442\u0430\u0442\u0438\u0447\u043d\u044b, \u043e\u0434\u043d\u0430\u043a\u043e vue \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0434\u0435\u043b\u0430\u0435\u0442 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u043c \u043a\u0430\u0436\u0434\u043e\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430 (\u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e). \u0412\u043e \u043c\u043d\u043e\u0433\u0438\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 \u044d\u0442\u043e \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u0432\u044b\u0441\u043e\u043a\u043e\u043c\u0443 \u0440\u0430\u0441\u0445\u043e\u0434\u0443 \u043f\u0430\u043c\u044f\u0442\u0438, \u0438 \u043b\u0443\u0447\u0448\u0435 \u043f\u043e\u0436\u0435\u0440\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c\u044e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0445 \u0441\u0432\u043e\u0439\u0441\u0442\u0432.<\/p>\n<pre><code class=\"javascript\">\/\/ \u0412\u043c\u0435\u0441\u0442\u043e state: () =&gt; ({   items: [] }), mutations: {   setItems (state, items) {     state.items = items   },   markItemCompleted (state, itemId) {     const item = state.items.find(item =&gt; item.id === itemId)     if (item) {       item.completed = true     }   } }  \/\/ \u0414\u0435\u043b\u0430\u0435\u043c state: () =&gt; ({   items: [] }), mutations: {   setItems (state, items) {     state.items = items.map(item =&gt; Object.freeze(item))   },   markItemCompleted (state, itemId) {     const itemIndex = state.items.find(item =&gt; item.id === itemId)     if (itemIndex !== -1) {       \/\/ \u041d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u0434\u0435\u043b\u0430\u0442\u044c item.completed = true (\u043e\u0431\u044a\u0435\u043a\u0442 \u0437\u0430\u043c\u043e\u0440\u043e\u0436\u0435\u043d), \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0432\u0435\u0441\u044c \u043e\u0431\u044a\u0435\u043a\u0442;       const newItem = {         ...state.items[itemIndex],         completed: true       }       state.items.splice(itemIndex, 1, Object.freeze(newItem))     }   } }<\/code><\/pre>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0437\u0434\u0435\u0441\u044c: <a href=\"https:\/\/kasheftin.github.io\/vue-rerendering-optimization\/#\/example2\" rel=\"noopener noreferrer nofollow\">example2<\/a>. \u0417\u0430\u043c\u0435\u0447\u0443, \u0447\u0442\u043e \u0437\u0430\u043c\u0435\u0440\u044f\u0442\u044c \u0440\u0430\u0441\u0445\u043e\u0434 \u043f\u0430\u043c\u044f\u0442\u0438 \u043d\u0443\u0436\u043d\u043e \u043d\u0430 build-\u0432\u0435\u0440\u0441\u0438\u0438 (\u043d\u0435 \u0432 development).<\/p>\n<h2>3. \u0424\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0435 \u0433\u0435\u0442\u0442\u0435\u0440\u044b<\/h2>\n<p>\u0418\u043d\u043e\u0433\u0434\u0430 \u044d\u0442\u043e \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u044e\u0442 \u0432 <a href=\"https:\/\/vuex.vuejs.org\/guide\/getters.html#method-style-access\" rel=\"noopener noreferrer nofollow\">\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438<\/a>. \u0424\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0435 \u0433\u0435\u0442\u0442\u0435\u0440\u044b \u043d\u0435 \u043a\u0435\u0448\u0438\u0440\u0443\u044e\u0442\u0441\u044f. \u0412\u043e\u0442 \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0434\u0435\u043b\u0430\u0442\u044c items.find \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430:<\/p>\n<pre><code class=\"javascript\">\/\/ Vuex:  getters: {   itemById: (state) =&gt; (itemId) =&gt; state.items.find(item =&gt; item.id === itemId) } ... \/\/ Some &lt;Item :item-id=\"itemId\" \/&gt; component: computed: {   item () { return this.$store.getters.itemById(this.itemId) } }<\/code><\/pre>\n<p>\u0412\u043e\u0442 \u044d\u0442\u043e \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442 \u043e\u0431\u044a\u0435\u043a\u0442 itemsByIds \u043f\u0440\u0438 \u043f\u0435\u0440\u0432\u043e\u043c \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0438 \u0438 \u0437\u0430\u043a\u0435\u0448\u0438\u0440\u0443\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<pre><code class=\"javascript\">getters: {   itemByIds: (state) =&gt; state.items.reduce((out, item) =&gt; {     out[item.id] = item     return out   }, {}) } \/\/ Some &lt;Item :item-id=\"itemId\" \/&gt; component: computed: {   item () { return this.$store.getters.itemsByIds[this.itemId] } }<\/code><\/pre>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0437\u0434\u0435\u0441\u044c: <a href=\"https:\/\/kasheftin.github.io\/vue-rerendering-optimization\/#\/example3\" rel=\"noopener noreferrer nofollow\">example3<\/a>.<\/p>\n<h2>4. \u0413\u0440\u0430\u043c\u043e\u0442\u043d\u043e\u0435 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043d\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b<\/h2>\n<p>\u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b &#8212; \u043a\u043b\u044e\u0447\u0435\u0432\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u044d\u043a\u043e\u0441\u0438\u0441\u0442\u0435\u043c\u044b vue. \u041f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430 \u0438 \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u0435\u0432 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f (shouldComponentUpdate) \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043b\u044f \u0441\u0442\u0440\u043e\u0438\u0442\u0435\u043b\u044c\u0441\u0442\u0432\u0430 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u041f\u0435\u0440\u0432\u043e\u0435 \u0437\u043d\u0430\u043a\u043e\u043c\u0441\u0442\u0432\u043e \u0441 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c\u0438 \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442 \u043d\u0430 \u0438\u043d\u0442\u0443\u0438\u0442\u0438\u0432\u043d\u043e-\u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u0443\u0440\u043e\u0432\u043d\u0435: \u0435\u0441\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u043a\u0430\u043a\u0438\u0445-\u0442\u043e \u043e\u0434\u043d\u043e\u0442\u0438\u043f\u043d\u044b\u0445 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432, \u0442\u043e\u0433\u0434\u0430 \u043d\u0430\u0432\u0435\u0440\u043d\u043e\u0435 \u0434\u043b\u044f \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u043b\u0443\u0447\u0448\u0435 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442.<\/p>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e, \u043a\u0440\u043e\u043c\u0435 \u0441\u043c\u044b\u0441\u043b\u043e\u0432\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b &#8212; \u044d\u0442\u043e \u043c\u043e\u0449\u043d\u044b\u0439 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c, \u0434\u0430\u044e\u0449\u0438\u0439 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c \u043d\u0430\u0434 \u0433\u0440\u0430\u043d\u0443\u043b\u044f\u0440\u043d\u043e\u0441\u0442\u044c\u044e \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0439, \u044d\u0442\u043e \u0448\u0442\u0443\u043a\u0430, \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0432\u043b\u0438\u044f\u044e\u0449\u0430\u044f \u043d\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c. \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0442\u0430\u043a\u043e\u0439 (\u0443\u0436\u0430\u0441\u043d\u044b\u0439) \u043a\u043e\u0434:<\/p>\n<pre><code class=\"javascript\">\/\/ Store: export const getters = {   extendedItems (state) {     return state.items.map(item =&gt; ({       ...item,       isChecked: state.checkedItemIds.includes(item.id)     }))   },   extendedItemsByIds (state, getters) {     return getters.extendedItems.reduce((out, extendedItem) =&gt; {       out[extendedItem.id] = extendedItem       return out     }, {})   } }  \/\/ App.vue: &lt;ItemById for=\"id in $store.state.ids\" :key=\"id\" :item-id=\"id \/&gt;  \/\/ Item.vue: &lt;template&gt;   &lt;div&gt;{{ item.title }}&lt;\/div&gt; &lt;\/template&gt;  &lt;script&gt; export default {   props: ['itemId'],   computed: {     item () { return this.$store.getters.extendedItemsByIds[this.itemId] }   },   updated () {     console.count('Item updated')   } } &lt;\/script&gt;<\/code><\/pre>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0440\u0430\u0431\u043e\u0442\u044b \u0437\u0434\u0435\u0441\u044c: <a href=\"https:\/\/kasheftin.github.io\/vue-rerendering-optimization\/#\/example4p1\" rel=\"noopener noreferrer nofollow\">example4p1<\/a>. \u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u043b\u044e\u0431\u043e\u0433\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u043e\u0434\u043d\u043e\u0433\u043e item \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0432\u0441\u0435\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 &lt;Item&gt;. \u041f\u0440\u0438\u0447\u0438\u043d\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0438 &lt;Item&gt; \u0441\u0441\u044b\u043b\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u043e\u0431\u044a\u0435\u043a\u0442 extendedItemsByIds, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0435\u0440\u0435\u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u0437\u0430\u043d\u043e\u0432\u043e \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u043b\u044e\u0431\u043e\u0433\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u043b\u044e\u0431\u043e\u0433\u043e item. <\/p>\n<p>\u041a\u0430\u0436\u0434\u044b\u0439 vue \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 &#8212; \u044d\u0442\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043e\u0442\u0434\u0430\u0435\u0442 virtual DOM \u0438 \u043a\u0435\u0448\u0438\u0440\u0443\u0435\u0442 \u0435\u0433\u043e (memoization). \u0412\u0445\u043e\u0434\u043d\u044b\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u0444\u0443\u043d\u043a\u0446\u0438\u0438 &#8212; \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 &#8212; \u043e\u0442\u043b\u0435\u0436\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 dry run \u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u0442 \u0438\u0437 \u0441\u0441\u044b\u043b\u043e\u043a \u043d\u0430 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0432 props \u0438 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0442\u0438\u043f\u0430 $store. \u0415\u0441\u043b\u0438 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 &#8212; \u043f\u043e\u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043d\u043e \u0440\u0430\u0432\u043d\u044b\u0439 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c\u0443 \u043d\u043e\u0432\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442, \u043a\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0435 \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442.<\/p>\n<p>\u0418\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 store \u043d\u0435\u0443\u0434\u0430\u0447\u043d\u0430\u044f. \u041c\u044b \u043d\u0430\u0447\u0430\u043b\u0438 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c normalizr \u043f\u043e\u0434\u0445\u043e\u0434, \u043d\u043e \u043d\u0435 \u0434\u043e\u0434\u0435\u043b\u0430\u043b\u0438. \u0423\u0434\u043e\u0431\u043d\u0435\u0435 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0443 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u043c \u043c\u0430\u0441\u0441\u0438\u0432\u0435 ids. \u0422\u0430\u043a \u0436\u0435, \u0432\u043c\u0435\u0441\u0442\u043e \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0432\u0441\u0435\u0445 \u0441\u0432\u043e\u0439\u0441\u0442\u0432 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0432 getter, \u043b\u0443\u0447\u0448\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u0432\u0435\u0441\u044c \u043e\u0431\u044a\u0435\u043a\u0442. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0442\u0430\u043a:<\/p>\n<pre><code class=\"javascript\">\/\/ Store: export const state = () =&gt; ({   ids: [],   itemsByIds: {},   checkedIds: [] })  export const getters = {   extendedItems (state, getters) {     return state.ids.map(id =&gt; ({       id,       item: state.itemsByIds[id],       isChecked: state.checkedIds.includes(id)     }))   } }  export const mutations = {   renameItem (state, { id, title }) {     const item = state.itemsByIds[id]     if (item) {       state.itemsByIds[id] = Object.freeze({         ...item,         title       })     }   },   setCheckedItemById (state, { id, isChecked }) {     const index = state.checkedIds.indexOf(id)     if (isChecked &amp;&amp; index === -1) {       state.checkedIds.push(id)     } else if (!isChecked &amp;&amp; index !== -1) {       state.checkedIds.splice(index, 1)     }   } }  \/\/ Item.vue: computed: {   item () {     return this.$store.state.itemsByIds[this.itemId]   },   isChecked () {     return this.$store.state.checkedIds.includes(this.itemId)   } }<\/code><\/pre>\n<p>\u0417\u0430\u043c\u0435\u0442\u0438\u043c, \u0447\u0442\u043e \u043c\u0443\u0442\u0430\u0446\u0438\u044f renameItem \u043d\u0435 \u043f\u0435\u0440\u0435\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442 state.itemsByIds, \u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u043e\u0442\u0442\u0443\u0434\u0430. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 rename \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e: <a href=\"https:\/\/kasheftin.github.io\/vue-rerendering-optimization\/#\/example4p2\" rel=\"noopener noreferrer nofollow\">example4p2<\/a>. \u041e\u0434\u043d\u0430\u043a\u043e isChecked \u0432\u0441\u0435 \u0440\u0430\u0432\u043d\u043e \u0441\u0441\u044b\u043b\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0432\u0435\u0441\u044c state.checkedIds (\u0438\u0449\u0435\u0442 \u0442\u0430\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435), \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0447\u0435\u043a\u0431\u043e\u043a\u0441 \u043f\u043e-\u043f\u0440\u0435\u0436\u043d\u0435\u043c\u0443 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u043f\u043e\u043b\u043d\u044b\u0439 \u0440\u0435\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u0432\u0441\u0435\u0445 &lt;Item&gt;.<\/p>\n<p>\u042d\u0442\u0430 \u043e\u0448\u0438\u0431\u043a\u0430 \u0443\u0439\u0434\u0435\u0442, \u0435\u0441\u043b\u0438 \u0432 \u043a\u0430\u0436\u0434\u044b\u0439 &lt;Item&gt; \u0433\u0440\u0430\u043d\u0443\u043b\u044f\u0440\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0433\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b:<\/p>\n<pre><code class=\"javascript\">&lt;Item<\/code><\/pre>\n<\/p>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-318289","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/318289","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=318289"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/318289\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=318289"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=318289"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=318289"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}