1、生命周期函数
import {onBeforeMount, onBeforeUpdate, onBeforeUnmount, onMounted, onUpdated, onUnmounted, reactive} from 'vue';
//组件实例挂载前执行
onBeforeMount(() => {
console.log('onBeforeMount')
});
//组件实例更新前执行
onBeforeUpdate(() => {
console.log('onBeforeUpdate')
});
//组件实例卸载前执行
onBeforeUnmount(()=>{
console.log('onBeforeUnmount')
})
//组件实例挂载后执行
onMounted(()=>{
console.log('onMounted')
})
//组件实例更新后执行
onUpdated(() => {
console.log('onUpdated')
});
//组件实例卸载后执行
onUnmounted(()=>{
console.log('onUnmounted')
})
2、路由相关
//路由跳转
import {useRouter} from "vue-router";
const router = useRouter();
function login(){
router.push('/home')
}
---------------------------------------
//路由守卫
//全局前置守卫
import { createRouter, createWebHistory } from 'vue-router';
const router = createRouter({
history: createWebHistory(),
routes: [...]
});
router.beforeEach((to, from, next) => {
// 在路由切换之前执行的逻辑
if (to.meta.requiresAuth && !isAuthenticated) {
// 如果需要登录验证,并且用户未登录,则重定向到登录页
next('/login');
} else {
// 否则继续路由切换
next();
}
});
---------------------------------------
//路由独享守卫:针对特定路由定义的守卫,只在该路由切换时执行
const routes = [
{
path: '/admin',
component: AdminComponent,
beforeEnter: (to, from, next) => {
// 在/admin路由切换之前执行的逻辑
if (!isAdmin) {
// 如果用户不是管理员,则取消路由切换
next('/dashboard');
} else {
// 否则继续路由切换
next();
}
}
},
// 其他路由...
];
---------------------------------------
//组件内守卫:在组件内定义的守卫,用于处理特定组件的生命周期事件
export default {
// 组件内的路由守卫
beforeRouteEnter(to, from, next) {
// 在组件路由进入之前执行的逻辑
// 由于组件还未创建,无法访问组件实例,因此使用回调函数 next 来访问组件实例
next(vm => {
// 可以访问组件实例的属性和方法
if (vm.isLoggedIn) {
// 如果用户已登录,则继续路由切换
next();
} else {
// 否则重定向到登录页
next('/login');
}
});
},
// 其他组件生命周期钩子...
};
3、数据双向绑定
//使用ref实现数据双向绑定
<template>
<input v-model="value"/>
{{value}}
</template>
<script setup lang="ts">
import { ref } from 'vue';
const value = ref('666')
</script>
//使用reactive实现响应式对象
<template>
<div @click="change">改变变量值:{{data.queryParams.pageNum}}</div>
</template>
<script setup lang="ts">
const data = reactive({
form: {},
queryParams: {
pageNum: 1,
pageSize: 10,
name: undefined,
},
rules: {
jobName: [{ required: true, message: "名称不能为空", trigger: "blur" }]
}
})
function change() {
data.queryParams.pageNum= 2
}
</script>
//使用ref实现响应式对象,替换reactive为ref,取值中添加.value变为data.value.queryParams.pageNum
const data = ref({
form: {},
queryParams: {
pageNum: 1,
pageSize: 10,
name: undefined,
},
rules: {
jobName: [{ required: true, message: "名称不能为空", trigger: "blur" }]
}
})
function change() {
data.value.queryParams.pageNum= 2
}
4、组件通信
//父组件传值给子组件
//父组件
<HelloWorld msg="Hello Vue 3 + Vite" ref="hello" @getValue="getValue" />
//子组件使用defineProps接收参数
<script setup lang="ts">
const props = defineProps({
msg: String
})
console.log(props.msg);
</script>
---------------------------------------------
//子组件使用defineEmits传值给父组件
const emit = defineEmits(["getValue"])
function send() {
emit('getValue', 888)
}
//父组件接收值
function getValue(value: number): void {
console.log("子组件传过来的" + value);
}
---------------------------------------------
//父组件中调用子组件的方法
//父组件
<button @click="callChildMethod">调用子组件方法</button>
//子组件中的方法
function childMethod(params:any) {
console.log('获取子组件方法,参数为',params);
}
方法1,通过proxy:
const { proxy } = getCurrentInstance() as any;
function callChildMethod() {
//子组件中需使用defineExpose暴露方法
proxy.$refs["hello"].childMethod('refs')
}
//子组件中使用defineExpose暴露方法
defineExpose({
childMethod,
});
方法2,通过ref:
const hello = ref < any > ();
function callChildMethod() {
//子组件不需要暴露方法
hello.value.childMethod('ref < any >')
}
方法3,通过v-model:
//父组件
<template>
<Child v-model="message" />
{{message}}
</template>
<script setup>
const message = ref('父传给子');
</script>
子组件:
<template>
<div>
<button @click="handleClick">修改model</button>
{{ modelValue }}
</div>
</template>
<script setup>
// 接收
defineProps([
'modelValue', // 接收父组件使用 v-model 传进来的值,必须用 modelValue 这个名字来接收
]);
const emit = defineEmits(['update:modelValue']); // 必须用 update:modelValue 这个名字来通知父组件修改值
function handleClick() {
emit('update:modelValue', '子改变值');
}
</script>
5、watch
import {ref, watch, watchEffect} from 'vue';
const count = ref(1)
//通过watch监听
watch(count , (newValue, oldValue) => {
console.log(`value发生变化,新值为:${newValue},旧值为:${oldValue}`);
});
//通过watchEffect监听
watchEffect(() => {
console.log(count .value);
});
6、computed
const count = ref(1)
const showTip = computed(() => {
return count.value * 0.8;
});
console.log(showTip.value);
7、pinia相关
//useCounter.ts
import { defineStore } from "pinia"
// 调用defineStore定义store, defineStore返回一个函数
const useCounter = defineStore("counter", {
state: () => ({
counter: 101
}),
// 定义getters
getters: {
doubleCounter(state) {
return state.counter * 2
}
}
})
// 将useCounter函数导出
export default useCounter
<button @click="getInfo">获取store信息</button>
<button @click="resetInfo">重置store信息</button>
<button @click="getInfo">获取store信息</button>
<script setup lang="ts">
import counts from '../store/useCounter'
const counterStore = counts()
function getInfo() {
console.log(counterStore.counter);
}
function resetInfo(){
counterStore.$reset()
}
function changeInfo() {
counterStore.$patch({
counter: 808
})
}
</script>