vue.jsvuejs3ref

Vue3 ref not getting refreshed?


I need some help to understand the way refs work. I'm pretty sure I'm making some obvious, basic mistake, but I just don't get it. Can someone please explain?

In the script setup I get some props passed from the outer component:

const props = defineProps({
    myEvent: Object,
    gridColumnLabels: Object,
    gridColumnOrder: Array,
    isAdmin: Boolean,
    isLoggedIn: Boolean,
    userEmail: String
})

Then I have a ref declared:

const isMR = ref(props.myEvent.mREmail ? props.myEvent.mREmail?.includes(userEmail) : false)

myEvent.mREmail may exist or not. I expect that if myEvent.mREmail exists, and it includes userEmail the isMR is true.

Now in my template I display:

<div>
    userEmail: {{ userEmail }}
</div>
<div>
    props.myEvent.mREmail: {{ props.myEvent.mREmail}}
</div>
<div>
    props.myEvent?.mREmail?.includes(userEmail): {{ props.myEvent?.mREmail?.includes(userEmail) }}
</div>
<div>
    isMR: {{ isMR }}
</div>

Here's the result I get rendered:

userEmail: qw@as.zx
props.myEvent.mREmail: qw@as.zx
props.myEvent?.mREmail?.includes(userEmail): true
isMR: false

enter image description here

Why, oh why?....


Solution

  • Using the playground with the following

    <script setup>
    import { ref } from 'vue'
    import Child from './Child.vue'
    
    const localEmail = ref('cool@gmail.com')
    </script>
    
    <template>
        <p>parent component</p>
        <input v-model="localEmail" />
        <br />
    
        <Child :email="localEmail" />
    </template>
    

    Child.vue

    <script setup>
    import { computed } from 'vue'
    
    const props = defineProps({
        email: String
    })
    
    const isMatching = computed(() => props.email == 'cool@gmail.com')
    </script>
    
    <template>
        ---
        <p>child component</p>
        <p>props from parent: {{ props.email }}</p>
        <p>does it match? {{ isMatching }}</p>
    </template>
    

    We have the correct boolean if matching the proper email enter image description here

    And a false otherwise enter image description here

    A prop is already reactive and does not need to be wrapped into a ref once more.

    Vue uses a proxy underneath, it breaks the whole principle if you wrap it twice. Give a read to that one for more explanations on the Reactivity system: https://vuejs.org/api/options-state.html#props

    If you want to re-evaluate a specific value, use computed for such purpose, it will track the dependencies and react to them accordingly.
    More info here: https://vuejs.org/guide/essentials/computed.html