This is the 4th day of my participation in the August More Text Challenge

Thanks to the Nuggets for letting me dig deep into something and write it down!

What is reactive

Responsiveness is a programming paradigm that allows us to adapt to change in a declarative way. When a value is evaluated by attaching to another value, if the previous value changes, the attached value changes at the same time. For a typical example, see Excel functions. When cell A3=SUM(A1:A2), when A1 or A2 changes at this time, A3 will immediately respond to update.

Responsiveness is the core API of Vue3. There is also a separate package for this responsive API that can be used independently even without Vue3: @vue/ reActivity

Responsive API-Computed and Watch

There are three modules in the reactive core library: REF and Reactive reactive variables, computed attribute variables and Watch status monitoring function

computedCalculate attribute

Methods a

Takes a getter function and returns an immutable reactive ref object for the value returned from the getter.

const count = ref(1)
const plusOne = computed(() = > count.value + 1)

console.log(plusOne.value) / / 2

plusOne.value++ / / error
Copy the code

Way 2

It can also use objects with get and set functions to create writable ref objects.

const count = ref(1)
const plusOne = computed({
  get: () = > count.value + 1.set: val= > {
    count.value = val - 1
  }
})

plusOne.value = 1
console.log(count.value) / / 0
Copy the code

watchState monitoring

Watch needs to listen to specific data sources and perform side effects in a separate callback function. By default, it is also lazy — that is, the callback is invoked only when the listening source changes.

Listen on a single source

The listener data source can be a getter function with a return value, or a ref:

// Listen for a getter
const state = reactive({ count: 0 })
watch(
  () = > state.count,
  (count, prevCount) = > {
    / *... * /})// Listen directly on a ref
const count = ref(0)
watch(count, (count, prevCount) = > {
  / *... * /
})
Copy the code

Listening for multiple sources

Listeners can also listen on multiple sources simultaneously using arrays:

watch([fooRef, barRef], ([foo, bar], [prevFoo, prevBar]) = > {
  / *... * /
})
Copy the code

Deep listen object source

When trying to check for property changes in deeply nested objects or arrays, the deep option still needs to be set to true.

const state = reactive({ 
  id: 1.attributes: { 
    name: ' '
  }
})

watch(
  () = > state,
  (state, prevState) = > {
    console.log(
      'deep',
      state.attributes.name,
      prevState.attributes.name
    )
  },
  { deep: true }
)

state.attributes.name = 'Alex' // Log: "deep" "Alex" "Alex"
Copy the code

Alternatively, you can use a deep-copy function for deep listening

import _ from 'lodash'

const state = reactive({
  id: 1.attributes: {
    name: ' ',
  }
})

watch(
  () = > _.cloneDeep(state),
  (state, prevState) = > {
    console.log(
      state.attributes.name,
      prevState.attributes.name
    )
  }
)

state.attributes.name = 'Alex' // log: "Alex" ""
Copy the code

watchEffect

To automatically apply and reapply side effects based on reactive state, we can use the watchEffect method. It executes a function passed in immediately, tracing its dependencies responsively, and rerunking the function when its dependencies change.

const count = ref(0)

watchEffect(() = > console.log(count.value))
// -> logs 0

setTimeout(() = > {
  count.value++
  // -> logs 1
}, 100)
Copy the code

This method is not difficult to use, but in practical application, if the code is not handled properly, the readability of the code may be confusing if the code is left for a long time.

watchEffect->stop()Stop listening

Explicitly calling the return value to stop listening:

const stop = watchEffect(() = > {
  / *... * /
})

stop()
Copy the code

Feeling and wish to think

So far Vue3’s responsive framework has taken functional play to the extreme.

The API is not hard to use, but can you actually disassemble and visually read the code and execute the logic when you actually write a project? If you write what you think is a great piece of logic, can someone else just pick it up and change it?

The functional version of the reactive framework has caused me some distress:

The first worry is that every time you declare something, you add value to it. It’s very uncomfortable! Really uncomfortable! Very uncomfortable! 😣

The second agony is done each time in callback(). Maddening! 😫

JS would be much better off if there were a syntactic sugar solution for declaring reactive variables, avoiding const every time, and porting it to the ECMAScript specification.

Here are my ref and computed grammar sugar ideas:

ref count = 1;
computed plusOne = () = > count + 1

console.log(plusOne) / / 2
plusOne++ / / error
Copy the code

Handles the case where getters and setters coexist to compute properties.

ref count = 1;
computed plusOne = {
  get: () = > count + 1.set: val= > {
    count = val - 1
  }
}

plusOne = 1
console.log(count) / / 0
Copy the code

The above snippets are just ideas!

The literature

  • Vue3 responsive base API