xgqfrms / Vue-3.x

Vue 3.x
https://vue3.xgqfrms.xyz
MIT License
1 stars 0 forks source link

Reactivity API #6

Open xgqfrms opened 1 year ago

xgqfrms commented 1 year ago

Reactivity API

ref() computed() reactive() readonly() watchEffect() watchPostEffect() watchSyncEffect() watch()

https://vuejs.org/api/reactivity-core.html

xgqfrms commented 1 year ago

https://vuejs.org/guide/essentials/reactivity-fundamentals.html

Vue 3 响应式实现原理

function reactive(obj) {
  return new Proxy(obj, {
    get(target, key) {
      track(target, key)
      return target[key]
    },
    set(target, key, value) {
      target[key] = value
      trigger(target, key)
    }
  })
}

function ref(value) {
  const refObject = {
    get value() {
      track(refObject, 'value')
      return value
    },
    set value(newValue) {
      value = newValue
      trigger(refObject, 'value')
    }
  }
  return refObject
}

https://vuejs.org/guide/extras/reactivity-in-depth.html#how-reactivity-works-in-vue

xgqfrms commented 1 year ago

Vue 3 Composition API 使用 <script setup> 自动 expose 🚀

<script setup 🚀>
// import {createApp, ref, reactive} from "vue"
import { ref } from 'vue'

// data
const count = ref(0)
// methods
function increment() {
  // .value is needed in JavaScript
  count.value++
}
</script>

<template>
  <button @click="increment">
    {{ count }}
  </button>
</template>

<!--

Vue 3 Composition API 使用 <script setup> 自动 expose 🚀

https://vuejs.org/guide/essentials/reactivity-fundamentals.html#script-setup

https://vuejs.org/guide/scaling-up/sfc.html

-->
xgqfrms commented 1 year ago

Vue 3 Composition API 使用 setup() 需要手动 expose 💩

<script>
// import {createApp, ref, reactive} from "vue"
import { ref } from 'vue'

export default {
  // `setup` is a special hook dedicated for the Composition API.
  setup() {
    const count = ref(0)
    function increment() {
      // .value is needed in JavaScript
      count.value++
    }
    // expose the ref to the template
    // don't forget to expose the function as well.
    // 手动 expose 💩
    return {
      count,
      increment
    }
  }
}

</script>

<template>
  <button @click="increment">
    {{ count }}
  </button>
</template>

<!--

Vue 3 Composition API 使用 setup() 需要手动 expose 💩

https://vuejs.org/guide/essentials/reactivity-fundamentals.html#ref

https://codepen.io/xgqfrms/pen/KKbzLGM?editors=1111

-->
xgqfrms commented 1 year ago

https://www.cnblogs.com/xgqfrms/p/16797628.html

xgqfrms commented 1 year ago

ref vs reactive 🚀

https://vuejs.org/guide/essentials/reactivity-fundamentals.html#ref

https://vuejs.org/guide/essentials/reactivity-fundamentals.html#reactive


<!-- <script type="importmap">
  {
    "imports": {
      "vue": "https://unpkg.com/vue@3/dist/vue.esm-browser.js"
    }
  }
</script> -->

<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>

<div id="app">
  <h1>{{ message }}</h1>
  <hr>

  <select v-model="id" @change="handleChangeId" >
    <option v-for="item in items"
      :key="item.id"
      :value="item.id">
      {{ item.name }} ❓ {{ item.price }}
    </option>
  </select>

  <select v-model="obj" @change="handleChange" >
    <option v-for="item in items"
      :key="item.id"
      :value="item">
      {{ item.name }} ❓ {{ item.price }}
    </option>
  </select>
  <p>This is selected Product list name = <mark>{{ form.name }}</mark></p>
  <p>This is selected Product list price = <mark>{{ form.price }}</mark></p>
</div>

<script>
  // import { h, toRefs, toRef, ref, reactive, } from 'vue'
  // const { h, toRefs, toRef, createApp, ref, reactive, }  = Vue
  const { createApp, ref, reactive } = Vue

  createApp({
    // `setup` is a special hook dedicated for the Composition API.
    setup() {
      const message = ref('Hello Vue3!')
      const name = ref('?');
      const price = ref(0);
      const id = ref(1);
      const obj = ref({
        id: 1
      });
      // ref
      // const form = ref({
      //   name,
      //   price
      // })
      // ❌
      // There is another way to declare reactive state, with the reactive() API.
      // Unlike a ref which wraps the inner value in a special object, reactive() makes an object itself reactive:
      const form = reactive({
        name: '',
        price: 0,
      })
      const items = [
        { id: 1, name: 'apple' , price: 100 },
        { id: 2, name: 'banana' , price: 80 },
      ];
      function handleChangeId(e) {
        console.log(`e`, e)
        console.log(`form`, form)
        console.log(`id`, id)
        // ✅
        const item = items.find(item => id.value === item.id);
        form.name = item.name
        form.price = item.price;
      }
      function handleChange(e) {
        console.log(`e`, e)
        console.log(`form`, form)
        console.log(`obj`, obj)
        // ✅
        form.name = obj.value.name
        form.price = obj.value.price;
        // console.log(`form.value.name =`, form.value.name)
        // console.log(`form.value.price =`, form.value.price)
        // ✅
        // const item = items.find(item => obj.value.id === item.id);
        // form.name = item.name
        // form.price = item.price;
      }
      // function handleChange(e) {
      //   console.log(`e`, e)
      //   console.log(`form`, form)
      //   console.log(`obj`, obj)
      //   console.log(`id`, id)
      //   // ✅
      //   // const item = items.find(item => obj.value.id === item.id);
      //   const item = items.find(item => id.value === item.id);
      //   form.name = item.name
      //   form.price = item.price;
      //   // 😂
      //   // form.name = e.target.innerText;
      //   // form.price = e.target.innerText;
      //   // ❓
      //   // console.log(`form.name =`, form.name)
      //   // console.log(`form.price =`, form.price)
      // }
      // function handleChange(e) {
      //   // console.log(`e`, e)
      //   console.log(`form`, form)
      //   // ✅ value
      //   console.log(`form.value.name =`, form.value.name)
      //   console.log(`form.value.price =`, form.value.price)
      //   // ✅ _rawValue
      //   console.log(`form._rawValue.name =`, form._rawValue.name)
      //   console.log(`form._rawValue.price =`, form._rawValue.price)
      //   // ❌
      //   // console.log(`form.name =`, form.name)
      //   // console.log(`form.price =`, form.price)
      // }
      // expose the ref to the template
      return {
        message,
        obj,
        id,
        form,
        items,
        handleChange,
        handleChangeId,
      }
      // return () => h('div', [name.value, price.value, form.name, form.price])
    },
  }).mount('#app')
</script>

<!--

https://codepen.io/xgqfrms/pen/KKbzLGM?editors=1111

https://vuejs.org/guide/essentials/reactivity-fundamentals.html#ref

https://vuejs.org/guide/essentials/reactivity-fundamentals.html#reactive

https://stackoverflow.com/questions/77012612/how-to-get-other-json-value-using-composition-api-v-model-select-box

https://vuejs.org/guide/quick-start.html

https://github.com/xgqfrms/Vue-3.x/blob/master/v3-app/src/components/ChildTest.vue

https://github.com/xgqfrms/Vue-3.x/blob/master/composition-api/setup.vue

 -->
xgqfrms commented 1 year ago

https://zzk.cnblogs.com/my/s/blogpost-p?Keywords=Vue%203%20Composition%20API