1、声明基本类型
数据声明现在的一般规则是:
- 使用 reactive 代替 Object, Array, Map, Set
- 使用 ref 代替 String, Number, Boolean
<script lang="ts" setup>
import { reactive, ref } from 'vue';
const num = reactive(0); // value cannot be made reactive: 0
const obj = ref({});
</script>
对于原始值使用reactive会导致警告,但使用ref声明Object可以,并且将在内部调用reactive。
2、.value
该值在对象内部在 .value 属性下可用,但在模版中使用时,引用会被解包,这时.value不需要。但解包只在顶层属性有效。
<template>
<button @click="add">
{{ num }}
</button>
<div>{{ obj.foo }}</div> <!-- 1 -->
<div>{{ obj.foo + 1 }}</div> <!-- [object Object]1 -->
</template>
<script lang="ts" setup>
import { ref } from 'vue';
const num = ref(0);
console.log(num); // { value: 0 }
const add = () => {
num.value ++;
}
const obj = { foo: ref(1) }
</script>
3、不支持this
<script lang="ts" setup>
import { useRoute, useRouter } from 'vue-router';
import { useStore } from 'vuex';
import { getCurrentInstance } from 'vue'
const { proxy } = getCurrentInstance();
const router = useRouter();
const route = useRoute();
const store = useStore();
console.log(route.query.redirect)
console.log(proxy.$refs.formRef)
const gotoUserNote = () => {
store.commit('permission/SET_UPDATE_CARD_SHOW', false);
router.push('/agreement/user-note');
};
</script>
4、router.currentRoute
router.currentRoute是ref响应式数据 要拿值的话需要.value,或者用unref转
<template>
<div>{{ currentRoute_false }}</div> <!-- -->
<div>{{ currentRoute_true }}</div> <!-- /test -->
</template>
<script lang="ts" setup>
import { unref } from 'vue';
import { useRouter } from 'vue-router';
const router = useRouter();
const currentRoute_false = router.currentRoute.fullPath //没有.value
const currentRoute_true = router.currentRoute.value.fullPath
const currentRoute = unref(router.currentRoute);
console.log(currentRoute.fullPath) // /test
</script>
5、setup不支持
有一些 Options API 方法的属性在 script setup 中不受支持。
- name
- inheritAttrs
- 插件或库需要的自定义选项
需要在同一组件定义两个不同的脚本
<script lang="ts">
export default {
name: 'PyPicker',
inheritAttrs: false,
customOptions: {}
}
</script>
<script setup>
// script setup logic
</script>
或者不使用setup
<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
name: 'PyPicker',
inheritAttrs: false,
customOptions: {},
setup(props, { emit }) {}
})
6、导入
使用defineEmits和defineProps (用于声明props),都不需要导入,当使用setup时,它们会自动可用。
<script lang="ts" setup>
const props = defineProps({
foo: String,
});
const emit = defineEmits(['confirm']);
emit('confirm');
</script>
7、refs
需注意:在列表数组上循环,并创建 itemRefs 数组。但如果不是在循环上获取ref,这时的下一个ref会覆盖上一个ref。
<template>
<ul>
<li v-for="item in list" ref="itemRefs" :key="item">
{{ item }}
</li>
<li ref="abitemRefs">内容1</li>
<li ref="abitemRefs">内容2</li>
</ul>
</template>
<script setup>
import { nextTick, ref } from "vue";
import { getCurrentInstance } from 'vue'
const { proxy } = getCurrentInstance();
const list = ref([1, 2, 3]);
const itemRefs = ref([]);
nextTick(() => {
console.log(proxy.$refs.itemRefs)
console.log(proxy.$refs.abitemRefs)
})
</script>