рдирдорд╕реНрдХрд╛рд░, рд╣реЗрдмреНрд░!
рдХреНрдпрд╛ рдЖрдкрдХреЛ рдиреМрдХрд░реА рдХреЗ рд╕рд╛рдХреНрд╖рд╛рддреНрдХрд╛рд░ рдкрд╕рдВрдж рд╣реИрдВ? рдФрд░ рдЕрдХреНрд╕рд░ рдЙрдиреНрд╣реЗрдВ рдЦрд░реНрдЪ рдХрд░рддреЗ рд╣реИрдВ? рдпрджрд┐ рджреВрд╕рд░реЗ рдкреНрд░рд╢реНрди рдХрд╛ рдЙрддреНрддрд░ "рд╣рд╛рдБ" рд╣реИ, рддреЛ рдЙрди рдЙрдореНрдореАрджрд╡рд╛рд░реЛрдВ рдореЗрдВ рд╕реЗ рдЖрдк рд╢рд╛рдпрдж рдЙрддреНрдХреГрд╖реНрдЯ рдФрд░ рд╕реНрдорд╛рд░реНрдЯ рд▓реЛрдЧреЛрдВ рд╕реЗ рдорд┐рд▓реЗ, рдЬрд┐рдиреНрд╣реЛрдВрдиреЗ рдЖрдкрдХреЗ рд╕рднреА рд╕рд╡рд╛рд▓реЛрдВ рдХреЗ рдЬрд╡рд╛рдм рджрд┐рдП рдФрд░ рдкреЗрд░реЛрд▓ рдХреЗ рдЕрдВрдд рдореЗрдВ рд╕рдВрдкрд░реНрдХ рдХрд┐рдпрд╛ред
рд▓реЗрдХрд┐рди рдЖрдк рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рдкреЗрд╢реЗрд╡рд░реЛрдВ рдХреЛ рдмрд╣реБрдд рдЕрдзрд┐рдХ рднреБрдЧрддрд╛рди рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рдФрд░ рдЙрдирдХреЗ рдореБрдХрд╛рдмрд▓реЗ рд╣реЛрд╢рд┐рдпрд╛рд░ рджрд┐рдЦрдирд╛ рдЬрд░реВрд░реА рд╣реИ, рдЙрдиреНрд╣реЗрдВ рдХреЗрд╡рд▓ рд╕рд╛рдХреНрд╖рд╛рддреНрдХрд╛рд░ рдХреА рдЕрд╡рдзрд┐ рдХреЗ рд▓рд┐рдП рджреЗрдВред
рдпрджрд┐ рдЖрдкрдХреЛ рдЗрд╕рдХреЗ рд╕рд╛рде рд╕рдорд╕реНрдпрд╛ рд╣реИ, рддреЛ рдмрд┐рд▓реНрд▓реА рдХрд╛ рд╕реНрд╡рд╛рдЧрдд рдХрд░реЗрдВред рд╡рд╣рд╛рдВ рдЖрдкрдХреЛ Vue рдкрд░ рд╕рдмрд╕реЗ рдХрдард┐рди рдФрд░ рд╡рд┐рдХреГрдд рдкреНрд░рд╢реНрди рдорд┐рд▓реЗрдВрдЧреЗ, рдЬреЛ рдХрд┐рд╕реА рднреА рдЙрдореНрдореАрджрд╡рд╛рд░ рдХреЛ рдЬрдЧрд╣ рджреЗрдВрдЧреЗ рдФрд░ рдЖрдкрдХреЛ рдЕрдкрдиреЗ рдкреЗрд╢реЗрд╡рд░ рдХреМрд╢рд▓ рдкрд░ рд╕рдВрджреЗрд╣ рдХрд░реЗрдВрдЧреЗред

1. рдЬреАрд╡рди рдЪрдХреНрд░ рд╣реБрдХ рдХреЗ рдЕрдВрджрд░ рд╡реЙрдЪрд░ рдЯреНрд░рд┐рдЧрд░
рдпрд╣ рд╕рд╡рд╛рд▓ рдЖрд╕рд╛рди рд▓рдЧ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВ рдЧрд╛рд░рдВрдЯреА рджреЗрддрд╛ рд╣реВрдВ рдХрд┐ рдХреЛрдИ рднреА, рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рд╕рдмрд╕реЗ рдЙрдиреНрдирдд рдбреЗрд╡рд▓рдкрд░ рднреА рдЗрд╕рдХрд╛ рдЬрд╡рд╛рдм рдирд╣реАрдВ рджреЗрдЧрд╛ред рдЖрдк рдЙрдирд╕реЗ рд╕рд╛рдХреНрд╖рд╛рддреНрдХрд╛рд░ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рдкреВрдЫ рд╕рдХрддреЗ рд╣реИрдВ, рддрд╛рдХрд┐ рдЙрдореНрдореАрджрд╡рд╛рд░ рдХреЛ рддреБрд░рдВрдд рдЖрдкрдХреА рд╢реНрд░реЗрд╖реНрдарддрд╛ рдХрд╛ рдПрд╣рд╕рд╛рд╕ рд╣реЛред
рдкреНрд░рд╢реНрди:рдПрдХ TestComponent рдШрдЯрдХ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдПрдХ рд░рд╛рд╢рд┐ рдЪрд░ рд╣реИред рдЬреАрд╡рди рдЪрдХреНрд░ рдХреЗ рдореБрдЦреНрдп рд╣реБрдХ рдХреЗ рдЕрдВрджрд░, рд╣рдо 1 рд╕реЗ 6 рддрдХ рд╕рдВрдЦреНрдпрд╛рддреНрдордХ рдХреНрд░рдо рдореЗрдВ рдорд╛рди рд╕реЗрдЯ рдХрд░рддреЗ рд╣реИрдВред рд╡реЙрдХрд░, рдЬреЛ рдХрдВрд╕реЛрд▓ рдореЗрдВ рдЗрд╕рдХреЗ рдореВрд▓реНрдп рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИ, рдЗрд╕ рдЪрд░ рдкрд░ рдЦрдбрд╝рд╛ рд╣реИред
рд╣рдо рдПрдХ TestComponent рдЙрджрд╛рд╣рд░рдг рдмрдирд╛рддреЗ рд╣реИрдВ рдФрд░ рдХреБрдЫ рд╕реЗрдХрдВрдб рдХреЗ рдмрд╛рдж рдЗрд╕реЗ рд╣рдЯрд╛ рджреЗрддреЗ рд╣реИрдВред рдпрд╣ рдХрд╣рд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рд╣рдо рдХрдВрд╕реЛрд▓ рдЖрдЙрдЯрдкреБрдЯ рдореЗрдВ рджреЗрдЦреЗрдВрдЧреЗред
рдХреЛрдб:
/* TestComponent.vue */ <template> <span> I'm Test component </span> </template> <script> export default { data() { return { amount: 0, }; }, watch: { amount(newVal) { console.log(newVal); }, }, beforeCreate() { this.amount = 1; }, created() { this.amount = 2; }, beforeMount() { this.amount = 3; }, mounted() { this.amount = 4; }, beforeDestroy() { this.amount = 5; }, destroyed() { this.amount = 6; }, }; </script>
рдореИрдВ рдПрдХ рд╕рдВрдХреЗрдд рджреВрдВрдЧрд╛: "2345" рдЧрд▓рдд рдЙрддреНрддрд░ рд╣реИред
рдЬрд╡рд╛рдм рд╣реИрдХрдВрд╕реЛрд▓ рдореЗрдВ, рд╣рдо рдХреЗрд╡рд▓ рдирдВрдмрд░ 4 рджреЗрдЦреЗрдВрдЧреЗред
рд╡реНрдпрд╛рдЦреНрдпрд╛рдЙрджрд╛рд╣рд░рдг рд╕реНрд╡рдпрдВ рдЕрднреА рддрдХ рдХреНрд░рд┐рдПрдЯ рд╣реБрдХ рдореЗрдВ рдирд╣реАрдВ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЪреМрдХреАрджрд╛рд░ рдпрд╣рд╛рдВ рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ред
рд╡реЙрдХрд░ рдЯреНрд░рд┐рдЧрд░ рд╕реЗ рдкрд╣рд▓реЗ, рдирд┐рд░реНрдорд┐рдд, рдФрд░ рдорд╛рдЙрдВрдЯ рдХрд┐рдП рдЧрдП рд╣реБрдХ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рдХрд░рддрд╛ рд╣реИред рдЪреВрдВрдХрд┐ рдЗрди рд╕рднреА рд╣реБрдХ рдХреЛ рдПрдХ рдЯрд┐рдХ рдХреЗ рджреМрд░рд╛рди рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП Vue 4 рдХреЗ рдореВрд▓реНрдп рдХреЗ рд╕рд╛рде, рдПрдХ рдмрд╛рд░ рдмрд╣реБрдд рд╣реА рдЕрдВрдд рдореЗрдВ рдЪреМрдХреАрджрд╛рд░ рдХреЛ рдмреБрд▓рд╛рдПрдЧрд╛ред
Vue рдкрд╣рд▓реЗ рд╕реЗ рддрдп рдХрд┐рдП рдЧрдП рд╡реЗрд░рд┐рдПрд╕реНрдЯ рдФрд░ рдирд╖реНрдЯ рдХрд┐рдП рдЧрдП рд╣реБрдХ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдЪрд░ рдХреЗ рдкрд░рд┐рд╡рд░реНрддрди рдХреА рдирд┐рдЧрд░рд╛рдиреА рд╕реЗ рд╕рджрд╕реНрдпрддрд╛ рд╕рдорд╛рдкреНрдд рдХрд░ рджреЗрдЧрд╛, рдЗрд╕рд▓рд┐рдП 5 рдФрд░ 6 рдХрдВрд╕реЛрд▓ рдХреЛ рдирд╣реАрдВ рдорд┐рд▓реЗрдЧрд╛ред
рдЙрддреНрддрд░ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд╕рд╛рде рд╕реИрдВрдбрдмреЙрдХреНрд╕2. рдирд┐рд╣рд┐рдд рд╡реНрдпрд╡рд╣рд╛рд░
рдпрд╣ рдкреНрд░рд╢реНрди Vue рдореЗрдВ рджреБрд░реНрд▓рдн рд╕рд╣рд╛рд░рд╛ рд╡реНрдпрд╡рд╣рд╛рд░ рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реИред рд╕рднреА рдкреНрд░реЛрдЧреНрд░рд╛рдорд░, рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рдкреНрд░реЛрдк рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдорд╛рдиреНрдпрддрд╛рдУрдВ рдХреЛ рдЙрдЬрд╛рдЧрд░ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕ рддрд░рд╣ рдХреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд╛ рд╕рд╛рдордирд╛ рдХрднреА рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдЙрдореНрдореАрджрд╡рд╛рд░ рдХреЛ рдпрд╣ рдХрд╣рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рдЗрд╕ рд╕рд╡рд╛рд▓ рдХреЛ рдкреВрдЫрдирд╛ рдмреЗрд╣рддрд░ рд╣реЛрдЧрд╛, рдПрдХ рдЧрд▓рдд рдЬрд╡рд╛рдм рдХреЗ рдмрд╛рдж рдЗрд╕рдХреА рдирд┐рдВрджрд╛ рдХрд░реЗрдВ рдФрд░ рдЕрдЧрд▓реЗ рдкрд░ рдЬрд╛рдПрдВред
рдкреНрд░рд╢реНрди:рдмреВрд▓рд┐рдпрди рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рд╛рде рд╕рд╣рд╛рд░рд╛ рдмрд╛рдХреА рд╕реЗ рдХреИрд╕реЗ рднрд┐рдиреНрди рд╣реЛрддрд╛ рд╣реИ?
/* SomeComponent.vue */ <template> </template> <script> export default { props: { testProperty: { type: Boolean, }, }, }; </script>
рдЬрд╡рд╛рдм рд╣реИрдмреВрд▓рд┐рдпрди рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рд╛рде рдкреНрд░реЛрдк рдЕрдиреНрдп рд╕рднреА рд╕реЗ рднрд┐рдиреНрди рд╣реЛрддрд╛ рд╣реИ рдХрд┐ Vue рдореЗрдВ рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рд╢реЗрд╖ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдХрд╛рд╕реНрдЯ рд╣реИред
рдпрджрд┐ рдХрдмрд╛рдм-рдорд╛рдорд▓реЗ рдореЗрдВ рдПрдХ рдЦрд╛рд▓реА рд╕реНрдЯреНрд░рд┐рдВрдЧ рдпрд╛ рд╕реНрд╡рдпрдВ рдХрд╛ рдирд╛рдо рдПрдХ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ Vue рдЗрд╕реЗ рд╕рддреНрдп рдореЗрдВ рдмрджрд▓ рджреЗрдЧрд╛ред
рдПрдХ рдЙрджрд╛рд╣рд░рдг:
рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдмреВрд▓рд┐рдпрди рдкреНрд░реЛрдк рдХреЗ рд╕рд╛рде рдПрдХ рдлрд╛рдЗрд▓ рд╣реИ:
/* TestComponent.vue */ <template> <div v-if="canShow"> I'm TestComponent </div> </template> <script> export default { props: { canShow: { type: Boolean, required: true, }, }, }; </script>
TestComponent рдШрдЯрдХ рдХреЗ рд╕рднреА рд╡реИрдз рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЗ рдиреАрдЪреЗ рджрд┐рдЦрд╛рдП рдЧрдП рд╣реИрдВред
/* TestWrapper.vue */ <template> <div> <TestComponent canShow="" /> <TestComponent canShow /> <TestComponent canShow="can-show" /> </div> </template> <script> import TestComponent from 'path/to/TestComponent'; export default { components: { TestComponent, }, }; </script>
рдЙрддреНрддрд░ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд╕рд╛рде рд╕реИрдВрдбрдмреЙрдХреНрд╕3. $ рд░реЗрдл рдореЗрдВ рдПрдХ рд╕рд░рдгреА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛
рдпрджрд┐ рдЖрдкрдХреЗ рдЙрдореНрдореАрджрд╡рд╛рд░ рдХреЛ рдкрддрд╛ рд╣реИ рдХрд┐ рдЗрд╡рд╛рди рдпреВ рд╕реНрддрд░ рдкрд░ рдлреНрд░реЗрдорд╡рд░реНрдХ рдмрд╛рд╣рд░ рд╕реЗ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рддреЛ рдЖрдкрдХреЗ рдкрд╛рд╕ рдЕрднреА рднреА рдЕрдкрдиреА рдЖрд╕реНрддреАрди рдкрд░ рдХреБрдЫ рдЯреНрд░рдореНрдк рдХрд╛рд░реНрдб рд╣реИрдВ: рдЖрдк рдлреНрд░реЗрдо рдХреЗ рдЕрдирд┐рд░реНрджрд┐рд╖реНрдЯ рдФрд░ рдЕрд╕реНрдкрд╖реНрдЯ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ рдкреНрд░рд╢реНрди рдкреВрдЫ рд╕рдХрддреЗ рд╣реИрдВред
рдкреНрд░рд╢реНрди:Vuex рдореЗрдВ рдлрд╝рд╛рдЗрд▓ рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рдХреА рдПрдХ рд╕рд░рдгреА рд╣реЛрддреА рд╣реИ, рд╕рд░рдгреА рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ рдЕрджреНрд╡рд┐рддреАрдп рдирд╛рдо рдФрд░ рдЖрдИрдбреА рдЧреБрдг рд╣реЛрддреЗ рд╣реИрдВред рдЗрд╕ рд╕рд░рдгреА рдХреЛ рд╣рд░ рдХреБрдЫ рд╕реЗрдХрдВрдб рдореЗрдВ рдЕрдкрдбреЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддрддреНрд╡реЛрдВ рдХреЛ рд╣рдЯрд╛ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЗрд╕рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛рддрд╛ рд╣реИред
рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рдШрдЯрдХ рд╣реИ рдЬреЛ рдПрдХ рдмрдЯрди рдХреЗ рд╕рд╛рде рдкреНрд░рддреНрдпреЗрдХ рд╕рд░рдгреА рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╛ рдирд╛рдо рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕ рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░рдХреЗ рд╡рд░реНрддрдорд╛рди рдлрд╝рд╛рдЗрд▓ рд╕реЗ рдЬреБрдбрд╝реЗ рдбреЛрдо рддрддреНрд╡ рдХреЛ рдХрдВрд╕реЛрд▓ рдореЗрдВ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП:
/* FileList.vue */ <template> <div> <div v-for="(file, idx) in files" :key="file.id" ref="files" > {{ file.name }} <button @click="logDOMElement(idx)"> Log DOM element </button> </div> </div> </template> <script> import { mapState } from 'vuex'; export default { computed: { ...mapState('files'), }, methods: { logDOMElement(idx) { console.log(this.$refs.files[idx]); }, }, }; </script>
рдпрд╣ рдХрд╣рд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рд╕рдВрднрд╛рд╡рд┐рдд рддреНрд░реБрдЯрд┐ рдХрд╣рд╛рдВ рд╣реИ рдФрд░ рдЗрд╕реЗ рдХреИрд╕реЗ рдареАрдХ рдХрд┐рдпрд╛ рдЬрд╛рдПред
рдЬрд╡рд╛рдм рд╣реИрд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ $ ref рдХреЗ рдЕрдВрджрд░ рдХреА рд╕рд░рдгреА рдореВрд▓ рд╕рд░рдгреА (
рдЬрд╛рд░реА рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд▓рд┐рдВрдХ ) рдХреЗ рд╕рдорд╛рди рдХреНрд░рдо рдореЗрдВ рдирд╣реАрдВ рдЬрд╛ рд╕рдХрддреА рд╣реИред рдпрд╣реА рд╣реИ, рдРрд╕реА рд╕реНрдерд┐рддрд┐ рд╣реЛ рд╕рдХрддреА рд╣реИ: рд╣рдо рд╕реВрдЪреА рдХреЗ рддреАрд╕рд░реЗ рддрддреНрд╡ рдХреЗ рдмрдЯрди рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рджреВрд╕рд░реЗ рдХрд╛ рдбреЛрдо рддрддреНрд╡ рдХрдВрд╕реЛрд▓ рдкрд░ рдкреНрд░рджрд░реНрд╢рд┐рдд рд╣реЛрддрд╛ рд╣реИред
рдпрд╣ рдХреЗрд╡рд▓ рддрдм рд╣реЛрддрд╛ рд╣реИ рдЬрдм рд╕рд░рдгреА рдореЗрдВ рдбреЗрдЯрд╛ рдмрд╛рд░-рдмрд╛рд░ рдмрджрд▓рддрд╛ рд╣реИред
рд╕рдорд╛рдзрд╛рди рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЛ GitHub рдкрд░ рдЬрд╛рд░реА рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:
1. рдкреНрд░рддреНрдпреЗрдХ рдЖрдЗрдЯрдо рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрджреНрд╡рд┐рддреАрдп рд░реЗрдлрд░реА рдмрдирд╛рдПрдВ
<template> <div> <div v-for="(file, idx) in files" :key="file.id" :ref="`file_${idx}`" > {{ file.name }} <button @click="logDOMElement(idx)"> Log DOM element </button> </div> </div> </template> <script> import { mapState } from 'vuex'; export default { computed: { ...mapState('files'), }, methods: { logDOMElement(idx) { console.log(this.$refs[`file_{idx}`]); }, }, }; </script>
2. рдЕрддрд┐рд░рд┐рдХреНрдд рд╡рд┐рд╢реЗрд╖рддрд╛
<template> <div> <div v-for="(file, idx) in files" :key="file.id" :data-file-idx="idx" > {{ file.name }} <button @click="logDOMElement(idx)"> Log DOM element </button> </div> </div> </template> <script> import { mapState } from 'vuex'; export default { computed: { ...mapState('files'), }, methods: { logDOMElement(idx) { const fileEl = this.$el.querySelector(`*[data-file-idx=${idx}]`); console.log(fileEl); }, }, }; </script>
4. рдЕрдЬреАрдм рдШрдЯрдХ рдордиреЛрд░рдВрдЬрди
рдкреНрд░рд╢реНрди:рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рд╡рд┐рд╢реЗрд╖ рдШрдЯрдХ рд╣реИ рдЬреЛ рд╣рд░ рдмрд╛рд░ рдШреБрдбрд╝рд╕рд╡рд╛рд░ рд╣реБрдХ рдХреЛ рдХрдВрд╕реЛрд▓ рдХреЛ рд▓рд┐рдЦрддрд╛ рд╣реИ:
/* TestMount.vue */ <template> <div> I'm TestMount </div> </template> <script> export default { mounted() { console.log('TestMount mounted'); }, }; </script>
рдЗрд╕ рдШрдЯрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ TestComponent рдШрдЯрдХ рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕рдореЗрдВ рдПрдХ рдмрдЯрди рд╣реИ, рдЬрд┐рд╕реЗ рджрдмрд╛рдХрд░ 1 рд╕реЗрдХреЗрдВрдб рдХреЗ рд▓рд┐рдП рд╕рдВрджреЗрд╢ рд╢реАрд░реНрд╖ рд╕рдВрджреЗрд╢ рджрд┐рдЦрд╛рдИ рджреЗрдЧрд╛ред
/* TestComponent.vue */ <template> <div> <div v-if="canShowTopMessage"> Top message </div> <div> <TestMount /> </div> <button @click="showTopMessage()" v-if="!canShowTopMessage" > Show top message </button> </div> </template> <script> import TestMount from './TestMount'; export default { components: { TestMount, }, data() { return { canShowTopMessage: false, }; }, methods: { showTopMessage() { this.canShowTopMessage = true; setTimeout(() => { this.canShowTopMessage = false; }, 1000); }, }, }; </script>
рдмрдЯрди рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░реЗрдВ рдФрд░ рджреЗрдЦреЗрдВ рдХрд┐ рдХрдВрд╕реЛрд▓ рдореЗрдВ рдХреНрдпрд╛ рд╣реЛрддрд╛ рд╣реИ:

рдкрд╣рд▓реЗ рдорд╛рдЙрдВрдЯ рдХреА рдЙрдореНрдореАрдж рдереА, рд▓реЗрдХрд┐рди рдЕрдиреНрдп рджреЛ рдХрд╣рд╛рдВ рд╣реИрдВ? рдЗрд╕реЗ рдХреИрд╕реЗ рдареАрдХ рдХрд░реЗрдВ?
рд╕реИрдВрдбрдмреЙрдХреНрд╕ рддреНрд░реБрдЯрд┐ рдХреЛ рд╕рдордЭрдиреЗ рдФрд░ рдЗрд╕реЗ рдареАрдХ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд╕рд╛рдердЬрд╡рд╛рдм рд╣реИрдпрд╣рд╛рдБ рд╕рдорд╕реНрдпрд╛ Vue рдореЗрдВ рд╡рд░реНрдЪреБрдЕрд▓ DOM рдХреЗ рдЕрдВрддрд░ рдХреЛ рдЦреЛрдЬрдиреЗ рдХреА рдЦрд╝рд╛рд╕рд┐рдпрдд рд╕реЗ рдЙрддреНрдкрдиреНрди рд╣реЛрддреА рд╣реИред
рдмрд╣реБрдд рд╢реБрд░реБрдЖрдд рдореЗрдВ, рд╣рдорд╛рд░рд╛ рд╡рд░реНрдЪреБрдЕрд▓ рдбреЛрдо рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:
рдмрдЯрди рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдпрд╣ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:
Vue рдирдП рд╡рд░реНрдЪреБрдЕрд▓ рдХреЗ рд╕рд╛рде рдкреБрд░рд╛рдиреЗ рд╡рд░реНрдЪреБрдЕрд▓ рдбреЛрдо рдХрд╛ рдорд┐рд▓рд╛рди рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рд╣реИ рддрд╛рдХрд┐ рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдпрд╛ рдЬрд╛ рд╕рдХреЗ рдХрд┐ рдХреНрдпрд╛ рд╣рдЯрд╛рдпрд╛ рдФрд░ рдЬреЛрдбрд╝рд╛ рдЬрд╛рдирд╛ рд╣реИ:
рд╣рдЯрд╛рдП рдЧрдП рдЖрдЗрдЯрдо рд▓рд╛рд▓ рд░рдВрдЧ рдореЗрдВ рдкрд╛рд░ рдХрд┐рдП рдЧрдП рд╣реИрдВ, рдирд┐рд░реНрдорд┐рдд рдЖрдЗрдЯрдо рд╣рд░реЗ рд░рдВрдЧ рдореЗрдВ рд╣рд╛рдЗрд▓рд╛рдЗрдЯ рдХрд┐рдП рдЧрдП рд╣реИрдВVue рдХреЛ TestMount рдШрдЯрдХ рдирд╣реАрдВ рдорд┐рд▓рд╛, рдЗрд╕рд▓рд┐рдП рдЗрд╕реЗ рдкреБрдирдГ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ред
рдмрдЯрди рджрдмрд╛рддреЗ рд╣реА рдПрдХ рд╕рдорд╛рди рд╕реНрдерд┐рддрд┐ рджреВрд╕рд░реА рдмрд╛рд░ рджреЛрд╣рд░рд╛рдИ рдЬрд╛рдПрдЧреАред рдЗрд╕ рдмрд┐рдВрджреБ рдкрд░, TestMounted рдШрдЯрдХ рддреАрд╕рд░реА рдмрд╛рд░ рдХрдВрд╕реЛрд▓ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреА рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИред
рд╕рдорд╕реНрдпрд╛ рдХреЛ рдареАрдХ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдмрд╕ TestMounted рдШрдЯрдХ рдХреЗ рд╕рд╛рде div рдкрд░ рдореБрдЦреНрдп рд╡рд┐рд╢реЗрд╖рддрд╛ рдбрд╛рд▓реЗрдВ:
/* TestComponent.vue */ <template> <div> <div key="container"> <TestMount /> </div> </div> </template> /* ... */
рдЕрдм Vue рд╡рд░реНрдЪреБрдЕрд▓ рдбреЛрдо рдХреЗ рдЖрд╡рд╢реНрдпрдХ рддрддреНрд╡реЛрдВ рдХреЛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдореИрдк рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдЧрд╛ред
5. рдПрдХ рддрд╛рд▓рд┐рдХрд╛ рдШрдЯрдХ рдмрдирд╛рдирд╛
рдЙрджреНрджреЗрд╢реНрдп:рдПрдХ рдШрдЯрдХ рдмрдирд╛рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ рдЬреЛ рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде рдПрдХ рд╕рд░рдгреА рд▓реЗрддрд╛ рд╣реИ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдПрдХ рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИред рд╕реНрддрдВрдн рдФрд░ рд╕реЗрд▓ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХрд╛ рдЕрд╡рд╕рд░ рджреЗрдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред
рдХреЙрд▓рдо рдФрд░ рд╕реЗрд▓ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдПрдХ рд╡рд┐рд╢реЗрд╖ рдШрдЯрдХ (
рддрддреНрд╡-рдпреВрдЖрдИ рдХреЗ рд╕рдорд╛рди) рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкреНрд░реЗрд╖рд┐рдд рдХреА рдЬрд╛рдиреА рдЪрд╛рд╣рд┐рдП:
/* SomeComponent.vue */ <template> <CustomTable :items="items"> <CustomColumn label="Name"> <template slot-scope="item"> {{ item.name }} </template> </CustomColumn> <CustomColumn label="Element Id"> <template slot-scope="item"> {{ item.id }} </template> </CustomColumn> </CustomTable> </template>
рд╢реБрд░реБрдЖрдд рдореЗрдВ, рдХрд╛рд░реНрдп рдореЗрдВ рддрддреНрд╡-рдЙрдИ рдХреЗ рд╕рдорд╛рди рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рдереАред рд▓реЗрдХрд┐рди рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рдХрд┐ рдХреБрдЫ рд▓реЛрдЧ рдореВрд▓ рд╢рдмреНрджреЛрдВ рдореЗрдВ рдХрд╛рд░реНрдп рдкреВрд░рд╛ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реИрдВред рдЗрд╕рд▓рд┐рдП, рд╕реНрддрдВрднреЛрдВ рдФрд░ рд╕реЗрд▓ рдХреЗ рдШрдЯрдХреЛрдВ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рд╕рд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреЛ рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рдерд╛ред
рдореБрдЭреЗ рдпрдХреАрди рд╣реИ рдХрд┐ рдЖрдкрдХреЗ рд╕рд╛рдХреНрд╖рд╛рддреНрдХрд╛рд░рдХрд░реНрддрд╛ рд╣рд░ рд╕рдордп рдПрдХ рд╕реНрддреВрдк рдореЗрдВ рд░рд╣реЗрдВрдЧреЗред рдРрд╕реА рд╕рдорд╕реНрдпрд╛ рдХреЗ рд╕рдорд╛рдзрд╛рди рдХреЗ рд▓рд┐рдП рдЖрдк рдЙрдиреНрд╣реЗрдВ 30 рдорд┐рдирдЯ рдХрд╛ рд╕рдордп рджреЗ рд╕рдХрддреЗ рд╣реИрдВред
рдирд┐рд░реНрдгрдпрдореБрдЦреНрдп рд╡рд┐рдЪрд╛рд░ рд╕рднреА рдбреЗрдЯрд╛ рдХреЛ CustomTable рдШрдЯрдХ рдореЗрдВ CustomTable рдШрдЯрдХ рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдирд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ рдпрд╣ рд╕рдм рдХреБрдЫ рдЦреБрдж рдХреЛ рдкреНрд░рд╕реНрддреБрдд рдХрд░реЗрдЧрд╛ред
рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИред рдпрд╣ рдХреБрдЫ рдмрд┐рдВрджреБрдУрдВ (рдЬреИрд╕реЗ рд▓реЗрдмрд▓ рдХреЛ рдмрджрд▓рдирд╛) рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рдирд╣реАрдВ рд░рдЦрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореВрд▓ рд╕рд┐рджреНрдзрд╛рдВрдд рд╕реНрдкрд╖реНрдЯ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред
export default { render() { return null; }, props: { label: { type: String, required: true, }, }, mounted() {
export default { render() { const { columnsData, items } = this; const { default: defaultSlot } = this.$slots; return ( <div> // CustomColumn {defaultSlot} <table> // <tr> {columnsData.map(columnData => ( <td key={columnData.label}> {columnData.label} </td> ))} </tr> // {items.map(item => ( <tr> {columnsData.map(columnData => ( <td key={columnData.label}> {columnData.createCell(item)} </td> ))} </tr> ))} </table> </div> ); }, props: { items: { type: Array, required: true, }, }, data() { return { columnsData: [], }; }, methods: { setColumnData(columnData) { this.columnsData.push(columnData); }, }, };
6. рдПрдХ рдкреЛрд░реНрдЯрд▓ рдмрдирд╛рдирд╛
рдпрджрд┐ рдЖрдкрдХреЗ рдЙрдореНрдореАрджрд╡рд╛рд░ рдиреЗ рдкрд┐рдЫрд▓реЗ рдХрд╛рд░реНрдп рдХреЛ рдкреВрд░рд╛ рдирд╣реАрдВ рдХрд┐рдпрд╛ рд╣реИ, рддреЛ рдЪрд┐рдВрддрд╛ рдХреА рдХреЛрдИ рдмрд╛рдд рдирд╣реАрдВ рд╣реИ: рдЖрдк рдЙрд╕реЗ рдПрдХ рдФрд░ рджреЗ рд╕рдХрддреЗ рд╣реИрдВ, рдХреЛрдИ рдХрдо рдореБрд╢реНрдХрд┐рд▓ рдирд╣реАрдВ!
рдЙрджреНрджреЗрд╢реНрдп:рдПрдХ рдкреЛрд░реНрдЯрд▓ рдФрд░ рдкреЛрд░реНрдЯрд▓рдЯрд╛рд░реНрдЧ рдШрдЯрдХ рдмрдирд╛рдПрдВ, рдЬреИрд╕реЗ
рдкреЛрд░реНрдЯрд▓- рдкреБ рд▓рд╛рдЗрдмреНрд░реЗрд░реАред
/* FirstComponent.vue */ <template> <div> <Portal to="title"> Super header </Portal> </div> </template>
/* SecondComponent.vue */ <template> <div> <PortalTarget name="title" /> </div> </template>
рдирд┐рд░реНрдгрдпрдПрдХ рдкреЛрд░реНрдЯрд▓ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рддреАрди рдСрдмреНрдЬреЗрдХреНрдЯ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рд╣реЛрдВрдЧреЗ:
- рдкреЛрд░реНрдЯрд▓ рдбреЗрдЯрд╛ рд╡реЗрдпрд░рд╣рд╛рдЙрд╕
- рдкреЛрд░реНрдЯрд▓ рдШрдЯрдХ рдЬреЛ рд╕реНрдЯреЛрд░ рдореЗрдВ рдбреЗрдЯрд╛ рдЬреЛрдбрд╝рддрд╛ рд╣реИ
- PortalTarget рдШрдЯрдХ рдЬреЛ рд╕реНрдЯреЛрд░ рд╕реЗ рдбреЗрдЯрд╛ рдкреБрдирд░реНрдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИ
import Vue from 'vue'; const bus = new Vue({ data() { return { portalDatas: [], }; }, methods: { setPortalData(portalData) { const { portalDatas } = this; const portalDataIdx = portalDatas.findIndex( pd => pd.id === portalData.id, ); if (portalDataIdx === -1) { portalDatas.push(portalData); return; } portalDatas.splice(portalDataIdx, 1, portalData); }, removePortalData(portalDataId) { const { portalDatas } = this; const portalDataIdx = portalDatas.findIndex( pd => pd.id === portalDataId, ); if (portalDataIdx === -1) { return; } portalDatas.splice(portalDataIdx, 1); }, getPortalData(portalName) { const { portalDatas } = this; const portalData = portalDatas.find(pd => pd.to === portalName); return portalData || null; }, }, }); export default bus;
import dataBus from './dataBus'; let currentId = 0; export default { props: { to: { type: String, required: true, }, }, computed: {
import dataBus from './dataBus'; export default { props: { name: { type: String, required: true, }, }, render() { const { portalData } = this; if (!portalData) { return null; } return ( <div class="portal-target"> {portalData.portalEl} </div> ); }, computed: { portalData() { return dataBus.getPortalData(this.name); }, }, };
рдпрд╣ рд╕рдорд╛рдзрд╛рди рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЛ рдмрджрд▓рдиреЗ рдХрд╛ рд╕рдорд░реНрдерди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рд╕рдВрдХреНрд░рдордг рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдПрдирд┐рдореЗрд╢рди рдХрд╛ рд╕рдорд░реНрдерди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдкреЛрд░реНрдЯрд▓-рд╡реНрдпреВ рдЬреИрд╕реЗ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдорд╛рдиреЛрдВ рдХрд╛ рд╕рдорд░реНрдерди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рд╕рд╛рдорд╛рдиреНрдп рд╡рд┐рдЪрд╛рд░ рд╕реНрдкрд╖реНрдЯ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред
7. рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рд╢реАрд▓рддрд╛ рдХреА рд░реЛрдХрдерд╛рдо
рдкреНрд░рд╢реНрди:рдЖрдкрдиреЗ рдПрдкреА рд╕реЗ рдПрдХ рдмрдбрд╝реА рд╡рд╕реНрддреБ рдкреНрд░рд╛рдкреНрдд рдХреА рдФрд░ рдЗрд╕реЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдпрд╛ред рдХреБрдЫ рдЗрд╕ рддрд░рд╣:
/* ItemView.vue */ <template> <div v-if="item"> <div> {{ item.name }} </div> <div> {{ item.price }} </div> <div> {{ item.quality }} </div> </div> </template> <script> import getItemFromApi from 'path/to/getItemFromApi'; export default { data() { return { item: null, }; }, async mounted() { this.item = await getItemFromApi(); }, }; </script>
рдЗрд╕ рдХреЛрдб рдореЗрдВ рдПрдХ рд╕рдорд╕реНрдпрд╛ рд╣реИред рд╣рдо рдЖрдЗрдЯрдо рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╛ рдирд╛рдо, рдореВрд▓реНрдп, рдЧреБрдгрд╡рддреНрддрд╛ рдФрд░ рдЕрдиреНрдп рдЧреБрдг рдирд╣реАрдВ рдмрджрд▓рддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рд╡реАрдпреВ рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдирд╣реАрдВ рдЬрд╛рдирддрд╛ рд╣реИ рдФрд░ рдкреНрд░рддреНрдпреЗрдХ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рд╢реАрд▓рддрд╛ рдЬреЛрдбрд╝рддрд╛ рд╣реИред
рдЗрд╕рд╕реЗ рдХреИрд╕реЗ рдмрдЪрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ?
рдЬрд╡рд╛рдм рд╣реИрдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рд╢реАрд▓ рдЧреБрдгреЛрдВ рдХреЛ рдмрджрд▓рдиреЗ рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рдЕрдВрджрд░ рдЬреЛрдбрд╝рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рдлреНрд░реАрдЬ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред
Vue рдЬрд╛рдБрдЪ рдХрд░реЗрдЧрд╛ рдХрд┐ рдХреНрдпрд╛ рдСрдмреНрдЬреЗрдХреНрдЯ Object.isFrozen рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЬрдореЗ рд╣реБрдП рд╣реИред рдФрд░ рдпрджрд┐ рдРрд╕рд╛ рд╣реИ, рддреЛ Vue рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рд╢реАрд▓ рдЧреЗрдЯрд░реНрд╕ рдХреЛ рдирд╣реАрдВ рдЬреЛрдбрд╝реЗрдЧрд╛ рдФрд░ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рдЧреБрдгреЛрдВ рдореЗрдВ рдмрд╕ рдЬрд╛рдПрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рдЙрдиреНрд╣реЗрдВ рдХрд┐рд╕реА рднреА рдорд╛рдорд▓реЗ рдореЗрдВ рдирд╣реАрдВ рдмрджрд▓рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдмрд╣реБрдд рдмрдбрд╝реА рд╡рд╕реНрддреБрдУрдВ рдХреЗ рд╕рд╛рде, рдпрд╣ рдЕрдиреБрдХреВрд▓рди рдХрдИ рджрд╕рд┐рдпреЛрдВ рдорд┐рд▓реАрд╕реЗрдХрдВрдб рддрдХ рдмрдЪрд╛рдиреЗ рдореЗрдВ рдорджрдж рдХрд░рддрд╛ рд╣реИред
рдЕрдиреБрдХреВрд▓рд┐рдд рдШрдЯрдХ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦреЗрдЧрд╛:
/* ItemView.vue */ <template> </template> <script> import getItemFromApi from 'path/to/getItemFromApi'; export default { async mounted() { const item = await getItemFromApi(); Object.freeze(item); this.item = item; }, }; </script>
рдСрдмреНрдЬреЗрдХреНрдЯ.рдлреНрд░реАрдЬ рдХреЗрд╡рд▓ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рдЧреБрдгреЛрдВ рдХреЛ рдЬрдорд╛ рджреЗрддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, рдпрджрд┐ рдХрд┐рд╕реА рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ рдиреЗрд╕реНрдЯреЗрдб рдСрдмреНрдЬреЗрдХреНрдЯ рд╣реИрдВ, рддреЛ рдЙрдиреНрд╣реЗрдВ рднреА рдЬрдореЗ рд╣реБрдП рд╣реЛрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
19 рдЬрдирд╡рд░реА, 2019 рддрдХ рдЕрдкрдбреЗрдЯ рдХрд░реЗрдВ :
рджрд┐рдорд┐рддреНрд░реА рдЬрд╝реНрд▓реЗрдЧрд┐рди рдХреА рд╕рд▓рд╛рд╣ рдкрд░
, рдореИрдВрдиреЗ рд╡реАрдпреВ-рдиреЙрдирд░реЗрдХреНрдЯрд┐рд╡ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЛ рджреЗрдЦрд╛ рдФрд░ рдПрдХ рдФрд░ рддрд░реАрдХрд╛ рдкрд╛рдпрд╛ред рдпрд╣ рдЙрди рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХрджрдо рд╕рд╣реА рд╣реИ, рдЬрд╣рд╛рдВ рдЖрдкрдХреЗ рдкрд╛рд╕ рдмрд╣реБрдд рд╕реЗ рдиреЗрд╕реНрдЯреЗрдб рдСрдмреНрдЬреЗрдХреНрдЯ рд╣реИрдВред
Vue рдХрд┐рд╕реА рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рд╢реАрд▓рддрд╛ рдирд╣реАрдВ рдЬреЛрдбрд╝реЗрдЧрд╛ рдпрджрд┐ рд╡рд╣ рджреЗрдЦрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рд╢реАрд▓ рд╣реИред рд╣рдо рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рд▓рд┐рдП рдПрдХ рдЦрд╛рд▓реА рдСрдмреНрдЬрд░реНрд╡рд░ рдмрдирд╛рдХрд░ Vue рдХреЛ рдЯреНрд░рд┐рдХ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
/* ItemView.vue */ <template> </template> <script> import Vue from 'vue'; import getItemFromApi from 'path/to/getItemFromApi'; const Observer = new Vue() .$data .__ob__ .constructor; export default { async mounted() { const item = await getItemFromApi(); </script>
8. рдзреАрдореА рдЙрдкрдХрд░рдгреЛрдВ рдХреА рддреНрд░реБрдЯрд┐рдпрд╛рдВ
рдкреНрд░рд╢реНрди:рдПрдХ рдШрдЯрдХ рдХреЗ рд╕рд╛рде рдПрдХ рдШрдЯрдХ рд╣реИ рдЬреЛ рдХрдВрд╕реЛрд▓ рдореЗрдВ рдЖрдЗрдЯрдо рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рдЧреБрдгреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ рдЖрдЗрдЯрдо рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рдирд┐рдХрд╛рд▓рддрд╛ рд╣реИ:
/* SomeComponent.vue */ <template> <div v-if="item"> <button @click="logAndClean()"> Log and clean </button> </div> </template> <script> export default { data() { return { item: { value: 124, }, }; }, methods: { logAndClean() { console.log(this.item.value); this.item = null; }, }, }; </script>
рдпрд╣рд╛рдБ рдХреНрдпрд╛ рдЧрд▓рдд рд╣реЛ рд╕рдХрддрд╛ рд╣реИ?
рдЬрд╡рд╛рдм рд╣реИрд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ Vue рдмрдЯрди рдкрд░ рдкрд╣рд▓реА рдмрд╛рд░ рдХреНрд▓рд┐рдХ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рд▓рд┐рдП DOM рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдиреЗ рдФрд░ рдмрдЯрди рдХреЛ рд╣рдЯрд╛рдиреЗ рдореЗрдВ рдХреБрдЫ рд╕рдордп рд▓рдЧрддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХрднреА-рдХрднреА рдбрдмрд▓-рдХреНрд▓рд┐рдХ рдХрд░ рд╕рдХрддрд╛ рд╣реИред LogAndClean рд╡рд┐рдзрд┐ рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рдкрд╣рд▓реА рдмрд╛рд░ рдХрд╛рдо рдХрд░рддреА рд╣реИ, рдФрд░ рджреВрд╕рд░реА рдмрд╛рд░ рджреБрд░реНрдШрдЯрдирд╛рдЧреНрд░рд╕реНрдд рд╣реЛ рдЬрд╛рддреА рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдореВрд▓реНрдп рд╕рдВрдкрддреНрддрд┐ рдкреНрд░рд╛рдкреНрдд рдирд╣реАрдВ рдХрд░ рд╕рдХрддреА рд╣реИред
рдореИрдВ рд▓рдЧрд╛рддрд╛рд░ рддреНрд░реБрдЯрд┐ рдЯреНрд░реИрдХрд░ рдореЗрдВ рдРрд╕реА рд╕рдорд╕реНрдпрд╛ рджреЗрдЦрддрд╛ рд╣реВрдВ, рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдЕрдХреНрд╕рд░ 4-5k рд░реВрдмрд▓ рдХреЗ рд▓рд┐рдП рд╕рд╕реНрддреЗ рдореЛрдмрд╛рдЗрд▓ рдлреЛрди рдкрд░ред
рдЗрд╕рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП, рдлрд╝рдВрдХреНрд╢рди рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рдХреЗрд╡рд▓ рдЖрдЗрдЯрдо рдХреЗ рдЕрд╕реНрддрд┐рддреНрд╡ рдХреЗ рд▓рд┐рдП рдПрдХ рдЪреЗрдХ рдЬреЛрдбрд╝реЗрдВ:
<template> </template> <script> export default { methods: { logAndClean() { const { item } = this; if (!item) { return; } console.log(item.value); this.item = null; }, }, }; </script>
рдмрдЧ рдХреЛ рдкреБрди: рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдк рд╕реИрдВрдбрдмреЙрдХреНрд╕ рдореЗрдВ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд╕рд╛рде рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ, рд╕реАрдкреАрдпреВ рдХреА рдЕрдзрд┐рдХрддрдо рдереНрд░реЙрдЯрд▓рд┐рдВрдЧ рд╕реЗрдЯ рдХрд░реЗрдВ рдФрд░ рдЬрд▓реНрджреА рд╕реЗ рдмрдЯрди рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░реЗрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ рдРрд╕рд╛ рдХрд┐рдпрд╛ред
рдЙрддреНрддрд░ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реИрдВрдбрдмреЙрдХреНрд╕ рд▓рд┐рдВрдХрд▓реЗрдЦ рдХреЛ рдЕрдВрдд рддрдХ рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж! рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЕрдм рдЖрдк рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рд╕рд╛рдХреНрд╖рд╛рддреНрдХрд╛рд░ рдореЗрдВ рд╣реЛрд╢рд┐рдпрд╛рд░ рд▓рдЧ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЖрдкрдХреЗ рдЙрдореНрдореАрджрд╡рд╛рд░реЛрдВ рдХрд╛ рд╡реЗрддрди рдХрд╛рдлреА рдХрдо рд╣реЛ рдЬрд╛рдПрдЧрд╛!