1.setup
setup() 函数是 vue3 中,专门为组件提供的新属性。它为我们使用 vue3 的 Composition API 新特性提供了统一的入口,setup 函数会在 beforeCreate 之后,created 之前执行, vue3 也是取消了这两个钩子,统一用 setup 代替, 该函数相当于一个生命周期函数, setup 内部没有 this指向 , 但能通过getCurrentInstance()获取
setup(props, context) {
console.log(props, context);
}
//获取当前vue实例
const { proxy } = getCurrentInstance();
2.ref
ref() 函数用来根据给定的值创建一个响应式的数据对象,返回的是一个对象,这个对象上包含一个value属性,但template中不需要
<script setup>
const userList = ref([]);
console.log(userList.value)
</script>
3.reactive和toRefs
template中需要使用reactive里的内容时, 配合使用toRefs结构赋值起来
const data = reactive({
form: {},
queryParams: {
pageNum: 1,
pageSize: 10,
},
rules: {}
});
const { queryParams, form, rules } = toRefs(data);
因为toRefs() 函数可以将 reactive() 创建出来的响应式对象,转换为普通的对象,只不过,这个对象上的每个属性节点,都是 ref() 类型的响应式数据, 所以当访问queryParams时也需要加上value
console.info(queryParams.value)
4.computed
1.函数式写法
const obj = ref({
arr: ["foo", "bar"],
});
const getObjLength = computed(() => {
return obj.value.arr.length >= 3 ? "Yes" : "No";
});
我们在这里定义了一个计算属性 getObjLength 。computed() 方法期望接收一个 getter 函数,返回值为一个计算属性 ref。和其他一般的 ref 类似,你可以通过 getObjLength .value 访问计算结果。计算属性 ref 也会在模板中自动解包,因此在模板表达式中引用时无需添加 .value。
Vue 的计算属性会自动追踪响应式依赖。当obj.value.arr 改变时,任何依赖于 getObjLength 的绑定都会同时更新。
2.对象写法
const firstName = ref('John')
const lastName = ref('Doe')
const fullName = computed({
// getter
get() {
return firstName.value + ' ' + lastName.value
},
// setter
set(newValue) {
// 注意:我们这里使用的是解构赋值语法
[firstName.value, lastName.value] = newValue.split(' ')
}
})
5.watch
1.单个ref
const { proxy } = getCurrentInstance();
const deptName = ref("");
watch(deptName, (val) => {
proxy.$refs["deptTreeRef"].filter(val);
});
2.不能直接侦听响应式对象的属性值
onst obj = reactive({ count: 0 })
watch(obj.count, (count) => {
console.log(`Count is: ${count}`)
})
这里需要用一个返回该属性的 getter 函数:
watch(
() => obj.count,
(count) => {
console.log(`Count is: ${count}`)
}
)
为何要忽略值类型,是因为Vue需要依赖Proxy对象实现依赖收集
6.defineProps
除 Boolean 外的未传递的可选 prop 将会有一个默认值 undefined。
const props = defineProps({
// 是否加载显示
loading: {
type: Boolean,
default: false,
},
// 表格内数据
data: {
type: Array,
//返回一个工厂函数
default: () => []
}
}
7.defineEmits
const emit = defineEmits(["rowClick"]);
function handleRowClick(row) {
emit("rowClick", row);
}
8.slot
v-slot 可以简写为 # , 只能用于template上
1.匿名插槽
没有提供 name 的 会隐式地命名为default
2.具名插槽
<slot name="header"></slot>
<my-component>
<template #header>
<!-- header 插槽的内容放这里 -->
</template>
</my-component>
3.作用域插槽
<slot :name="status" :val="1"></slot>
<my-component>
<template #status="deliver">
{{ deliver.val }}
</template>
<my-component>
4.条件插槽
<div v-if="$slots.header" >
<slot name="header" />
</div>
vue2和vue3插槽的区别?
具名插槽时 vue2中使用name,vue3使用v-slot,简写为#,当是匿名插槽时用default
作用插槽时 vue2使用slot-scope来接收数据,vue3用v-slot来接收,同时v-slot可以简写为#,
reactive 和 ref 的区别?
1.ref用于定义基本类型和引用类型,reactive仅用于定义引用类型
2.reactive只能用于定义引用数据类型的原因在于内部是通过ES6的Proxy实现响应式的,而Proxy不适用于基本数据类型
3.ref定义对象时,底层会通过reactive转换成具有深层次的响应式对象,所以ref本质上是reactive的再封装
4.在脚本里使用ref定义的数据时,记得加.value后缀
5.在定义数组时,建议使用ref,从而可避免reactive定义时值修改导致的响应式丢失问题
vue3中配置自动按需导入auto-import
//vite.config.js
import autoImport from 'unplugin-auto-import/vite'
export default function createAutoImport() {
return autoImport({
imports: [
'vue',
'vue-router',
'pinia'
],
dts: false
})
}