生命周期钩子
setup可以用来代替data,methods,computed,watch等等选项,也可以代替生命周期钩子。 可以使用onX导入函数实现生命周期
实现挂载生命周期
import { onMounted, onUpdated, onUnmounted } from 'vue'
export default {
setup() {
onMounted(() => {
console.log("lifecircle mounted");
})
}
}
beforecreated和created vue3中没有,直接在setup中写。
provide和inject
爷组件中
import { provide } from 'vue'
setup() {
const name = 'juju';
let counter = 100;
provide("name", name);
provide("counter", counter);
}
注入
import { inject } from 'vue'
const name = inject("name"); //第二个参数是默认值
let counter = inject("counter");
同时,如果传入的值是一个ref对象,那么应尽量传入一个readonly对象,避免子孙组件去修改传入的值
const name = ref('juju');
let counter = ref(100);
provide("name", readonly(name)); //在使用provide时多使用readonly,使得子孙组件不能修改数据
provide("counter", readonly(counter));
vue3中封装写法
建立一个hooks文件夹,放入完成的功能 useCounter.js
import { ref, computed } from 'vue'
export default function() {
const number = ref(0);
const doubleNumber = computed(() => number.value * 2);
const plus = () => {
number.value++
}
const sub = () => {
number.value--
}
return {
number,
doubleNumber,
plus,
sub
}
}
组件中引入
import useCounter from './hooks/useCounter.js'
setup() {
const increment = () => counter.value++;
const { number, doubleNumber, plus, sub } = useCounter();
return {
increment,
number,
doubleNumber,
plus,
sub
}
}
setup顶层写法
由于script标签里只有setup代码,因此以后可以在标签里直接加入setup
<script setup>
import { ref } from 'vue';
const counter = ref(0);
const increament = () => counter.value++;
</script>
对于组件导入,无需写components option
<template>
<div>
<h2>当前计数: {{ counter }}</h2>
<button @click="increament">+1</button>
<hello-world></hello-world>
</div>
</template>
<script setup>
import HelloWorld from './HelloWorld'
import { ref } from 'vue';
const counter = ref(0);
const increament = () => counter.value++;
</script>
对于props,需要导入新函数
<template>
<div>
{{ message }}
</div>
</template>
<script setup>
import { defineProps } from 'vue';
const props = defineProps({
message: {
type: String,
default: '哈哈啊哈'
}
})
</script>
对于事件也需要导入一个函数
<template>
<div>
<button @click="emitEvent">发射事件</button>
</div>
</template>
<script setup>
import { defineEmits } from 'vue';
const emit = defineEmits(["increment", "decrement"]);
const emitEvent = () => {
emit('increment', '10000')
}
</script>
<style scoped>
</style>
render函数
通过h函数可以给render函数返回一个vnode从而创建vnode对象。 h函数接受三个参数,
- 1.一个html标签,一个组件,一个异步组件或函数式组件。 如'div'
- 2.属性值。如div的class,id等
- 3.子元素。
<script>
import { h } from 'vue'
export default {
render() {
return h('h2', {class: 'title'}, "helloworldxixi")
}
}
</script>
<style scoped>
</style>
此时就能在页面上创建出一个h2标签。
render函数计数器案例
<script>
import { h, ref } from 'vue'
export default {
setup() {
const counter = ref(0);
return {
counter
}
},
render() {
return h('div', {class: 'app'}, [
h('h2', null, `当前计数: ${this.counter}`),
h('button', {
onClick: () => this.counter++
}, "+1"),
h('button', {
onClick: () => this.counter--
}, "-1"),
])
}
}
</script>
<style scoped>
</style>
由于render绑定了this,因此可以用this.counter获取值
jsx的使用
jsx可以使用一个工具将jsx转成render函数。