Open xgqfrms opened 1 year ago
https://vuejs.org/guide/essentials/reactivity-fundamentals.html
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
<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
-->
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
-->
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
-->
Reactivity API
ref() computed() reactive() readonly() watchEffect() watchPostEffect() watchSyncEffect() watch()
https://vuejs.org/api/reactivity-core.html