vue3知识点

定义变量

ref定义 基本类型 对象类型 解构赋值(需.value)

reactive 对像类型 解构赋值失去响应性

javescript 复制代码
ref 
const num = ref(0)
num.value = 
const stringName = ref('111')
const  isType = ref(true)
javescript 复制代码
reactive
const num = reactive({name:'123',age:3})
num.name   num.age
若是想把{name:'345',age:120} 赋值给num
Object.assign('num',{name:'345',age:120})
或者
toRefs使reactive中的值都转换成单个ref对象具有响应式
let {name,age} = toRefs(num)  转换成的是 let name = ref('')   let age = ref()

解构

toRefs 是把响应式的东西拿出来 在设置成响应式的

toRef 某个属性转成具有响应式的属性

computed计算属性

computed 有缓存 只读不可修改

javescript 复制代码
import { ref, computed } from 'vue';

const message = ref('Hello');
const reversedMessage = computed(() => {
  return message.value.split('').reverse().join('');
});

如果想要修改某个值 需要使用 get set 方法进行修改

javascript 复制代码
<template>
  <div>
    <p>Full name: "{{ fullName }}"</p>
    <input v-model="fullName" />
  </div>
</template>

import { ref, computed } from 'vue';

const firstName = ref('John');
const lastName = ref('Doe');

const fullName = computed({
  get() {
    return firstName.value + ' ' + lastName.value;
  },
  set(newValue) {
    [firstName.value, lastName.value] = newValue.split(' ');
  }
});
</script>

watch

watch 只能监听ref 定义的基本类型和对象类型数据

watch监听基本类型

watch(sum,(v,o)=>{}) watch

监听对象类型的话 监视的是对象的地址值 若想监听到对象内部属性的变化 开启深度监听

watch(person,(n,o)=>{},{deep:true})

watch 监听 reactive 定义的对象 默认是 开启深度监听的 是不能关闭的

let person = reactive({

name:'111',car:{car1:'1',car2:'2'}

})

watch(()=>person.name) 监听对象中的对象

watch(person.car,(new,val)=>{}) 监听c1 c2 可用

watch(()=>person.car,(new,val)=>{}) 监听整个car可用

watch(()=>person.car,(new,val)=>{},{deep:true}) 监听整个car c1 c2 都可用

监听的如果是对象中的属性 使用函数式

若是对象监听的是地址值 需关注对象内部 需要手动开启深度监听

watch 监听多个变量的时候

watch([a,b],(val)=>{ 其中 value是[a的最新值,b的最新值]

let [a1,b1] = value 解构赋值

})

watchEffect

watchEffect 不用写监视谁 直接写回调 立即运行一个函数 同时 响应式的追踪其依赖 并在依赖更改时 重新执行该函数

watchEffect(()=>{

if(a.value)

})

watch 对比watchEffect

都能监听响应式数据的变化,不同的是监听数据变化的方式不同 watch 要明确指出监视的数据 watchEffect 不用明确指出监视的数据 函数中用到哪些属性那就监视哪些属性

vue3中的执行顺序

先执行子组件的mounted 再执行父组件的mounted App.vue 是最后执行的

hook 封装

hook类似vue2中的mixin

具体用法

hook/user.ts

export functiion qwe(){

...属性 方法 函数

return {方法 属性 函数}

}

使用

import qwe from '@/hook/user'

const {方法,属性} = qwe()

vue-router

1 安装

npm install vue-router

2 创建路由配置文件

src/router/index.js

import { createRouter, createWebHistory } from 'vue-router';

import Home from '.../views/Home.vue';

import About from '.../views/About.vue';

const routes = [

{ path: '/', component: Home },

{ path: '/about', component: About }

];

const router = createRouter({

history: createWebHistory(),

routes

});

export default router;

3 main.js中使用

import { createApp } from 'vue';

import App from './App.vue';

import router from './router';

const app = createApp(App);

app.use(router);

app.mount('#app');

4 路由的基本使用

javescript 复制代码
      路由占位符
     <router-link to="/">Home</router-link>    跳转区
    <router-link to="/about">About</router-link>   展示区
    <router-view></router-view>
javescript 复制代码
      组合式 API 访问
     import { useRouter, useRoute } from 'vue-router';

	export default {
	  setup() {
	    const router = useRouter();
	    const route = useRoute();
	
	    // 路由跳转
	    router.push('/about');
	    let {query} = toRefs(router)      路由携带参数解构 都变成响应式的
	    let {params} = toRefs(router)      路由携带参数解构 都变成响应式的
	    // 获取路由参数
	    console.log(route.params.id);
	  }
	};

全局前置守卫

javescript 复制代码
router.beforeEach((to, from, next) => {
  if (to.path === '/admin' && !isAuthenticated) {
    next('/login');
  } else {
    next();
  }
});

组件内守卫

javescript 复制代码
export default {
  beforeRouteEnter(to, from, next) {
    next(vm => {
      // 访问组件实例
    });
  }
};

嵌套路由 配置子路由

javescript 复制代码
const routes = [
  {
    path: '/user',
    component: UserLayout,
    children: [
      { path: 'profile', component: UserProfile },
      { path: 'settings', component: UserSettings }
    ]
  }
];

路由的props

javescript 复制代码
const routes = [
  {
    path: '/user/:id/:title/:content?',    添加?时传不传都行
    component: UserLayout,
   法1  props:true      将路由收到的原有params 参数作为props 传给路由组件     只对params 有效
   法2  props(route){    函数写法   可以自己决定 将什么作为props 传给路由组件
               return  route.query
           }   
   法3   props:{a:'',b:'',c:''}   对象的写法 可以自己决定将什么作为props 传给组件
  }
];

在user页面 props:true   的页面
defineProps(['id','title','content'])

基础导航

javescript 复制代码
router.push('/about');
router.replace('/home');
router.go(-1); // 后退一页
router.push({ name: 'user', params: { id: 123 } });
router.push({ path: '/user', query: { sort: 'asc' } });

history hash模式

history url比较美观 没有 #号 项目上线时需要服务端配合处理路径问题 否则刷新404问题

大致相关配置

location / {

root:'/root/XXXXXX'

index index.html

try_files

uri uri/ index.html

}

hash 模式 兼容性更好 SEO 优化较差

const router = createRouter({

history: createWebHashHistory(),

routes

});

数据传递

方式1 总线 mitt 接收数据 提前绑定好事件(提前订阅消息) 提供数据:在合适得时候触发事件(发布)

utils/emitter.ts

javescript 复制代码
import  mitt  from  'mitt'
export mitt()
或者
const emitter = mitt()  调用mitt得emitter   emitter能绑定事件 触发事件
export  default  emitter
javescript 复制代码
使用
import  emitter  from  '@/utils/emitter.ts'
emitter.on('test',(v)=>{})  绑定事件
emitter.off('test')解除绑定
emitter.emit('test')触发事件
emitter.all.clear()  解除所有函数绑定
在组件卸载时解绑事件  emitter.off('test')解除绑定

方式2

$attrs 是什么

父组件传递给子组件但未被声明为 props 的属性

包括 HTML 属性、自定义属性、DOM 事件监听器

不包含:已声明的 props class 和 style(在 Vue 3 中它们有单独的处理机制)

用于实现当前组件的父组件向当前组件的子组件通信(祖-->孙)

所有父组件向子组件传递的数据 接收了 会存在props中 没接收的都在attrs中 $attrs中会包含所有未接收的对象

javescript 复制代码
<!-- Parent.vue -->
<template>
  <ChildComponent 
    title="父组件标题" 
    data-id="123" 
    @custom-event="handleEvent"
    class="parent-class"
  />
</template>

<!-- ChildComponent.vue -->
<template>
  <div>
    <!-- 将未声明的属性透传给孙子组件 -->
    <GrandChild v-bind="$attrs" />
  </div>
</template>

<script setup>
// 只声明了 title 作为 prop
defineProps(['title'])
</script>

<!-- GrandChild.vue -->
<template>
  <div>
    <!-- 将接收到的属性绑定到根元素 -->
    <div v-bind="$attrs">孙子组件</div>
  </div>
</template>
结果  title 被 ChildComponent 作为 prop 接收
data-id 和 @custom-event 透传到 GrandChild
GrandChild 的根元素会获得:data-id="123" 和 custom-event 监听器

Vue 3 中的变化(对比 Vue 2)

特性

Vue 2 包含内容 普通属性 class/style 包含在 attrs 中 事件监听器 在 listeners 中 透传方式 需要同时绑定 attrs 和 listeners

Vue 3 包含内容 属性 + 事件监听器 class/style 不包含在 attrs 中 事件监听器 合并到 attrs 中 透传方式 只需绑定 $attrs

方式3

$refs

  1. 操作子组件数据: 一旦获取到子组件的实例,父组件可以修改子组件暴露的变量值,实现父子组件间的直接数据交换。
  2. 批量处理子组件:$refs 可以用于同时获取多个子组件的实例,从而一次性操作多个子组件的数据,这对于批量更新非常有用。
  3. 访问DOM元素: 除了组件实例,$refs也可以用来获取原生DOM元素的引用,使得开发者可以直接操作DOM元素的属性和方法。

$parent

1.访问父组件实例:$parent允许子组件直接访问其父组件的实例,这为子组件提供了一种方式来调用父组件的方法或修改父组件的数据。

2.破坏封装性

虽然$parent提供了强大的功能,但它也可能导致组件间的紧耦合,破坏了组件的封装性和复用性。因此,官方推荐使用props和自定义事件来实现父子组件间的通信。

3.defineExpose使用

在Vue3中,为了安全地暴露父组件的数据和方法给子组件,可以使用defineExpose宏,这是一种更可控且类型友好的方式。

4.限制使用场景

由于$parent可能导致代码难以维护和理解,它通常不建议作为首选的通信方式,特别是在大型应用中。

javescript 复制代码
父组件
<template>
    <div class="father">
        <h4>父组件</h4>
	    <h4>父亲的房:{{ house }}</h4>
        <button @click="changeCar">修改子的车</button>
        <son ref="s"/>
    </div>
</template>
<script setup lang="ts" name="father">
    import { ref } from "vue";
    import son from "../components/son.vue";
    let s = ref()
    let house = ref('檀宫')
    function changeCar(){
        s.value.car = '奔驰'
    }
    //暴露属性
    defineExpose({house})
</script>

子组件
<template>
    <div class="son">
        <h4>子组件</h4>
        <h4>子的汽车:{{ car }}</h4>
        <button @click="changeHouse($parent)">传输数据给父</button>
    </div>
</template>
<script setup lang="ts" name="father">
    import { ref } from "vue";
    let car = ref('宝马')
    function changeHouse(parent:any){
        parent.house = '汤臣一品'
    }
    defineExpose({car})
</script>

批量修改相关ts

javescript 复制代码
父组件中  @click= getA($refs)
function getA(refs:{[key:string]:any}){    [key:string]  定义数据中包含key是string类型    :any 值any  若使用object 会报类型错误
   for(let key in refs){
       refs[key].book +=3    refs[key]里面得值不定 属性名不定 不能用object定义类型
   }
}

方式4

provide inject 祖到孙 孙到祖

javescript 复制代码
 具体使用
 发送
 import  {provide} from 'vue'
 provide('名','值')
 实现
 let money = ref(0)
 const updateMoney = (v:number)=>{}
 provide('名',{money,updateMoney})    money 必须传递得是响应式对象     updateMoney函数
 
 接收
 import {inject}  from 'vue'
 let x = inject('名')  或   let x = inject('名','默认值')  或   let x = inject('名',{brand:未知,price:0})
 实现接收
 inject('名',{money:0,updateMoney:(x:num)=>{}})
 

插槽

javescript 复制代码
默认插槽     
父组件
<category  >
      <span>123</span>
</category>
子组件category.vue  
<div>
   <slot></slot>     
</div>
javescript 复制代码
具名插槽      name   v-slot
父组件
<category  >
     <template v-slot:'s1'>
         <span>123</span>
     </template>
     简写
     <template #s1>
    </template>
</category>
子组件category.vue  
<div>
   <slot name='s1'></slot>     
</div>
javescript 复制代码
作用域插槽       数据在子组件中 但是结构由父组件决定 
父组件
<category  >
     <template v-slot='params'  || v-slot='params.games1' || v-slot={games1}>
         <span>{{ params.games1 || games1 }}</span>
     </template>
</category>
子组件category.vue  
<div>
   <slot :games1='games'></slot>       :games1='games'  子组件传递数据
</div>
作用域插槽也可以有名字
<slot name='qwe' :games1='games'></slot>
<template v-slot:qwe='params'>{{params.games1}}</template>

其他

shallowRef 只处理第一层的响应式

shallowReactive 浅层次的响应式 只改第一层

readonly 只读

shallowReadonly 浅层次第一层只读

let sum1 = ref(0)

let sum2 = readonly(sum1)

sum2不可直接修改 对数据的保护

readonly(sum1) 响应式对象通过改变sum1修改sum2

toRow 原始数据 函数响应式 不会触发视图更新 用于获取一个响应式对象的原始对象 收到的是普通对象

markRow 标记一个对象 使其永远不会变成响应式的

customRef 自定义Ref

javescript 复制代码
let initValue = '123'
let msg = customRef((track,trigger)=>{
    return  {
       get(){
          track()      持续关注一旦变化就会更新
          return initValue
       },
       set(value){
              initValue = value
              trigger()      通知vue数据变化
       }
   }
})

Teleport 是 Vue3 提供的一个内置组件,它可以将组件的内容传送到 DOM 树的任何位置,而不受组件层级的限制。这在处理模态框、通知、弹出菜单等需要突破组件层级限制的场景中特别有用。

javescript 复制代码
<template>
  <teleport to="body">
    <!-- 这里的内容会被传送到 body 标签下 -->
    <div class="modal">
      <!-- 模态框内容 -->
    </div>
  </teleport>
</template>
原文链接:https://blog.csdn.net/qq_34645412/article/details/145370022

Suspense 是 Vue 3 中用于处理异步组件加载的内置组件,它允许在等待异步组件时显示备用内容

javescript 复制代码
<template>
  <Suspense>
    <!-- 默认插槽:显示主要内容 -->
    <template #default>
      <AsyncComponent />
    </template>

    <!-- fallback 插槽:加载时显示备用内容 -->
    <template #fallback>
      <div>加载中...</div>
    </template>
  </Suspense>
</template>

app.component('hello',hello) 全局组件

app.config.globalProperties.x = '9' 全局属性

如果要给项目添加整体灰调 filter:saturate(0)滤镜 饱和度为0 灰色

自定义指令

app.directive('beauty',(element,{value})=>{

element.innerText += value

element.style.color = 'green'

})

< p v-beauty='sun'>开心< /p>

app.mount('') 挂载

app.unmount() 卸载

app.use()安装插件

vue2与vue3 区别

v-enter 修改为了 v-enter-from

v-leave 修改为了 v-leave-from

v-if v-for 使用优先级发生改变 2 不能同时使用v-if v-for v-if优先级低 v-for 优先级高 3 v-if优先级高于v-for

移除了on off once 方法 filter children propert

event 对原生事件 event就是事件对象能.target

对自定义事件 $event就是触发事件时所传递的数据 不能.target

v-model

javescript 复制代码
v-model  用于html标签   
< input type='text' v-model='name' />
原理  <input :value='name'  type='text'  @input="name=(<HTMLInputElement>$event.target.value)">

v-model  用于组件标签
<childrenCom v-model="name" />
父级
<script setup>
import { ref } from 'vue'

const title = ref('默认标题')
const content = ref('这里是内容')
</script>

<template>
  <CustomEditor v-model:title="title" v-model:content="content" />
  <p>标题:{{ title }}</p>
  <p>内容:{{ content }}</p>
</template>

CustomEditor.vue
<script setup>
import { defineProps, defineEmits } from 'vue'

defineProps(['modelValue', 'modelModifiers', 'title', 'content'])
const emit = defineEmits(['update:title', 'update:content'])
</script>

<template>
  <div>
    <input
      :value="title"
      @input="event => emit('update:title', event.target.value)"
      placeholder="编辑标题"
    />
    <textarea
      :value="content"
      @input="event => emit('update:content', event.target.value)"
      placeholder="编辑内容"
    ></textarea>
  </div>
</template>
详细链接 :https://blog.csdn.net/2301_79858914/article/details/143828284
相关推荐
JIngJaneIL2 小时前
基于java+ vue建筑材料管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot
土豆12502 小时前
终端自治时代的 AI 开发范式:Claude Code CLI 全方位实操指南
前端·人工智能·程序员
一 乐2 小时前
办公系统|基于springboot + vueOA办公管理系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·spring
Gazer_S2 小时前
【Vue Router 路由守卫(Navigation Guards)指南:概念、执行顺序、beforeResolve、异步路由组件】
前端·javascript·vue.js
半梅芒果干2 小时前
vue3 新建文件store自动导入
开发语言·前端·javascript
玖笙&2 小时前
✨万字解析解析:Vue.js优雅封装级联选择器组件(附源码)
前端·javascript·vue.js·前端框架
烟袅2 小时前
深入理解 React 中 useState 与 useEffect
前端·javascript·react.js
行走的陀螺仪2 小时前
前端基建从0到1搭建步骤清单(含工具选型+配置要点+落地注意事项)
前端·javascript·typescript·设计规范·前端工程化·规范化·前端基建