Изменение внешних массивов и объектов в компонентах

Последнее обновление: 03.11.2020

В отличие от строк, чисел, логических значений true и false массивы и сложные объекты передаются в компоненты по ссылке. То есть получив ссылку, можно управлять значением, которое хранится по этой ссылке.

Изменение массивов

Рассмотрим, как мы можем изменять в дочернем компоненте массивы, переданные из родительского компонента. Определим следующую веб-страницу:

<!DOCTYPE html>
<html>
<head>
<title>Компоненты Vue 3</title>
<meta charset="utf-8" />
</head>
<body>
<div id="app">
    <h2>Список пользователей</h2>
    <userform :users="users"></userform>
    <div>
        <useritem v-for="(user, index) in users"
                    :user="user"
                    :index="index"
                    :key="index"
                    v-on:userdelete="remove">
        </useritem>
    </div>
</div>
<script src="https://unpkg.com/vue"></script>
<script>
const app = Vue.createApp({
    data(){
		return {
			users:[
				{name: 'Tom', age: 23},
				{name: 'Bob', age: 26},
				{name: 'Alice', age: 28}
			]
		}  
    },
	
    methods:{
        remove(index){
            this.users.splice(index, 1)
        }
    }
});

app.component('userform', {
    props: ["users"],
    data() {
        return {
            user: {name:'', age:18}
        }
    },
    template: `<div>
                    <input type="text" v-model="user.name" />
                    <input type="number" v-model="user.age" />
                    <button  v-on:click="userAdd">Add</button>
                </div>`,
    methods: {
        userAdd(event){
            this.users.push({name:this.user.name, age: this.user.age});
        }
    }
});

app.component('useritem', {
    props: ["user", "index"],
    template: `<div>
                    <p>Name: {{user.name}} <br> Age: {{user.age}}</p>
                    <button  v-on:click="userDelete(index)">Delete</button>
                </div>`,
    methods: {
        userDelete(index){
            this.$emit('userdelete', index);
        }
    }
});

app.mount('#app');
</script>
</body>
</html>

Для добавления нового элемента в массив определен компонент userform, который представляет форму добавления. Для вывода одного элемента из массива определен компонент useritem, который также содержит кнопку для удаления элемента.

По сути здесь используются две различные техники для работы с массивами. Компонент userform получает ссылку на массив и при нажатии на кнопку вызывает метод userAdd(), в котором через полученную ссылку в массив добавляется новый элемент.

Компонент useritem использует другую технику. Он получает элемент для вывода и по нажатию на кнопку удаления генерирует событие userdelete, передавая с ним индекс удаляемого элемента. Родительский объект получает это событие с индексом и по индексу собственно удаляет элемент из массива.

То есть мы можем либо напрямую передавать ссылку в дочерний компонент и в нем изменять значения в массиве, либо генерировать в дочернем компоненте событие, которое передается родительскому объекту.

Изменение массивов родительского компонента в дочернем в Vue 3

Изменение объектов

Для изменения внешних объектов в компоненте можно использовать аналогичные техники. В частности, изменим html-страницу следующим образом:

<!DOCTYPE html>
<html>
<head>
<title>Компоненты Vue 3</title>
<meta charset="utf-8" />
</head>
<body>
<div id="app">
    <h2>Список пользователей</h2>
    <userform :user="user"></userform>
    <div>
        <useritem v-for="(user, index) in users"
                    :key="index"
                    :user="user"
                    :index="index"
                    v-on:userchange="change">
        </useritem>
    </div>
</div>
<script src="https://unpkg.com/vue"></script>
<script>
const app = Vue.createApp({
    data(){
		return {
			users:[
				{name: 'Tom', age: 23},
				{name: 'Bob', age: 26},
				{name: 'Alice', age: 28}
			],
			user:{}
		}  
    },
	
    methods:{
        change(index){
            this.user = this.users[index];
        }
    }
});

app.component('userform', {
    props: ["user"],
    template: `<div>
                    <input type="text" v-model="user.name" />
                    <input type="number" v-model="user.age" />
                </div>`,
});

app.component('useritem', {
    props: ["user", "index"],
    template: `<div>
                    <p>Name: {{user.name}} <br> Age: {{user.age}}</p>
                    <button  v-on:click="userChange(index)">Change</button>
                </div>`,
    methods: {
        userChange(index){
            this.$emit('userchange', index);
        }
    }
});

app.mount('#app');
</script>
</body>
</html>

Здесь компонент userform через props получает объект user, свойства которого связываются двухсторонней привязкой с полями ввода. При изменении введеных значений в этих полях изменится и значение в массиве:

Изменение объектов родительского компонента в дочернем в Vue 3
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850