'How do I update a watched property in a Vue "script setup" script?

I am new to the version of Vue that introduced the "script setup" tag. I would like to trigger a watcher to update the season property and then calculate a new value based on that input. You can see it happening here:

  watch(season, () => {
    getStandings(season)
  }, { immediate: true })

I am trying to trigger the watcher from within a function that is triggered by a child component emitting an event with data. You can see it here:

// in the template
<SeasonSelect :season="season" @changedOption="onChangeSelection"/>

// and then in the script
    function onChangeSelection(selection: number) {
        console.log(selection, 8);
        this.season = selection; // i tried this, this is what I expected to work
    }

What I want is for the selection parameter to make it into the watcher. If it goes there, the watcher should take care of the computation as I intend.

Please tell me directly how to handle this. There isn't a lot of findable info about how to handle the special case where "script setup" is used.

Here is the full code for this component, which is the main component called index.vue:

<script setup lang="ts">
  import { useDPC } from '@/composables/useDPC';
  import { CONFIGS } from '@/configs';

  import SeasonSelect from '../components/SeasonSelect.vue';



    function onChangeSelection(selection: number) {
        console.log(selection, 8);
        this.season = selection;
    }

  const season = $ref<number>(CONFIGS.SEASONS.THE_INTERNATIONAL_11)
  const { standings, getStandings, isLoading } = useDPC()

  watch(season, () => {
    getStandings(season)
  }, { immediate: true })
</script>

<template>
  <div>

    <SeasonSelect :season="season" @changedOption="onChangeSelection"/>
    <h1>DPC Standings for {{ season }} season</h1>

    <h2 v-if="isLoading">
      Loading...
    </h2>
    <ul v-else>
        <div v-for="team in standings" :key="team.team_id">
            <Team :team="team"/>
        </div>

    </ul>
  </div>
</template>

edit: please note that the official documentation page about "script setup" doesn't mention how to implement a watcher or update a watcher, and everything is different in a "script setup" file

edit2: Per request of Boussadjra Brahim here is the code for SeasonSelect

<script>
    import { CONFIGS } from '../configs';

console.log(CONFIGS, 4);
    export default {
        data() {
            return {
                seasons: Object.assign({},CONFIGS.SEASONS)
            }
        },
        props: {
            season: Number
        },
        methods: {
            onChange(event) {
                console.log(event.target.value, 16)
                this.$emit("changedOption", event.target.value);
            }
        }
    }
</script>

<template>
    <select v-model="season" name="season" @change="onChange($event)">
      <option v-for="(value, key) in seasons" :key="key" :value="value">
        {{ key }}
      </option>
    </select>
</template>

Third edit: Like yo even this detailed breakdown doesnt mention anything about using watched properties in the "script setup" version of a SFC



Solution 1:[1]

When you are using <script setup>, it does not mean that you don't need to import necessary stuffs to your codes. You did not import watch in your parent component that uses <script setup>. Also this.season is not correct in <script setup>. Here is a basic example on how to manage your <select> operation in a <script setup> way:

parent component:

<template>
  <div>
    <SeasonSelect :season="season" @changedOption="onChangeSelection"/>
    <h1>DPC Standings for {{ season }} season</h1>

<!--    <h2 v-if="isLoading">-->
<!--      Loading...-->
<!--    </h2>-->
<!--    <ul v-else>-->
<!--      <div v-for="team in standings" :key="team.team_id">-->
<!--        <Team :team="team"/>-->
<!--      </div>-->

<!--    </ul>-->
  </div>
</template>


<script setup>
// import { useDPC } from '@/composables/useDPC';
// import { CONFIGS } from '@/configs';

// -------------------------------------------
/* importing things that are necessary from vue */
// -------------------------------------------
import {watch, ref} from "vue";

import SeasonSelect from '../components/SeasonSelect.vue';

const season = ref("value1");

function onChangeSelection(selection) {
  console.log(selection, 8);
  season.value = selection;
}


// const season = $ref<number>(CONFIGS.SEASONS.THE_INTERNATIONAL_11)
// const { standings, getStandings, isLoading } = useDPC()

watch(season, () => {
  console.log("season watch")
})
</script>

<style scoped>

</style>

child component:

<template>
  <select v-model="season" name="season" @change="onChange($event)">
    <option v-for="(value, key) in seasons" :key="key" :value="value">
      {{ key }}
    </option>
  </select>
</template>

<script>
// import { CONFIGS } from '../configs';

// console.log(CONFIGS, 4);
export default {
  name: "SeasonSelect",
  data() {
    return {
      /* I used a simple object to demonstrate the way you can implement this code. */
      seasons: {
        key1: "value1",
        key2: "value2",
        key3: "value3"
      }
    }
  },
  props: {
    season: String
  },
  methods: {
    onChange(event) {
      console.log(event.target.value, 16)
      this.$emit("changedOption", event.target.value);
    }
  }
}
</script>

<style scoped>

</style>

I also removed some features like using lang="ts", because they are not related to your question here.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 hamid-davodi