当前位置: 首页 > news >正文

Vue3 常用代码指南手抄,超详细 cheatsheet

一、Vue3 基础

1.1 创建 Vue3 项目
  • 使用 Vite 创建
npm create vite@latest my-vue-app -- --template vue
cd my-vue-app
npm install
npm run dev
  • 使用 Vue CLI 创建
npm install -g @vue/cli
vue create my-vue-app
1.2 项目结构
my-vue-app
├── node_modules
├── public
│   └── favicon.ico
├── src
│   ├── assets
│   ├── components
│   ├── views
│   ├── App.vue
│   ├── main.js
│   └── router
├── .gitignore
├── index.html
├── package.json
├── vite.config.js
└── README.md
1.3 main.js 配置
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'const app = createApp(App)app.use(router)
app.use(store)app.mount('#app')

二、组件

2.1 组件注册
  • 全局注册
import { createApp } from 'vue'
import MyComponent from './components/MyComponent.vue'const app = createApp(App)
app.component('MyComponent', MyComponent)
app.mount('#app')
  • 局部注册
<template><MyComponent />
</template><script>
import MyComponent from './components/MyComponent.vue'export default {components: {MyComponent}
}
</script>
2.2 组件通信
  • 父传子: props
// 父组件
<template><ChildComponent :message="parentMessage" />
</template><script>
import ChildComponent from './ChildComponent.vue'export default {components: { ChildComponent },data() {return {parentMessage: 'Hello from parent'}}
}
</script>
// 子组件
<template><div>{{ message }}</div>
</template><script>
export default {props: {message: {type: String,required: true}}
}
</script>
  • 子传父: emit
// 子组件
<template><button @click="sendMessage">Send Message</button>
</template><script>
export default {emits: ['message'],methods: {sendMessage() {this.$emit('message', 'Hello from child')}}
}
</script>
// 父组件
<template><ChildComponent @message="handleMessage" />
</template><script>
import ChildComponent from './ChildComponent.vue'export default {components: { ChildComponent },methods: {handleMessage(message) {console.log(message)}}
}
</script>
  • 兄弟组件通信: EventBus
// event-bus.js
import { EventEmitter } from 'vue'
export const EventBus = new EventEmitter()
// 组件 A
<template><button @click="sendMessage">Send Message</button>
</template><script>
import { EventBus } from './event-bus'export default {methods: {sendMessage() {EventBus.emit('message', 'Hello from component A')}}
}
</script>
// 组件 B
<template><div>{{ message }}</div>
</template><script>
import { onMounted, onUnmounted } from 'vue'
import { EventBus } from './event-bus'export default {data() {return {message: ''}},setup() {const handleMessage = (msg) => {message.value = msg}onMounted(() => {EventBus.on('message', handleMessage)})onUnmounted(() => {EventBus.off('message', handleMessage)})}
}
</script>
2.3 插槽
  • 默认插槽
// 子组件
<template><slot></slot>
</template>
// 父组件
<ChildComponent><p>默认插槽内容</p>
</ChildComponent>
  • 具名插槽
// 子组件
<template><slot name="header"></slot><slot></slot><slot name="footer"></slot>
</template>
// 父组件
<ChildComponent><template #header><h1>Header</h1></template><p>默认插槽内容</p><template #footer><p>Footer</p></template>
</ChildComponent>
  • 作用域插槽
// 子组件
<template><slot :user="user"></slot>
</template><script>
export default {data() {return {user: { name: 'Alice', age: 25 }}}
}
</script>
// 父组件
<ChildComponent v-slot:default="slotProps"><p>{{ slotProps.user.name }}</p>
</ChildComponent>

三、Vue Router

3.1 基本配置
// router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
import About from '../views/About.vue'const routes = [{ path: '/', name: 'Home', component: Home },{ path: '/about', name: 'About', component: About }
]const router = createRouter({history: createWebHistory(),routes
})export default router
// 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')
3.2 导航守卫
  • 全局守卫
router.beforeEach((to, from, next) => {console.log('全局前置守卫')next()
})
  • 路由独享守卫
const routes = [{path: '/',component: Home,beforeEnter: (to, from, next) => {console.log('路由独享守卫')next()}}
]
3.3 动态路由
  • 定义动态路由
const routes = [{ path: '/user/:id', name: 'User', component: User },
]
  • 获取路由参数
<template><div>User ID: {{ id }}</div>
</template><script>
import { useRoute } from 'vue-router'export default {setup() {const route = useRoute()return {id: route.params.id}}
}
</script>
  • 路由跳转
<template><router-link to="/user/123">Go to User 123</router-link>
</template>
<script>
import { useRouter } from 'vue-router'export default {setup() {const router = useRouter()const goToUser = () => {router.push({ name: 'User', params: { id: 123 } })}return { goToUser }}
}
</script>
3.4 嵌套路由
const routes = [{path: '/dashboard',component: Dashboard,children: [{path: 'profile',component: Profile},{path: 'settings',component: Settings}]}
]
<!-- Dashboard.vue -->
<template><div><h1>Dashboard</h1><router-view></router-view></div>
</template>
3.5 路由懒加载
const Home = () => import('../views/Home.vue')
const routes = [{ path: '/', name: 'Home', component: Home },
]

四、Vuex

4.1 基本配置
// store/index.js
import { createStore } from 'vuex'export default createStore({state: {count: 0},mutations: {increment(state) {state.count++}},actions: {increment({ commit }) {commit('increment')}},getters: {doubleCount(state) {return state.count * 2}}
})
// main.js
import { createApp } from 'vue'
import App from './App.vue'
import store from './store'const app = createApp(App)
app.use(store)
app.mount('#app')
4.2 使用 Vuex
  • 在组件中获取 state
<template><div>Count: {{ count }}</div>
</template><script>
import { mapState } from 'vuex'export default {computed: {...mapState(['count'])}
}
</script>
  • 在组件中提交 mutation
<template><button @click="increment">Increment</button>
</template><script>
import { mapMutations } from 'vuex'export default {methods: {...mapMutations(['increment'])}
}
</script>
  • 在组件中分发 action
<template><button @click="increment">Increment</button>
</template><script>
import { mapActions } from 'vuex'export default {methods: {...mapActions(['increment'])}
}
</script>
  • 使用 getters
<template><div>Double Count: {{ doubleCount }}</div>
</template><script>
import { mapGetters } from 'vuex'export default {computed: {...mapGetters(['doubleCount'])}
}
</script>
4.3 模块化
// store/modules/user.js
export default {namespaced: true,state: {username: ''},mutations: {setUsername(state, username) {state.username = username}},actions: {setUsername({ commit }, username) {commit('setUsername', username)}},getters: {username: (state) => state.username}
}
// store/index.js
import { createStore } from 'vuex'
import user from './modules/user'export default createStore({modules: {user}
})
// 使用模块中的 state, mutation, action, getter
<template><div>Username: {{ username }}</div><button @click="setUsername('Alice')">Set Username</button>
</template><script>
import { mapState, mapMutations, mapActions, mapGetters } from 'vuex'export default {computed: {...mapState('user', ['username']),...mapGetters('user', ['username'])},methods: {...mapMutations('user', ['setUsername']),...mapActions('user', ['setUsername'])}
}
</script>

五、组合式 API

5.1 setup 函数
<template><div>{{ count }}</div><button @click="increment">Increment</button>
</template><script>
import { ref } from 'vue'export default {setup() {const count = ref(0)const increment = () => {count.value++}return {count,increment}}
}
</script>
5.2 响应式数据
  • ref
const count = ref(0)
  • reactive
const state = reactive({count: 0,user: {name: 'Alice'}
})
  • computed
const doubleCount = computed(() => count.value * 2)
  • watch
watch(count, (newVal, oldVal) => {console.log(`count changed from ${oldVal} to ${newVal}`)
})
5.3 生命周期钩子
  • onMounted
onMounted(() => {console.log('mounted')
})
  • onUnmounted
onUnmounted(() => {console.log('unmounted')
})
  • 其他钩子: onBeforeMount, onBeforeUnmount, onActivated, onDeactivated, onErrorCaptured, onRenderTracked, onRenderTriggered

六、其他常用功能

6.1 指令
  • v-bind
<img v-bind:src="imageSrc" />
  • v-model
<input v-model="message" />
  • v-if, v-else-if, v-else
<div v-if="isLoggedIn">Welcome!</div>
<div v-else>Please log in.</div>
  • v-for
<ul><li v-for="item in items" :key="item.id">{{ item.name }}</li>
</ul>
  • v-on 修饰符

    • .stop:阻止事件冒泡

      <button @click.stop="handleClick">Click</button>
      
    • .prevent:阻止默认事件

      <form @submit.prevent="handleSubmit"></form>
      
    • .once:事件只触发一次

      <button @click.once="handleClick">Click</button>
      
    • .self:只有事件是从元素本身触发时才触发处理函数

      <div @click.self="handleClick"><button>Click</button>
      </div>
      
    • 按键修饰符

      <input @keyup.enter="submit" />
      
  • v-for 进阶用法

    • 遍历对象

      <ul><li v-for="(value, key, index) in object" :key="key">{{ index }} - {{ key }}: {{ value }}</li>
      </ul>
      
    • 遍历数字范围

      <div v-for="n in 10" :key="n">{{ n }}</div>
      
    • 使用 v-fortemplate 结合

      <ul><template v-for="item in items" :key="item.id"><li>{{ item.name }}</li><li class="divider" role="presentation"></li></template>
      </ul>
      
  • v-slot 插槽

    • 具名插槽

      <!-- 子组件 -->
      <slot name="header"></slot>
      <slot></slot>
      <slot name="footer"></slot>
      
      <!-- 父组件 -->
      <ChildComponent><template #header><h1>Header</h1></template><p>默认插槽内容</p><template #footer><p>Footer</p></template>
      </ChildComponent>
      
    • 作用域插槽

      <!-- 子组件 -->
      <slot :user="user"></slot>
      
      <!-- 父组件 -->
      <ChildComponent v-slot:default="slotProps"><p>{{ slotProps.user.name }}</p>
      </ChildComponent>
      
6.2 过渡与动画
  • 单元素过渡

    <transition name="fade"><div v-if="isVisible">Hello</div>
    </transition>
    
    .fade-enter-active, .fade-leave-active {transition: opacity 0.5s;
    }
    .fade-enter-from, .fade-leave-to {opacity: 0;
    }
    
  • 列表过渡

    <transition-group name="list" tag="ul"><li v-for="item in items" :key="item.id">{{ item.name }}</li>
    </transition-group>
    
    .list-enter-active, .list-leave-active {transition: all 0.5s;
    }
    .list-enter-from, .list-leave-to {opacity: 0;transform: translateY(30px);
    }
    
  • 使用 JavaScript 钩子

    <transition @before-enter="beforeEnter" @enter="enter" @leave="leave"><div v-if="isVisible">Hello</div>
    </transition>
    
    export default {methods: {beforeEnter(el) {el.style.opacity = 0},enter(el, done) {Velocity(el, { opacity: 1, fontSize: '1.4em' }, { duration: 300, complete: done })},leave(el, done) {Velocity(el, { opacity: 0, fontSize: '1em' }, { duration: 300, complete: done })}}
    }
    
6.3 混入(Mixin)
  • 定义混入

    // mixins/log.js
    export default {created() {console.log('Mixin created')},methods: {log(message) {console.log(message)}}
    }
    
  • 使用混入

    <script>
    import logMixin from './mixins/log'export default {mixins: [logMixin],created() {this.log('Hello from component')}
    }
    </script>
    
6.4 自定义指令
  • 定义自定义指令

    // directives/focus.js
    export default {mounted(el) {el.focus()}
    }
    
  • 注册全局指令

    import { createApp } from 'vue'
    import App from './App.vue'
    import focusDirective from './directives/focus'const app = createApp(App)
    app.directive('focus', focusDirective)
    app.mount('#app')
    
  • 使用自定义指令

    <input v-focus />
    
6.5 插件
  • 创建插件

    // plugins/logger.js
    export default {install(app, options) {console.log(options)app.config.globalProperties.$logger = (message) => {console.log(message)}}
    }
    
  • 使用插件

    // main.js
    import { createApp } from 'vue'
    import App from './App.vue'
    import loggerPlugin from './plugins/logger'const app = createApp(App)
    app.use(loggerPlugin, { someOption: 'someValue' })
    app.mount('#app')
    
    // 在组件中使用
    export default {mounted() {this.$logger('Hello from plugin')}
    }
    

七、Vue3 新特性

7.1 Teleport
  • 使用 Teleport 将组件内容渲染到指定位置

    <!-- App.vue -->
    <div><h1>App</h1><Teleport to="body"><div id="modal"><p>Modal Content</p></div></Teleport>
    </div>
    
7.2 Suspense
  • 使用 Suspense 处理异步组件

    <template><Suspense><template #default><AsyncComponent /></template><template #fallback><div>Loading...</div></template></Suspense>
    </template>
    
  • 异步组件示例

    // components/AsyncComponent.vue
    <template><div>Async Component</div>
    </template><script>
    export default {async setup() {// 模拟异步操作await new Promise((resolve) => setTimeout(resolve, 2000))return {}}
    }
    </script>
    
    <!-- 使用 Suspense 包裹异步组件 -->
    <template><Suspense><template #default><AsyncComponent /></template><template #fallback><div>Loading...</div></template></Suspense>
    </template>
    
  • 错误处理

    <template><Suspense><template #default><AsyncComponent /></template><template #fallback><div>Loading...</div></template><template #error><div>Error occurred!</div></template></Suspense>
    </template>
    
    // components/AsyncComponent.vue
    <script>
    export default {async setup() {await new Promise((_, reject) => setTimeout(() => reject(new Error('Async Error')), 2000))}
    }
    </script>
    
7.3 Fragment
  • Vue3 支持组件返回多个根节点,无需再使用包裹元素

    <template><header>Header</header><main>Main Content</main><footer>Footer</footer>
    </template>
    
7.4 组合式 API 进阶
  • 响应式 API

    • reactive:创建响应式对象

      import { reactive } from 'vue'const state = reactive({count: 0,user: {name: 'Alice'}
      })
      
    • ref:创建响应式引用

      import { ref } from 'vue'const count = ref(0)
      
    • computed:创建计算属性

      import { ref, computed } from 'vue'const count = ref(0)
      const doubleCount = computed(() => count.value * 2)
      
    • watch:监听数据变化

      import { ref, watch } from 'vue'const count = ref(0)
      watch(count, (newVal, oldVal) => {console.log(`count changed from ${oldVal} to ${newVal}`)
      })
      
  • 生命周期钩子

    • onMounted:组件挂载完成后调用

      import { onMounted } from 'vue'onMounted(() => {console.log('mounted')
      })
      
    • onUnmounted:组件卸载后调用

      import { onUnmounted } from 'vue'onUnmounted(() => {console.log('unmounted')
      })
      
    • 其他钩子:onBeforeMount, onBeforeUnmount, onActivated, onDeactivated, onErrorCaptured, onRenderTracked, onRenderTriggered

  • 依赖注入

    • provideinject

      // 父组件
      import { provide, ref } from 'vue'const theme = ref('dark')
      provide('theme', theme)
      
      // 子组件
      import { inject, onMounted } from 'vue'const theme = inject('theme')
      onMounted(() => {console.log(`Theme is ${theme.value}`)
      })
      
  • 自定义 Hooks

    • 创建可复用的组合式函数

      // hooks/useMousePosition.js
      import { ref, onMounted, onUnmounted } from 'vue'export function useMousePosition() {const x = ref(0)const y = ref(0)const updatePosition = (e) => {x.value = e.pageXy.value = e.pageY}onMounted(() => {window.addEventListener('mousemove', updatePosition)})onUnmounted(() => {window.removeEventListener('mousemove', updatePosition)})return { x, y }
      }
      
      // 使用自定义 Hook
      import { useMousePosition } from '../hooks/useMousePosition'export default {setup() {const { x, y } = useMousePosition()return { x, y }}
      }
      

八、性能优化

8.1 组件懒加载
  • 使用动态导入实现组件懒加载

    const Home = () => import('./views/Home.vue')
    const routes = [{ path: '/', component: Home }
    ]
    
8.2 避免不必要的渲染
  • 使用 v-once 渲染静态内容

    <div v-once>{{ message }}</div>
    
  • 使用 shallowRefshallowReactive 避免深层响应式

    import { shallowRef } from 'vue'const data = shallowRef({ count: 0 })
    

在这里插入图片描述

http://www.lryc.cn/news/481513.html

相关文章:

  • 结构体是否包含特定类型的成员变量
  • 堆排序与链式二叉树:数据结构与排序算法的双重探索
  • 用 Python 从零开始创建神经网络(四):激活函数(Activation Functions)
  • 使用 Flask 和 ONLYOFFICE 实现文档在线编辑功能
  • 【C++】【算法基础】序列编辑距离
  • 【Android】轮播图——Banner
  • 学SQL,要安装什么软件?
  • webstorm 设置总结
  • 基于Spring Boot的养老保险管理系统的设计与实现,LW+源码+讲解
  • Java | Leetcode Java题解之第541题反转字符串II
  • sql分区
  • [OpenGL]使用OpenGL实现硬阴影效果
  • 嵌入式采集网关(golang版本)
  • ctfshow(328)--XSS漏洞--存储型XSS
  • 【C#】Thread.CurrentThread的用法
  • 简单分享一下淘宝商品数据自动化抓取的技术实现与挑战
  • Netty篇(入门编程)
  • 【渗透测试】payload记录
  • 2024自动驾驶线控底盘行业研究报告
  • css3D变换用法
  • Rust:启动与关闭线程
  • Ubuntu 的 ROS 2 操作系统安装与测试
  • 在双显示器环境中利用Sunshine与Moonlight实现游戏串流的同时与电脑其他任务互不干扰
  • ElasticSearch备考 -- Cross cluster replication(CCR)
  • windows C#-异常处理
  • 边缘计算在智能制造中的应用
  • 点云开发:从入门到精通的全面教程
  • 【含文档】基于ssm+jsp的商店会员系统(含源码+数据库+lw)
  • 【大数据学习 | kafka高级部分】文件清除原理
  • dolphin 配置data 从文件导入hive 实践(一)