Modular API
What is a composite API
The official address
As projects grow and functions become more complex, defined data and operations on its data are placed in different places, such as methods and Watch, and fragmentation makes it difficult to understand and maintain complex components. The separation of options masks a potential logical problem. In addition, when dealing with a single logical concern, we have to constantly “jump” to blocks of options for related code, hence the emergence of composite apis
use
The composite API is implemented in VUe3 through the setup function, which takes props and context
When the setup function is executed, the instance is not created, so there is no reference to this in the setup function
parameter
-
props
export default { props: { title: String }, setup(props) { console.log(props.title) // If you want to use structure assignment const { title } = toRefs(props) } } Copy the code
-
context
Context is a plain JavaScript object that exposes the component’s three properties
export default { setup(props, context) { // Attribute (non-responsive object) console.log(context.attrs) // slot (non-responsive object) console.log(context.slots) // Trigger event (method) console.log(context.emit) } } Copy the code
Responsive foundation
Change data to reactive data, now ref, reactive
-
The ref function changes the basic data type into responsive data, essentially a proxy object, a reference object
import { ref } from 'vue' const counter = ref(0) console.log(counter) // Proxy {value: 0} console.log(counter.value) / / 0 counter.value++ console.log(counter.value) / / 1 Copy the code
The ref function can also retrieve HTML objects from the template
<div ref='homeDiv'>home</div> setup() { const homeDiv = ref(null) // Get the DOM element after the mount onMounted(() = > { console.log(homeDiv.value) }) return { // Remember to export it homeDiv } } Copy the code
-
Reactive functions that turn objects into reactive data and return a reactive copy of the object
import { reactive } from 'vue' const person = reactive({ name: 'Joe'.age: 22.languages: ['English'.'Chinese']})return { // toRefs converts reactive objects to normal objects, where each property of the resulting object is a ref pointing to the corresponding property of the original object. toRefs(person) }Copy the code
-
ToRef function
Create a new REF for a property on the source responsive object. The REF can then be passed, maintaining a reactive connection to its source property
const state = reactive({ foo: 1.bar: 2 }) const fooRef = toRef(state, 'foo') fooRef.value++ console.log(state.foo) / / 2 state.foo++ console.log(fooRef.value) / / 3 Copy the code
-
Calculate attribute
Takes a getter function and returns an immutable reactive ref object from the value returned by the getter
const count = ref(1) const plusOne = computed(() = > count.value + 1) console.log(plusOne.value) / / 2 plusOne.value++ // error Copy the code
You can also accept objects from the get and set functions
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 return { count, plusOne } Copy the code
-
Monitor properties
You can listen directly on a ref object or a getter function with a return value
// Listen for a getter const state = reactive({ count: 0 }) watch( () = > state.count, (count, prevCount) = > { console.log(count) } ) // Listen directly on a ref const count = ref(0) watch(count, (count, prevCount) = > { console.log(count) }) Copy the code
Multiple objects can be monitored
watch([fooRef, barRef], ([foo, bar], [prevFoo, prevBar]) = > { / *... * / }) Copy the code
The life cycle
Since no component instance is created when the setup function is created, there are no beforeCreate and Created lifecycle hooks, and operations that occur in either lifecycle can be performed in the Setup function
onBeforeMount(() = > { console.log('onBeforeMount') }) onMounted(() = > { console.log('mounted! ') }) onBeforeUpdate(() = > { console.log('onBeforeUpdate! ') }) onUpdated(() = > { console.log('updated! ') }) onUnmounted(() = > { console.log('unmounted! ')})Copy the code
Dojo.provide and inject
Used when passing values between components
- The provide function allows you to define property, name, and value with two parameters
provide: { location: 'North Pole'.geolocation: { longitude: 90.latitude: 135}}Copy the code
- The Inject function allows you to take two arguments, the name of the property to inject and the default value
You can make it responsive, or you can decorate it with readonly if you want the passed value to remain unchanged
const location = ref('North Pole') const geolocation = reactive({ longitude: 90.latitude: 135 }) provide('location', readonly(location)) provide('geolocation', geolocation) Copy the code
The instance
A tosdolist component is made, which inputs a value and displays it in the list below. It can be separated from the logic to make the whole logic clearer
<ul> <li v-for="(item, index) in list" :key="index"> <div v-if="item.edit" style="margin-right: 10px">{{ item.val }}</div> <el-input style="width: 300px" v-else v-model="item.val" @blur="item.edit = ! item.edit" /> <div> <el-button @click="edit(index)" type="primary">The editor</el-button> <el-button @click="remove(index)" type="primary">delete</el-button> </div> </li> </ul> setup() { const {state, handleChange, edit, remove} = useState() return { ...toRefs(state), handleChange, edit, remove, } } Copy the code
import { reactive} from "vue"; import Home from "@/model/home"; type stateType = { state: Home, handleChange: () = > void.edit: (val: number) = > void.remove: (val: number) = > void } export function useState() :stateType { const state: Home = reactive({ input: "".list: [],});const handleChange = () = > { state.list.push({ edit: true.val: state.input, }); state.input = ""; }; const edit = (index: number) = > { state.list[index].edit = false; }; const remove = (index: number) = > { state.list.splice(index, 1); }; return { state, handleChange, edit, remove } } Copy the code