Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The better way to code。 #114

Open
LastHeaven opened this issue Jan 21, 2020 · 5 comments
Open

The better way to code。 #114

LastHeaven opened this issue Jan 21, 2020 · 5 comments

Comments

@LastHeaven
Copy link

Basic example

<template>
  <div>
    <div>
      <span>double:</span><span>{{double}}</span>
    </div>
    <button @click="inc">Clicked {{ count }} times.</button>

    <div>
      <div><input type="number" v-model="form.a"></div>
      <div><input type="number" v-model="form.b"></div>
      <div>
        <span>a + b:</span>
        <span>{{result1}}</span>
      </div>
      <div>
        <span>a + count:</span>
        <span>{{result2}}</span>
      </div>
      <div>
        <span>b + count:</span>
        <span>{{result3}}</span>
      </div>
      <div>
        <span>a + b + double:</span>
        <span>{{result4}}</span>
      </div>
    </div>
  </div>
</template>

<script>
import { ref, reactive, computed } from 'vue'

export default {
  setup () {
    const form = reactive({
      a: 1,
      b: 2
    })
    const count = ref(0)

    const inc = () => {
      count.value++
    }

    const double = computed(() => {
      return count.value * 2
    })

    const result1 = computed(() => {
      return form.a + form.b
    })

    const result2 = computed(() => {
      return form.a + count.value
    })

    const result3 = computed(() => {
      return form.b + count.value
    })

    const result4 = computed(() => {
      return form.a + form.b + double.value
    })

    return {
      form,
      count,
      double,
      result1,
      result2,
      result3,
      result4,
      inc
    }
  }
}
</script>

The usage of .value is easy to make Bug.
So I think the better way is like this.

<template>
  <div>
    <div>
      <span>double:</span><span>{{double}}</span>
    </div>
    <button @click="inc">Clicked {{ count }} times.</button>

    <div>
      <div><input type="number" v-model="form.a"></div>
      <div><input type="number" v-model="form.b"></div>
      <div>
        <span>a + b:</span>
        <span>{{result1}}</span>
      </div>
      <div>
        <span>a + count:</span>
        <span>{{result2}}</span>
      </div>
      <div>
        <span>b + count:</span>
        <span>{{result3}}</span>
      </div>
      <div>
        <span>a + b + double:</span>
        <span>{{result4}}</span>
      </div>
    </div>
  </div>
</template>

<script>
import { toRefs, reactive, computed } from 'vue'

export default {
  setup () {
    const state = reactive({
      form: {
        a: 1,
        b: 2
      },
      count: 0
    })

    const inc = () => {
      state.count++
    }

    state.double = computed(() => {
      return state.count * 2
    })

    state.result1 = computed(() => {
      return state.form.a + state.form.b
    })

    state.result2 = computed(() => {
      return state.form.a + state.count
    })

    state.result3 = computed(() => {
      return state.form.b + state.count
    })

    state.result4 = computed(() => {
      return state.form.a + state.form.b + state.double
    })

    return {
      ...toRefs(state),
      inc
    }
  }
}
</script>

No more .value,just like state instead of this in vue2.

@ycmjason
Copy link

I proposed exactly the same previously. But then after using the API for a while it became clear to me that ref is amazing.

@ycmjason
Copy link

There is nothing to stop you from coding in that style tho. Feel free to do whatever you prefer?

@vmihailenco
Copy link

vmihailenco commented Jan 21, 2020

One big thing that does not work with reactive is TypeScript support. Even simple things like this don't compile with TypeScript without declaring a separate interface

const state = reactive({
  a: 1,
  b: 2,
  c: computed(() => {
    return state.a * state.b
  })
})

And even though everyone seem to embrace better TypeScript support - all the examples don't use it or just use ref instead. Even official ones.

So if you need TypeScript you either get used to write value & ref everywhere or get used to write interfaces for TypeScript & reactive (or hope that some day TS will compile recursive types). ref seems like a better option in the end.

@vmihailenco
Copy link

To be precise - it compiles, but state has type any (so no point in using TypeScript) - 'state' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.

@posva
Copy link
Member

posva commented Jan 21, 2020

The .value is necessary and described at https://vue-composition-api-rfc.netlify.com/#ref-vs-reactive
This was largely discussed during the RFC process at #78 and the previous one at #42 (that's why it has a note on the RFC website)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants