Lifecycle hook
This is the 21st day of my participation in the August Text Challenge.More challenges in August
Setup can be used to replace options like Data, Methods, computed, watch, and so on, as well as life-cycle hooks
You can register lifecycle hooks using the directly imported onX function
Created and beforeCreate hook functions are missing from the Composition API
The setup function is called as soon as the component is created
So the logic that would be executed in the Created and beforeCreate functions can be written directly inside the setup function
<template>
<div>
<button @click="changeCount">{{ count }}</button>
</div>
</template>
<script>
import {
ref,
onMounted,
onUpdated,
onBeforeUnmount
} from 'vue'
export default {
name: 'Home'.setup() {
let count = ref(0)
console.log(The setup function will be called first.)
onMounted(() = > console.log('onMounted'))
onUpdated(() = > console.log('onUpdated'))
onBeforeUnmount(() = > console.log('onBeforeUnmount'))
const changeCount = () = > count.value++
return {
count,
changeCount
}
}
}
</script>
Copy the code
Dojo.provide and inject
We actually used Provide and Inject before, and the Composition API replaces the Provide and Inject options as well
We can define each Property with the provide method,
Inject desired properties and corresponding values in descendant components (inject desired properties and corresponding values)
Provide can be passed two arguments:
- Name: name of the supplied property
- Value: indicates the provided attribute value
Inject can be passed two parameters:
- The name of the property to inject
- The default value
Parent component - data provider
<template>
<div>
<h2>Name {{name}} in the Home component</h2>
<h2>Age {{age}} in the Home component</h2>
<button @click="changeAgeInHome">Modify the age in the Home component</button>
<Home />
</div>
</template>
<script>
import { ref, readonly, provide } from 'vue'
import Home from './components/Home.vue'
export default {
name: 'App'.components: {
Home
},
setup() {
const name = ref('Klaus')
const age = ref(23)
// Provide data
// Parameter 1 -- key
// Parameter 2 -- value
// provide data to descendant components that are best modified to readonly
// Descendant components cannot modify the data provided by the parent component
// If you want to modify, the descendant component can only emit an event for the parent (data provider) to modify
// The purpose of this is to ensure one-way data flow, i.e. data is passed from parent to child
// In this way, the data source will become unified during the later debugging, which is convenient for debugging and maintenance
provide('name', readonly(name))
provide('age', readonly(age))
const changeAgeInHome = () = > age.value++
return {
name,
age,
changeAgeInHome
}
}
}
</script>
Copy the code
Child component - data consumer
<template>
<div>
<h2>{{ name }}</h2>
<h2>{{ age }}</h2>
</div>
</template>
<script>
import { readonly, ref, inject } from 'vue'
export default {
name: 'Home'.setup() {
// Inject receives the value provided by provide
The inject function takes two arguments
// Parameter 1: the name of the received data
// Parameter 2: default value -- Optional
const name = inject('name')
// The default value is set to readonly to prevent child components from arbitrarily modifying the data passed by the parent component
const age = inject('age', readonly(ref(18))
return {
name,
age
}
}
}
</script>
Copy the code
Stage of practice
counter
use
<template>
<div>
<p>count: {{ count }}</p>
<p>doubleCount: {{ doubleCount }}</p>
<button @click="increment">increment</button>
<button @click="decrement">decrement</button>
</div>
</template>
<script>
// The name of the incoming hook function can be arbitrary, but it is recommended to refer to the react hook function and use the small hump beginning with use
import useCount from './hooks/useCount'
export default {
name: 'Home'.setup() {
const {
count,
doubleCount,
increment,
decrement
} = useCount() // The introduced hook is a function, so it is called first
return {
count,
doubleCount,
increment,
decrement
}
}
}
</script>
Copy the code
hook -- /src/hooks/useCount.js
import { ref, computed } from 'vue'
export default function() {
const count = ref(0)
const doubleCount = computed(() = > count.value * 2)
const increment = () = > count.value++
const decrement = () = > count.value--
return {
count,
doubleCount,
increment,
decrement
}
}
Copy the code
Another way to use it
<template>
<div>
<p>count: {{ count }}</p>
<p>doubleCount: {{ doubleCount }}</p>
<button @click="increment">increment</button>
<button @click="decrement">decrement</button>
</div>
</template>
<script>
// You can use the template to destruct the return value of the hook function directly
import useCount from './hooks/useCount'
export default {
name: 'Home'.setup() {
return {
// Not recommended -- deconstructed data needs to be used in templates
// If there are too many hook functions introduced, then it is not convenient to know.
// Which hook function does that data come from. useCount() } } }</script>
Copy the code
Listen for scroll position
use
<template>
<div class="screen">
<div class="hint">
<p>scrollX: {{ scrollX }}</p>
<p>scrollY: {{ scrollY }}</p>
</div>
</div>
</template>
<script>
import useScrollPostion from './hooks/useScrollPostion'
export default {
name: 'App'.setup() {
const { scrollX, scrollY } = useScrollPostion()
return {
scrollX,
scrollY
}
}
}
</script>
<style scoped>
.screen {
width: 300vw;
height: 300vh;
}
.hint {
position: fixed;
right: 30px;
bottom: 30px;
}
</style>
Copy the code
hook
import { ref } from 'vue'
export default function() {
const scrollX = ref(0)
const scrollY = ref(0)
window.addEventListener('scroll'.() = > {
scrollX.value = window.scrollX
scrollY.value = window.scrollY
})
return {
scrollX,
scrollY
}
}
Copy the code
Monitoring mouse scrolling
import { ref } from 'vue'
export default function() {
const mouseX = ref(0)
const mouseY = ref(0)
window.addEventListener('mousemove'.e= > {
// We can use pageX and pageY in event to get the position of mouse movement
mouseX.value = e.pageX
mouseY.value = e.pageY
})
return {
mouseX,
mouseY
}
}
Copy the code
localStorage
hook
import { ref, watch } from 'vue'
export default function(key, value) {
const data = ref(value)
if (value) {
localStorage.setItem(key, JSON.stringify(value))
} else {
data.value = JSON.parse(localStorage.getItem(key))
}
// Data is a ref object, so when listening, listen for data.value
// v is the value of newValue, which is the value property of data
// Tips: If ref is an object, the value of the ref object is a reactive object by default
watch(data.value, v= > localStorage.setItem(key, JSON.stringify(v)))
return data
}
Copy the code
use
<template>
<div>
<h2>{{ storage.name }}</h2>
<button @click="changeStorage">change</button>
</div>
</template>
<script>
import useLocalStorage from './hooks/useLocalStorage'
export default {
name: 'App'.setup() {
const storage = useLocalStorage('info', { name: 'Klaus' })
console.log(useLocalStorage('info').value? .name)const changeStorage = () = > {
storage.value.name = 'Alex'
}
return {
storage,
changeStorage
}
}
}
</script>
Copy the code
Setup top-level authoring
< Script Setup > is a compile-time syntactic sugar for using composite apis in single-file components (SFC)
Eventually, the vUE component is compiled as a setup function
The parent component
<template>
<div>
<Cpn :message="msg" @changeMsg="changeMsg" />
</div>
</template>
<script setup>
import { ref } from 'vue'
// There is no need to define the component's name attribute in Script Setup. Its value is named as the file name of the SFC
// The component can be used directly after it is introduced, without any registration operation
import Cpn from './components/Cpn.vue'
const msg = ref('Hello World')
const changeMsg = v= > msg.value = v
// All methods and data that need to be used in the template do not need to be returned
</script>
Copy the code
Child components
<template>
<div>
<h2>{{ message }}</h2>
<button @click="change">change</button>
</div>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue'
// Accept the props passed by the parent component via defineProps
defineProps({
message: {
type: String.required: true}})// Use the defineEmits method to define the events that need to be triggered
// This method returns a function that all registered methods can use to fire events
const emit = defineEmits(['changeMsg'])
const change = function() {
emit('changeMsg'.'Hello Vue')}</script>
Copy the code