Composition API și Pinia

Configurare noua (How To)

Situatie

Mulți dintre noi ne-am obișnuit cu modul în care este scris codul în Vue sau în alte frameworkuri care îl extind precum Nuxt.js. Modul în care ne declarăm proprietățile și metodele în componentele Vue impune câteva limitări și condiții de declarare.

Solutie

Composition API + < script setup >

Recunoașteți în exemplul de mai jos o aplicație Vue. Se observă declararea proprietăților în metoda data() precum și a funcției increase în methods.

<script>
export default {
  data() {
    return {
      count: 0
    }
  },
  methods: {
    increase() {
      this.count++;
    }
  }
}
</script>

<template>
  <p>
    <button @click=”increase”>click
    </button>
  </p>

  <p>{{ count }}</p>
</template>

Composition API + < script setup > ne propune o alternativă mai naturală dar impune câteva limitări legate de modul în care declarăm și folosim valorile proprietăților. Mai jos, este exemplul de mai sus rescris folosind noua paradigmă:

<script setup>
import { ref } from „vue”;

const count = ref(0);

function increase() {
  count.value++;
}
</script>

<template>
  <p>
    <button @click=”increase”>click
    </button>
  </p>
  <p>{{ count }}</p>
</template>

Codul html din secțiunea template rămâne neschimbat, în schimb partea de script diferă destul de mult. Constanta count și metoda increase() sunt definite fără a mai folosi suportul oferit de data() și methods:. A se remarca modul în care atribuim o valoare folosind ref(0) dar și incrementarea acesteia prin proprietatea .value.

Pentru a păstra proprietățile react ale datelor noastre, le vom declara în felul următor:

const data = reactive({
  check: "abracadabra",
  info: [],//array of consecutive numbers
});

iar proprietățile computed astfel:

const totalSum = computed(() => {
  let total = 0;
  data.info.map((value) => (total += value));
  return total;
});

Codul complet pentru demo se poate vedea mai jos. A se remarca modul simplu de afișare a datelor:

<script setup>
import { computed, reactive, ref } from „vue”;

const data = reactive({
  check: „abracadabra”,
  info: [],
});
const count = ref(0);

function increase() {
  count.value++;
  data.info.push(count.value);
}

const totalSum = computed(() => {
  let total = 0;
  data.info.map((value) => (total += value));
  return total;
});
</script>

<template>
  <h1>Hello World!{{ data.check }}</h1>
  <p>count is: {{ count }}</p>
  <p><button @click=”increase”>click</button></p>
  <span v-for=”info in data.info:key=”info”>{{ info }} &nbsp;</span>
  <p>Total sum:{{ totalSum }}</p>
</template>

În interiorul tagului < template > nu mai este nevoie să folosim proprietatea .value, reconstrucția valorilor se realizează automat de către frameworkul Vue.

Concluzie

Composition API este acum parte din Vue3, reprezentând un mod mai elegant pentru definirea funcționalității componentelor. Trebuie doar să rețineți folosirea metodelor ref() pentru valori simple și reactive() pentru cele compuse.

Pinia, alternativa la Vuex

Reprezintă noul store care vine ca o alternativă la Vuex. Este asemănător cu acesta și păstrează aceeași filozofie de declarare a stărilor, getters și a acțiunilor, dar simplifică modul de declarare și de folosire a acestora.

Integrăm Pinia în proiectul nostru. Realizăm acest lucru prin modificarea src/main.js a aplicației demo. Va trebui să adăugăm frameworkul înainte de mountul aplicației.

Codul inițial:

import { createApp } from 'vue'  
import App from './App.vue'

createApp(App).mount('#app')

Va fi transformat astfel:

import { createApp } from 'vue'  
import App from './App.vue'  
import {createPinia} from "pinia";

const app = createApp(App);  
const pinia = createPinia()  
app.use(pinia).mount('#app')

Definim o variantă simplă de store care va conține counterul din exemplul precedent.

import { defineStore } from 'pinia'

export const counter=defineStore('count',{
    state:()=>{
        return {
            count_index: 0
        }
    }
})

iar integrarea sa se va realiza în acest fel:

import {counter} from "./store/counter";  
const storeCount = counter();

Spre deosebire de Vuex, în Pinia putem modifica direct starea (state) a store-ului nostru.

function increase() {  
  storeCount.count_index++;
....

Putem chiar să îl resetăm, dacă este nevoie:

if (storeCount.count_index===3){  
  storeCount.$reset();  
}

Afișarea valorilor din store se realizează direct:

<p>count is: {{ storeCount.count_index }}</p>

Putem să definim proprietăți computed care să folosească store-ul:

const triple=computed(()=>(storeCount.count_index*3))

Monitorizăm schimbările din store cu ajutorul metodei wotch:

watch(storeCount,(state)=>{  
  console.log("we got a change:",state, state.count_index)  
})

Getters

Vom folosi ca exemplu o proprietate care ne returnează valoarea negativă a counterului și o afișăm în ui.

//counter.js

getters:{  
  negative:(state)=>(-1*state.count_index),  
},

...

//app.vue
<p>Negative:{{storeCount.negative}}</p>

Dacă este nevoie, putem să transmitem și parametrii unei metode getter în felul următor:

//counter.js

getters:{  
...  
  multiply:(state)=>(factor)=>(state.count_index*factor)  
},

...
//app.vue

<p>Multiply:{{storeCount.multiply(4)}}</p>

Acțiuni

Acțiunile din store-ul Pinia sunt declarate ca funcții normale. Starea store-ului poate fi accesată prin intermediul this și remarcăm faptul că nu este necesară referința la state. Folosirea acestora în componentele Vue se rezumă la apelarea metodei corespunzătoare prin intermediul instanței store-ului.

//counter.js
actions:{
    increment(){
        this.count_index++;
    },
    add(value){
        this.count_index+=value;
    }
}
...
//app.vue
storeCount.increment();
storeCount.add(1);

Tip solutie

Permanent

Voteaza

(4 din 7 persoane apreciaza acest articol)

Despre Autor

Leave A Comment?