vue3知识点整理

本文介绍了Vue.js的关键特性,包括组件的生命周期函数,如onBeforeMount和onUpdated;路由管理,涉及路由跳转、全局和局部路由守卫;数据双向绑定,利用ref和reactive实现;组件间的通信,如props和emits;watch和watchEffect的使用,以及Pinia状态管理库的简单应用。
摘要由CSDN通过智能技术生成

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>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值