Vue3 writes a simple countdown component
Vue Composition API documentation: If you are not familiar with the SYNTAX of Vue 3, take a look at the syntax
At present, the document is still in English, here is a simple translation of a few core things:
setup
The setup function is a new component option that serves as a gateway to using the Composition API within the component.
1. Call timing
Setup is called immediately after the component instance is created and the initial props are resolved. For the life cycle level, it is called before the beforeCreate hook.
2. Work with template
If setup returns an object, the object’s properties are incorporated into the render context of the current component.
Refs returned from setup are automatically unwrapped when they get values from the template. Unref is also a new API, val = isRef(val)? Val. value: syntax sugar for val), so there is no need to add. Value to the template.
3. Use with render function
Setup can return not only an object, but also a render function directly. Note, however, that, unlike the template, which is unwrapped by itself, a.value is added to the refs value in render.
Parameters of 4.
Setup takes two parameters. The first is props, which is the most-used component. The second is the CTX context.
- Emit: Communicate with the parent component
- Slots: slots distribute content
- Attrs: can be used to encapsulate high-level components and cooperate with V-bind for attribute pass-through
5. This is not available in Setup
In VUe2, you can get the current instance through this in every lifecycle or method, but you can’t get this in the setup method. However, you can get the current instance with getCurrentInstance.
reactive
Passing in an object and returning a reactive proxy result to the target source is equivalent to version 2 of Vue.Observable ().
ref
It is similar to Reactive, but the basic value is passed in. Vaule to get the value, while the object wrapped in Reactive can get the value as an object. However, when the data structure is an array or a Map, even though the array is wrapped in Reactive, the.value value of an array item is still required to obtain the value.
//ref
const count = ref(0)
console.log(count.value);
//reactive
const state = reactive({
count
})
console.log(state.count);
//reactive with array
const arr = reactive([ref(0),3.5])
// need .value here
console.log(arr[0].value)
Copy the code
computed
Receives a callback function as a getter, or passes in an object with a getter and setter. One computed returns one object, and when you have more than one computed, you need to call it multiple times
const plusOne = computed((a)= > count.value + 1)
const plusTwo = computed({
get: (a)= > count.value + 1.set: val= > {
count.value = val - 1}})Copy the code
toRef, toRefs
ToRef can be used to create a REF for an attribute on the source response object.
export default {
// Since Javascript function arguments are passed by value, passing a parameter can be interpreted as copying the value of a variable if you pass a primitive type. After the base type is copied, the two variables are completely independent, and changes by either side do not affect the other. If you pass props. Numner (10), the inside of the function is independent of the outside. Operations inside the function cannot affect the outside variables unless you pass an object, such as the entire props, to keep referencing. But if you only need one attribute, there's no need to pass the whole thing in. This is where toRef comes in handy. What toRef returns is an object from which the.value can be retrieved.
setup(props) {
// {number:10}
useSomeFeature(toRef(props, 'number'))}}Copy the code
ToRefs can transform reactive objects into normal objects, where each property on the resulting object is a reference to the corresponding property in the original object. Can be used to prevent lost responses during deconstruction.
The life cycle
Most of the life cycle has been renamed and written slightly differently.
- You need to import yourself;
- Called in setup;
- beforeCreate -> use setup()
- created -> use setup()
- beforeMount -> onBeforeMount
- mounted -> onMounted
- beforeUpdate -> onBeforeUpdate
- updated -> onUpdated
- beforeDestroy -> onBeforeUnmount
- destroyed -> onUnmounted
- errorCaptured -> onErrorCaptured
Syntax is about these, the specific content or to see the official documentation. Let’s look at the specific code for the component
<script>
import { h, reactive, onMounted, onBeforeUnmount, toRef } from "vue";
import { formatTime } from "./utils";
export default {
props: {
time: {
type: Number.default: 0
},
millisecond: {
type: Boolean.default: false
},
autoStart: {
type: Boolean.default: true
}
},
setup(props, { emit }) {
const interval = props.millisecond ? 16 : 1000;
let leftTime = toRef(props, "time").value;
let autoStart = toRef(props, "autoStart").value;
let ticker = null;
let timeData = reactive(formatTime(leftTime));
const updateTime = (timeData, leftTime) = > {
const data = formatTime(leftTime);
Object.keys(timeData).forEach(k= > {
timeData[k] = data[k];
});
};
const start = (a)= > {
if(! ticker && leftTime >0) {
ticker = setInterval((a)= > {
leftTime -= interval;
if (leftTime <= 0) {
leftTime = 0;
clearInterval(ticker);
emit("finish");
} else {
emit("change", leftTime); } updateTime(timeData, leftTime); }, interval); }};const stop = (a)= > {
clearInterval(ticker);
ticker = null;
};
const restart = (a)= > {
clearInterval(ticker);
ticker = null;
leftTime = props.time;
emit("change", leftTime);
updateTime(timeData, leftTime);
start();
};
onMounted((a)= > {
autoStart && start();
});
onBeforeUnmount((a)= > {
stop();
});
return {
timeData,
start,
stop,
restart
};
},
render({ $slots, timeData, millisecond }) {
const time = ["hours"."minutes"."seconds"."millisecond"]
.filter(v= >v ! ="millisecond" || millisecond)
.map(v= > timeData[v])
.join(":");
const defaultContent = h(
"span",
{
style: { fontSize: "14px".color: "# 333" }
},
time
);
return h(
"div", ($slots.default && $slots.default(timeData)) || defaultContent ); }};</script>
Copy the code
The main change is in setup. There are no data and no methods. Basically, most of the code is written in setup, including events, life cycles, and so on, but it also depends on the scope of variables. You can also consider extracting the logic, but when passing parameters, you need to use toRef or toRefs, not base values.
High order component
Attrs is used to bind attributes, but I’m not sure.
<template>
<div>
<p>{{ word }}</p>
<countdown v-bind="attrs"></countdown>
</div>
</template>
<script>
import Countdown from "../components/countdown";
export default {
components: {
Countdown
},
props: {
word: {
type: String
}
},
setup(props, { attrs }) {
return {
attrs
};
}
};
</script>
Copy the code
DEMO
<template>
<div class="home">
<p>The basic use</p>
<countdown :time="66000"></countdown>
<p>Number of milliseconds</p>
<countdown :time="44444" millisecond></countdown>
<p>Gets component instances and methods</p>
<countdown :time="66000" ref="count" :auto-start="false"></countdown>
<button @click="count.start()">start</button>
<button @click="count.stop()">Shut down</button>
<button @click="count.restart()">restart</button>
<p>Use slot custom styles</p>
<countdown :time="66000" @change="change">
<template v-slot="timeData">
<span class="block">{{ timeData.hours }}</span>
<span class="colon">:</span>
<span class="block">{{ timeData.minutes }}</span>
<span class="colon">:</span>
<span class="block">{{ timeData.seconds }}</span>
</template>
</countdown>
<p>High order component</p>
<higher :time="8888" word="The test who" />
</div>
</template>
<script>
import Countdown from ".. /components/countdown";
import Higher from ".. /components/higher";
import { ref, onMounted } from "vue";
export default {
name: "Home".components: {
Countdown,
Higher
},
setup() {
const change = (a)= > {};
const count = ref(null);
onMounted((a)= > {
console.dir(count.value);
});
return{ change, count }; }};</script>
Copy the code
Display effect
The warehouse address
Github.com/linrunzheng…
The above are some learning results of VUE3 in these days. Please point out any mistakes.