vue3单文件组件组合式 API 语法糖 (<script setup>) 基础使用
vue文件中使用
setup-script无需return<script setup></script>
响应式数据
-
使用前需引入;
import { ref, reactive } from 'vue' -
非Object数据类型使用
ref,Object数据类型使用reactive;var string = ref(''); var bool = ref(false); var num = ref(1); var obj = reactive({}); -
ref方法定义的数据需要使用.value属性值赋值;var string = ref(''); string.value = '这样赋值'; -
reactive方法定义的数组或对象,直接整个赋值不触发视图更新,需对单项下标/属性赋值;var arr = reactive([]); arr = [1]; //这样不触发视图更新 arr[0] = 1; //触发视图更新
生命周期使用
-
整个setup-script标签运行于
created前,beforeCreated后,如需使用created之后的生命周期钩子,需要引入使用;import { onMounted } from 'vue'; onMounted(() => { console.log('这是mounted~~~') }) -
具体有
onBeforeMounted, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmounte(原beforeDestory), onUnmounted;
侦听器使用
-
watchEffect
watchEffect,立即执行传入的一个函数,同时响应式追踪其依赖,并在其依赖变更时重新运行该函数。import { watchEfect } from 'vue'; var count = ref(0); watchEffect(() => { console.log(count) }) -
watch监听ref
import { watch } 'vue'; var count = ref(0); watch(count, (newVal, oldVal) => { console.log(newVal, oldVal) }) -
watch监听reactive
var reObj = reactive({ a: 1, b: { c: 2 } }) watch(reObj, (newVal, oldVal) => { //监听整个reactive可直接深度监听 xxx }) -
watch监听对象属性
//监听对象属性这样写 var count = ref(0); var countObj = ref({ a: 0 }); var obj = { b: 0}; watch(() => count.value, () => {}); watch(() => countObj.a, () => {}); watch(() => obj.b, () => {}); -
watch深度监听
var obj = { a: { b: 0 } }; watch(obj, () => {}, { deep: true, lazy: true, //初始化不监听 }) -
主动清除侦听器
在setup()函数内创建watch监听,会在当前组件被销毁才会停止,如果想明确的停止某个监听,可以调用watch的返回值即可。const stop = watch(count, () => {}); if(xxx) { //调用stop后该侦听器就会停止监听 stop(); } -
侦听器停止时终止异步方法
页面销毁时侦听器停止监听,异步方法可能还在响应中,但这种响应已无必要。可以使用onInvalidate中止。watch(count, (newVal, oldVal, onInvalidate) => { const timer = setTimeout(() => { console.log(val); }, 3000); onInvalidate(() => { clearTimeout(timer); }) }) -
监听多个数据
var moreCount = ref(1); var moreStr = ref('what'); watch([moreCount,moreStr], ([newCount, newStr], [oldCount, oldStr]) => { console.log(newCount, newStr, oldCount, oldStr); })
计算属性computed
根据依赖数据变化响应,返回处理后的新的数据;建议数据过滤采用计算属性。
-
只读computed
import { computed } from 'vue'; var a = ref(1); var b = computed(() => { return a+2; }) -
可读写computed
import { computed } from 'vue'; var a = ref(1); var b = computed({ get() { return a+1; }, set(val) { return a.value = val - 1; } })
组件使用
-
组件引入和使用;
<script setup>标签内import后即可直接使用:<template> <tool></tool> </template> <script setup> import tool from '@/component/tool'; </script> -
props使用,需要引入;import { defineProps } from 'vue'; const props = defineProps({ propsData: { type: String, default: '这是props' } }) -
组件通信,需引入;
import { defineEmits } from 'vue';
路由跳转
-
页面跳转
import { useRouter } from 'vue-router'; const router = userRouter(); router.push('/index'); //query传参 router.push({ path: '/index', query: { id: 1 } }) //params传参,必须使用name,否则会报错 router.push({ name: 'index', params: { id: 1 } }) -
参数接收
import { useRoute } from 'vue-router'; const route = userRoute(); var id = route.query.id;
全局参数方法
-
注册全局参数方法
main.js文件内导入全局变量和全局方法文件,使用app.config.globalProperties注册;import App from "./App.vue"; import config from './utils/config'; //全局变量 import axios from "./service/index"; //全局方法 const app = createApp({ ...App }) app.config.globalProperties.$axios = axios; app.config.globalProperties.$config = config; -
使用全局方法,需引入
getCurrentInstance;import { getCurrentInstance } from 'vue'; const { proxy } = getCurrentInstance(); console.log(proxy.$config, proxy.$axios);
<style>中的v-bind
<style>可以使用js中的变量了
<script setup>
const theme = {
color: 'red'
}
</script>
<template>
<p>hello</p>
</template>
<style scoped>
p {
color: v-bind('theme.color');
}
</style>
实际的值会被编译成 hash 的 CSS 自定义 property,CSS 本身仍然是静态的。自定义 property 会通过内联样式的方式应用到组件的根元素上,并且在源值变更的时候响应式更新
使用过程问题
路由与跨域代理冲突
-
问题描述:
创建adminManage文件夹存放admin相关vue文件,路由路径变为/adminManage/xxx.vue;主动刷新页面变为json返回字段页面,提示未登录。 -
解决方法:
路由名与跨域代理中的/admin冲突导致,修改路由名去除admin即可。
页面组件销毁监听器依旧生效(暂无法重现)
- 问题描述:
页面组件注册监听器监听路由,该页面组件未销毁时,页面切换都会触发该侦听器。该页面销毁后,侦听器仍然存在且切换页面仍可触发;再次打开该页面组件,此侦听器被重复注册,即当前存在两个相同功能的侦听器,且均可被触发。