Vue组件
组件的概念和分类
- 组件具有复用性,但是复用的组件之间的数据是独立的
这也解释为什么
data
被声明为一个函数再返回一个对象
- 局部组件与全局组件
全局组件只要定义,处处皆可使用,使用简单性能较差;局部组件,定义后需要引入才能使用,使用复杂,性能高于全局组件
Vue.component('counter', {
data () {
return {
count: 1
}
},
template: `<div @click="count += 1">{{count}}</div>`
})
// 局部组件
const DivCounter = {
data () {
return {
count: 2
}
},
template: `<div @click="count +=1">{{count}}</div>`
}
const app = new Vue({
el: "#app",
components: {
DivCounter
},
template: `<div>
<counter/>
<DivCounter/>
</div>`
});
父组件向子组件传值
- 基础用法
const DivCounter = {
// 使用props接收传递的值
props: ["count"],
template: `<div>{{count}}</div>`
}
const app = new Vue({
el: "#app",
data() {
return {
count: 1
}
},
components: {
DivCounter
},
template: `<div>
// 引入子组件时动态绑定参数值和参数名称(参数名称就是props中接收的名称)
<DivCounter :count="count"/>
</div>`
});
props
可以接收的参数类型包含:String、Boolean、Array、Object、Fuction、Symbol
,使用时一般的值如同使用自己的data
的方法,函数如同使用自己的methods
中的方法
props的几种形式
// 1.最简化的方式-->数组
props:["count"]
// 2. 对象只规定类型
props: {
count:Number
}
// 3. 对象严格规定
props:{
count: {
type: xxx,
required: true/false,
default: xxx,
validator: func
}
}
单向数据流
通过props传递给子组件的数据不能被子组件修改,原因很简单,一个父组件可以对应多个子组件它的数据可能被用于自身及其他多个子组件,如果简单的在一个子组件中修改,可能会影响其它组件
- 解决方案一
props: ["count"],
data () {
return {
myCount: this.count, // 复制一份
}
}
Non_props
- 基础用法
类似于
props
绑定,但是没有props
那么会以属性的形式绑定在子组件的最外层,通过inheritAttrs: fasle
阻止绑定
const DivCounter = {
template: `<div><div>myCount</div></div>`
}
const app = new Vue({
el: "#app",
data() {
return {
count: 1
}
},
components: {
DivCounter
},
template: `<div>
<DivCounter count="count"/>
</div>`
});
$attrs
可以将属性或属性的一部分绑定在子组件的任意一个元素上
const DivCounter = {
template: `<div><div v-bind="$attrs">myCount</div></div>`
// template: `<div><div :count="$attrs.count">myCount</div></div>` 只使用count
// 其余地方使用
// mounted () {
// console.log(this.$attrs.count);
// }
}
const app = new Vue({
el: "#app",
data() {
return {
count: 1
}
},
components: {
DivCounter
},
template: `<div>
<DivCounter count="count" hello="data" class="hello" style="color: red;"/>
</div>`
});
子组件向父组件传递信息
$emit
const DivCounter = {
props: ["count"],
methods: {
handleItemClick () {
// 2. 向父组件传递一个自定义事件和参数
this.$emit("addOne", 2)
}
},
// 1. 绑定触发的函数
template: `<div @click="handleItemClick">{{count}}</div>`,
}
const app = new Vue({
el: "#app",
data() {
return {
count: 1
}
},
components: {
DivCounter
},
methods: {
handleAddOne(param) {
this.count += param;
}
},
// 3. 触发父组件中的事件
template: `<div>
<DivCounter :count="count" @addOne="handleAddOne"/>
</div>`
});
插槽slot
方便传递一些标签组件的插入
- 一般用法
const DivCounter = {
template: `
<form>
<input />
<slot><slot>
</form>
`,
}
const app = new Vue({
el: "#app",
data() {
return {
count: 1
}
},
components: {
DivCounter
},
template: `<div>
<DivCounter>
<button>按钮</button>
</DivCounter>
<DivCounter>
<div>div</div>
</DivCounter>
</div>`
});
值得注意的是
slot
无法绑定事件,需要绑定事件可以在外包裹一层标签
- 具名插槽
// 1. 具名插槽用template包裹(v-slot可以简写为#)
<template v-slot:header>
<div>header</div>
</template>
// 2. 使用
<slot name="header"></slot>
- 作用域插槽
父组件决定子组件的
slot
为什么dom
元素,但是其中的值是由子组件的data
决定的,一般{{}}
中的值只能在其本身所在的组件内部的data
中获取
const List = {
data() {
return {
items: [1, 2, 3],
}
},
template: `
<div>
<slot v-for="item in items" :item="item"/>
</div>
`,
}
const app = new Vue({
el: "#app",
data() {
return {}
},
components: {
List
},
template: `
<List v-slot="slotProps">
<div>{{slotProps.item}}</div>
</List>
`
});
动态组件
- 基础用法
动态组件
<components :is="" />
通过数据动态决定渲染的组件
const Com1 = {
template: `<input />`,
}
const Com2 = {
template: `<div>这是组件二号</div>`,
}
const app = new Vue({
el: "#app",
data () {
return {
currentItem: "Com1"
}
},
components: {
Com1,
Com2
},
methods: {
handleClick () {
this.currentItem === 'Com1' ? this.currentItem = 'Com2': this.currentItem = 'Com1';
}
},
template: `<div>
<component :is="currentItem" />
<button @click="handleClick">切换</button>
</div>`
});
keep-alive
keep-alive
嵌套于动态组件的外层,决定其切换时是否被销毁,同时监听切换事件
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!