vue的增量式学习-篇章3,又名:写毕设到企业级前端(第6天)
概念:Props 是从父组件传递数据到子组件的一种机制,用于实现组件之间的通信。父组件可以将数据传递给子组件,并在子组件中使用这些数据。
应用场景:使用 Props 来将数据从父组件传递给子组件,以便在子组件中显示、处理或修改这些数据。
示例代码:
<!-- 父组件 -->
<template>
<child-component :message="parentMessage"></child-component>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent,
},
data() {
return {
parentMessage: 'Hello from parent!',
};
},
};
</script>
<!-- 子组件 (ChildComponent.vue) -->
<template>
<div>{{ message }}</div>
</template>
<script>
export default {
props: ['message'],
};
</script>
概念:事件允许组件在特定的交互或状态变化时发出通知,以便其他组件能够响应并执行相应的操作。Vue 使用 @
或 v-on
来监听和处理事件。
应用场景:使用事件来实现组件之间的通信,例如在子组件中触发事件,然后父组件监听并响应该事件。
示例代码:
<!-- 子组件 -->
<template>
<button @click="sendMessage">Send Message</button>
</template>
<script>
export default {
methods: {
sendMessage() {
this.$emit('message-sent', 'Hello from child!');
},
},
};
</script>
<!-- 父组件 -->
<template>
<div>
<child-component @message-sent="receiveMessage"></child-component>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent,
},
methods: {
receiveMessage(message) {
console.log('Received message:', message);
},
},
};
</script>
概念:v-model
是 Vue 中的语法糖,用于双向绑定数据。它允许父组件通过 v-model
在子组件上进行属性绑定,并监听子组件的事件来更新数据。
应用场景:使用 v-model
来实现父组件与子组件之间的双向数据绑定。
示例代码:
<!-- 子组件 -->
<template>
<input :value="value" @input="$emit('input', $event)">
</template>
<script>
export default {
props: ['value'],
};
</script>
<!-- 父组件 -->
<template>
<div>
<child-component v-model="message"></child-component>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent,
},
data() {
return {
message: 'Hello from parent!',
};
},
};
</script>
概念:
在 Vue 中,当你使用一个自定义组件时,该组件的根元素是由组件自身的模板定义的。然而,有时你可能希望将一些额外的 HTML 属性传递给组件的根元素,以确保组件能够正常工作或与其他库/框架集成。
示例代码解释:
假设你有一个自定义按钮组件 CustomButton
,它接受一个 type
属性,并且应该将这个属性应用到按钮元素上。但你不希望在组件的模板中显式地定义 type
属性,而是希望该属性能够透传给组件的根元素。
以下是 CustomButton
组件的示例代码:
<!-- CustomButton.vue -->
<template>
<button :class="computedClass" v-bind="$attrs">
<slot></slot>
</button>
</template>
<script>
export default {
computed: {
computedClass() {
// 根据组件的逻辑计算按钮的 class
},
},
};
</script>
在这个示例中:
<button>
元素上使用了 v-bind="$attrs"
,这表示将所有未在组件中处理的属性透传给按钮元素。CustomButton
:<template>
<div>
<!-- 使用 CustomButton 组件,透传 type 属性 -->
<CustomButton type="submit">Submit</CustomButton>
</div>
</template>
在这个示例中,type
属性将会传递给 CustomButton
组件的根元素 <button>
,确保它被正确设置为 "submit"
。
这种透传属性的机制使得自定义组件更加灵活,能够与外部环境集成,并确保不会丢失传递给组件的属性。
概念:插槽是一种将内容插入组件内部的机制,允许父组件向子组件传递内容,并控制内容的显示位置。
应用场景:使用插槽来自定义组件的内容,使组件更灵活,适应不同的用例。
示例代码:
<!-- Card.vue -->
<template>
<div class="card">
<div class="card-header">
<!-- 默认插槽 -->
<slot></slot>
</div>
<div class="card-body">
<!-- 具名插槽,命名为 "content" -->
<slot name="content"></slot>
</div>
</div>
</template>
<!-- 使用 Card 组件 -->
<template>
<div>
<card>
<!-- 默认插槽的内容 -->
<p>This is a default slot content.</p>
<!-- 具名插槽的内容 -->
<template v-slot:content>
<p>This is a custom content for the "content" slot.</p>
</template>
</card>
</div>
</template>
<script>
import Card from './Card.vue';
export default {
components: {
Card,
},
};
</script>
provide
和 inject
,示例较为复杂,可根据具体需求编写。<!-- ThemeConfig.vue -->
<template>
<div>
<!-- 使用 provide 注入主题配置 -->
<provide :themeConfig="themeConfig">
<slot></slot>
</provide>
</div>
</template>
<script>
export default {
data() {
return {
themeConfig: {
primaryColor: 'blue',
secondaryColor: 'green',
},
};
},
};
</script>
<!-- ThemeButton.vue -->
<template>
<button :style="{ backgroundColor: themeConfig.primaryColor }">
Click me
</button>
</template>
<script>
export default {
inject: ['themeConfig'],
};
</script>
有两个组件:Home.vue
和About.vue
,并且您想按需加载About.vue
组件。
首先,创建一个About.vue
组件,内容如下:
<template>
<div>
<h1>About Page</h1>
<p>This is the about page.</p>
</div>
</template>
接下来,在您的路由配置中,确保您使用了Webpack的import()
函数来动态导入About.vue
组件。假设您正在使用Vue Router来进行路由配置,您的路由配置可能如下所示:
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [
{
path: '/',
component: () => import('./views/Home.vue') // 首页组件是同步加载的
},
{
path: '/about',
component: () => import(/* webpackChunkName: "about" */ './views/About.vue') // 异步加载About组件
}
]
const router = new VueRouter({
routes
})
export default router
在上面的代码中,About.vue
组件是使用import()
函数进行异步加载的。Webpack会将它打包成一个独立的文件,只有在用户首次访问该路由时才会加载。
最后,您可以在您的应用中使用<router-link>
标签来导航到/about
路由,触发异步加载:
<template>
<div>
<h1>Home Page</h1>
<p>This is the home page.</p>
<router-link to="/about">Go to About Page</router-link>
</div>
</template>
这就是一个简单的异步组件的案例。当用户点击“Go to About Page”链接时,Vue会按需加载About.vue
组件,而不是在应用加载时立即加载它。这有助于减小初始包的大小,提高应用性能。
请注意,上述示例中的路由配置可能基于Vue Router的使用方式。确保您的项目中有适当的Vue Router配置和Webpack设置以支持异步组件加载:
Vue Router 配置:
在Vue Router中,您需要使用import()
函数来动态导入组件,并将其配置为路由的component
属性。这告诉Vue Router按需加载组件。
const routes = [
{
path: '/',
component: () => import('./views/Home.vue') // 同步加载
},
{
path: '/about',
component: () => import(/* webpackChunkName: "about" */ './views/About.vue') // 异步加载
}
]
请注意,上面的示例中,我们使用了注释/* webpackChunkName: "about" */
来指定Webpack生成的异步组件的名称。这是可选的,但可以帮助您在生成的文件中更好地识别异步组件。
Webpack 配置:
您不必手动更改Webpack的配置文件,因为Vue CLI(如果您使用它来创建Vue项目)已经为您配置了异步组件加载的设置。Webpack会自动生成异步加载的代码块。
如果您不使用Vue CLI,而是手动配置Webpack,确保您的Webpack配置中启用了splitChunks
插件或类似的功能,以便将异步组件打包成单独的文件。
以下是一个可能的Webpack配置示例(要根据您的实际项目进行调整):
// webpack.config.js
const path = require('path');
module.exports = {
// ...其他配置...
optimization: {
splitChunks: {
chunks: 'all'
}
}
};
这个配置将帮助Webpack将异步组件打包到单独的文件中,以便按需加载。
确保您的Vue Router和Webpack配置都正确设置,以使异步组件按预期工作。
我会继续为其他主题提供概念、场景和示例代码。如果你有任何疑问或需要更多信息,请告诉我。
<!-- 逻辑复用示例 -->
<template>
<div>
<p>{{ greet('John') }}</p>
</div>
</template>
<script>
export default {
setup() {
// 通用逻辑函数
const greet = (name) => {
return Hello, ${name}!;
};
return {
greet,
};
},
};
</script>
ref
、reactive
、computed
等。假设您有一个需求:在多个组件中需要计算两个数字的和。您可以创建一个组合式函数来处理此逻辑。
首先,在您的项目中创建一个名为useAddition
的组合式函数:
// useAddition.js
import { ref } from 'vue';
// 创建一个可重用的组合式函数,用于计算两个数字的和
export function useAddition() {
// 定义两个响应式变量,用于存储数字
const num1 = ref(0);
const num2 = ref(0);
// 创建计算和的函数
function calculateSum() {
return num1.value + num2.value;
}
// 返回响应式变量和计算函数
return {
num1,
num2,
calculateSum,
};
}
接下来,您可以在任何需要计算两个数字的和的组件中使用这个组合式函数。
<template>
<div>
<h2>Calculate Sum</h2>
<input v-model="num1" type="number" />
<input v-model="num2" type="number" />
<p>Sum: {{ calculateSum() }}</p>
</div>
</template>
<script>
import { useAddition } from './useAddition'; // 导入组合式函数
export default {
setup() {
const { num1, num2, calculateSum } = useAddition(); // 使用组合式函数
return {
num1,
num2,
calculateSum,
};
},
};
</script>
在上面的示例中,我们导入了useAddition
组合式函数,并在组件的setup
函数中使用它。然后,我们可以在模板中访问num1
和num2
两个响应式变量,并通过调用calculateSum
函数来计算它们的和。
通过这种方式,您可以在多个组件中轻松地共享和重用计算和的逻辑,使代码更加可维护和清晰。这是Vue 3中组合式函数的一个示例,您可以根据自己的需求创建更多的组合式函数来封装逻辑。
概念:自定义指令是一种允许你扩展 Vue 的模板语法的方式,可以用于处理 DOM 元素的行为、样式、事件等。
应用场景:使用自定义指令来创建可复用的DOM操作或样式绑定功能,或在特定情况下修改DOM元素的行为。
示例代码:
<!-- 自定义指令的使用 -->
<template>
<div>
<p v-highlight="'yellow'">Highlight this text</p>
</div>
</template>
<script>
// 注册自定义指令
Vue.directive('highlight', {
bind(el, binding) {
el.style.backgroundColor = binding.value;
},
});
export default {
// 组件逻辑
};
</script>
概念:
<transition>
是 Vue 内置的过渡组件,用于在元素进入或离开 DOM 的时候,在不同状态间切换过渡效果。它通过在元素上添加/删除 CSS 类名来实现过渡效果。
应用场景:
实例代码:
<template>
<div>
<button @click="toggle">Toggle</button>
<transition name="fade" appear>
<p v-if="show">This is a transition example.</p>
</transition>
</div>
</template>
<script>
export default {
data() {
return {
show: false,
};
},
methods: {
toggle() {
this.show = !this.show;
},
},
};
</script>
<style>
.fade-enter-active, .fade-leave-active {
transition: opacity 0.5s;
}
.fade-enter, .fade-leave-to {
opacity: 0;
}
</style>
概念:
<transition-group>
是 Vue 内置的过渡组件,用于在多个元素间切换过渡效果。它通常与 v-for
一起使用,实现列表中元素的增删时的过渡效果。
应用场景:
实例代码:
<template>
<div>
<button @click="addItem">Add Item</button>
<transition-group name="list" tag="ul">
<li v-for="(item, index) in items" :key="index">{{ item }}</li>
</transition-group>
</div>
</template>
<script>
export default {
data() {
return {
items: [],
nextItem: 1,
};
},
methods: {
addItem() {
this.items.push(this.nextItem++);
},
},
};
</script>
<style>
.list-enter-active, .list-leave-active {
transition: opacity 0.5s, transform 0.5s;
}
.list-enter, .list-leave-to /* .list-leave-active in <2.1.8 */ {
opacity: 0;
transform: translateY(30px);
}
</style>
概念:
<keep-alive>
是 Vue 内置的组件缓存组件,用于保留已经渲染的组件实例,以避免重新渲染。这在路由切换时可以保持组件状态。
应用场景:
实例代码:
<template>
<div>
<button @click="toggleComponent">Toggle Component</button>
<keep-alive>
<my-component v-if="showComponent" />
</keep-alive>
</div>
</template>
<script>
import MyComponent from './MyComponent.vue';
export default {
components: {
MyComponent,
},
data() {
return {
showComponent: false,
};
},
methods: {
toggleComponent() {
this.showComponent = !this.showComponent;
},
},
};
</script>
概念:
<teleport>
是 Vue 内置的传送门组件,用于将组件的内容渲染到指定的 DOM 节点上,而不受当前组件的限制。这可以用于在组件外部渲染弹出框、对话框等内容。
应用场景:
实例代码:
<template>
<div>
<button @click="toggleDialog">Toggle Dialog</button>
<teleport to="#dialog">
<my-dialog v-if="showDialog" />
</teleport>
</div>
</template>
<script>
import MyDialog from './MyDialog.vue';
export default {
components: {
MyDialog,
},
data() {
return {
showDialog: false,
};
},
methods: {
toggleDialog() {
this.showDialog = !this.showDialog;
},
},
};
</script>
概念:
<suspense>
是 Vue 内置的组件,用于处理异步组件加载和渲染时的等待和错误处理。
应用场景:
实例代码:
<template>
<div>
<suspense>
<template #default>
<my-async-component />
</template>
<template #fallback>
<p>Loading...</p>
</template>
</suspense>
</div>
</template>
<script>
const MyAsyncComponent = () => import('./MyAsyncComponent.vue');
export default {
components: {
MyAsyncComponent,
},
};
</script>
概念:
单文件组件(SFC)是一种将组件的模板、脚本和样式封装在一个文件中的方式,以便更好地组织和维护组件。
应用场景:
实例代码: