一,组件理论
二,组件使用
以下代码都是案例,可以跟着做一遍
- 组件目录 src/components
- 创建 src/components/OneCom.vue 文件
1、组件基础
# 1、`App.vue` 文件中,引入组件
<template>
<div>欧阳克</div>
// 4、使用组件里的html代码,这里的标签名 跟 key 对应上
<OneCom></OneCom>
<one-com></one-com>
// 5、一般组件会起驼峰命名,比如:OneCom,TwoCom。
// 5.1、引入的后,标签可以使用2种方式:<OneCom></OneCom>、<two-com></two-com>
</template>
<script>
// 1、导入组件
import OneCom from './components/OneCom';
export default {
// 2、组件加入,也是使用组件
components:{
// 3、键盘随便起,value就是上面引入的名字
OneCom : OneCom,
// 如果key和value名字一样,可以写一个
OneCom
},
data() {
return {
};
},
methods:{
}
};
</script>
# 2、`OneCom.vue` 文件
<template>
<div>OneCom组件文件</div>
</template>
<script>
export default {
name : "OneCom"
};
</script>
# 3、子组件 使用 子组件
# 3.1、创建`TwoCom.vue` 文件
<template>
<div>TwoCom组件文件</div>
</template>
<script>
export default {
name : "TwoCom"
};
</script>
# 3.2、OneCom 文件引入 TwoCom 文件
<template>
<div>OneCom组件文件</div>
// 3、使用TwoCom标签
<two-com></two-com>
</template>
<script>
// 1、引入 TwoCom 文件,2个子组件在同一个目录
import TwoCom from './TwoCom';
export default {
name : "OneCom",
// 2、使用 TwoCom 组件
components:{
TwoCom
},
};
</script>
# 4、一个文件可以引入多个组件
<template>
<div>
<div>欧阳克</div>
<one-com></one-com>
<two-com></two-com>
</div>
</template>
<script>
import OneCom from "./components/OneCom.vue";
import TwoCom from "./components/TwoCom.vue";
export default {
components: {
OneCom,
TwoCom,
},
data() {
return {};
},
};
</script>
2.组件之间数据交互
# 1、父传子,属性传值
# 1.1、App.vue 文件
<template>
<div>欧阳克</div>
// 普通传值,key和value
<one-com title="php中文网"></one-com>
// 绑定变量传值
<one-com :title="title" :msg="msg"></one-com>
</template>
<script>
import OneCom from "./components/OneCom.vue";
export default {
name: "Phpcn",
data() {
return {
title: "使用变量的方式传值",
msg: "消息",
};
},
components:{
OneCom : OneCom
}
};
</script>
# 1.2、components/OneCom.vue 子文件
# 1.2.1、props 参数,获取父文件的传值
<template>
<div>
<div>{{ title }}</div>
<div>{{ msg }}</div>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
};
},
props: ["title", "msg"],
};
</script>
# 1.3、还可以传数组,App.vue文件
<script>
import OneCom from "./components/OneCom.vue";
export default {
data() {
return {
title : [
'欧阳克',
'朱天蓬',
'灭绝师太'
],
msg: "消息",
};
},
components:{
OneCom : OneCom
}
};
</script>
# 1.4、接收还可以限制参数,要改为对象。OneCom文件,自定义key
# 1.4.1、type 接收数据,类型:String,Array,
# 1.4.2、default 父文件没有传值,自己会给个默认值
# 1.4.3、required 等于true,就是必传的值
<template>
<div>
<one-com :title="title" :msg="msg" :ob="ob"></one-com>
</div>
</template>
<script>
import OneCom from "./components/OneCom.vue";
export default {
components: {
OneCom,
},
data() {
return {
title: ["欧阳克", "朱天蓬"],
msg: "消息",
ob: {
name: "欧阳克",
age: "38岁"
}
};
},
};
</script>
// OneCom文件
<template>
<div>
<div>{{ title }}</div>
<div>{{ msg }}</div>
<div>{{ ob }}</div>
</div>
</template>
<script>
export default {
data() {
return {};
},
// 数组和对象,要用方法返回。没有语法检查,就可以直接写对应的格式
props: {
title: {
type: Array,
default: function () {
return ["灭绝师太", "西门大官人"];
},
required : true
},
msg: {
type: String,
default: "默认msg",
},
ob: {
type: Object,
default: function () {
return { name: "朱天蓬", age: "48岁" };
}
},
}
};
</script>
# 2、子传父,事件传值 (2个子组件,tabBar 点击tabBar,另一个子组件里的数据要改变,就要经过父组件)
// App.vue文件
<template>
<div>{{teacher}}</div>
<one-com @app_edit="app_edit"></one-com>
</template>
<script>
import OneCom from './components/OneCom';
export default {
data() {
return {
teacher : "欧阳克"
};
},
components: {
OneCom,
},
methods : {
app_edit(e){
console.log('我是父文件的app_edit方法');
this.teacher = e;
}
}
};
</script>
// components/OneCom.vue 子文件
// 使用 $emit 方法,调用父文件的方法(https://v3.cn.vuejs.org/api/instance-methods.html#emit)
// 所有子传父,都是通过事件传过去的
<template>
<div>
<button @click="edit('朱天蓬')">传给父文件</button>
<button @click="edit('灭绝师太')">传给父文件</button>
</div>
</template>
<script>
export default {
data() {
return {
};
},
methods : {
edit(teacher){
console.log('我是子文件的edit方法');
this.$emit('app_edit',teacher);
}
}
};
</script>
3.父子组件之间相互访问
# 1、子组件调用父组件的方法:$parent 或 $root
// App.vue文件
<template>
<one-com></one-com>
</template>
<script>
import OneCom from './components/OneCom';
export default {
data() {
return {
};
},
components: {
OneCom
},
methods : {
app_fun() {
console.log("我是app.vue文件的app_fun方法");
}
}
};
</script>
// components/OneCom.vue 子文件
<template>
<div>{{ one_fun() }}</div>
</template>
<script>
export default {
data() {
return {};
},
methods: {
one_fun() {
console.log("我是子组件的one_fun方法");
// 使用 $parent 访问父组件, 在使用.app_func找到方法
this.$parent.app_fun();
// 使用 $parent.$parent 访问多层组件,$parent代表1层
this.$parent.$parent.app_fun();
// 使用 $root 访问最顶层的文件,$root 根节点,可以把这个代码放到 TwoCom.vue 文件里测试
this.$root.app_fun();
}
}
};
</script>
# 2、父组件调用子组件的方法:$refs
// components/OneCom.vue 子文件
<template>
<div>子组件</div>
</template>
<script>
export default {
data() {
return {};
},
methods: {
one_fun() {
console.log("我是子组件的one_fun方法");
}
}
};
</script>
// app.vue 文件
<template>
<div>
// 子组件要先起个别名
<one-com ref="one" @click="app_fun()"></one-com>
</div>
</template>
<script>
import OneCom from "./components/OneCom";
export default {
data() {
return {};
},
components: {
OneCom
},
methods: {
app_fun() {
// 通过 $refs 访问子组件,one找到别名子组件,在使用.one_fun找到方法
this.$refs.one.one_fun();
console.log("我是app.vue文件的app_fun方法");
}
}
};
</script>
4.插槽
- 插槽可以实现组件的扩展性,抽取共性,保留不同
- 插槽就相当于函数的传值
# 1、使用 slot 标签,做为占位:也叫插槽
// components/OneCom.vue 子文件
<template>
<div>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<slot></slot>
</div>
</template>
// App.vue文件
<template>
<div>
// 使用子组件,传button标签
<one-com>
<button>按钮</button>
</one-com>
// 使用子组件,传a标签
<one-com>
<a>a链接</a>
</one-com>
</div>
</template>
<script>
import OneCom from "./components/OneCom";
export default {
data() {
return {};
},
components: {
OneCom
}
};
</script>
# 2、插槽命名:如果多个插槽,传2次按钮,会出现4个按钮,所以要用命名的方法
// components/OneCom.vue 子文件
<template>
<div>
<slot></slot>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
// 使用name参数,给插槽起名
<slot name="two"></slot>
</div>
</template>
// App.vue文件
<template>
<div>
<one-com>
<button>按钮</button>
// 使用 template 标签,v-slot参数,找到有名字的插槽
<template v-slot:two>
<button>按钮</button>
</template>
</one-com>
<one-com>
<a>a链接</a>
// 也可以#简写,是v-slot的语法糖
<template #two>
<a>a链接</a>
</template>
</one-com>
<one-com>
// 还可以找没有名字的插槽
<template v-slot:default>
<a>a标签</a>
</template>
</one-com>
</div>
</template>
<script>
import OneCom from "./components/OneCom";
export default {
components: {
OneCom,
}
};
</script>
# 3、插槽默认值,没传插槽的话,使用默认值。传值的话,就会覆盖默认值
// components/OneCom.vue 子文件
<template>
<div>
<slot>第一个插槽</slot>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<slot name="two">第二个插槽</slot>
</div>
</template>
# 4、父级使用插槽,使用子组件数据
// components/OneCom.vue 子文件
<template>
<div>
<slot></slot>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<slot name="two" :php="php"></slot>
</div>
</template>
<script>
export default {
data() {
return {
php: "PHP中文网"
}
}
};
</script>
// App.vue 文件
<template>
<div>
<one-com>
<button>按钮</button>
// data 是接收数据,里面是 OneCom.vue 的 {php: "欧阳克"}
<template v-slot:two="data">
<button>按钮{{ data.php }}</button>
</template>
</one-com>
</div>
</template>
<script>
import OneCom from "./components/OneCom";
export default {
components: {
OneCom
}
};
</script>
三,文件样式
# 1、`style` 标签 `scoped` 属性设置样式只能本组件使用
// OneCom.vue 文件
<template>
// 1.1、Vue3.2 允许根节点穿透
<div class="red">{{ name }}</div>
<div>
// 1.2、无法穿透
<div class="red">{{ name }}</div>
</div>
</template>
<script>
export default {
data() {
return {
name: "欧阳克"
}
}
};
</script>
// 1.3、App.vue 文件
<template>
<div>
<div class="red">php中文网</div>
<one-com></one-com>
</div>
</template>
<script>
import OneCom from "./components/OneCom";
export default {
components: {
OneCom
}
};
</script>
// 1.4、增加scoped属性,OneCom.vue文件中,不能使用class="red"
<style scoped>
.red {
color: red;
}
</style>
# 2、`lang="scss"` 支持 `scss` 语法
<style scoped lang="scss">
</style>
四 ,组件的周期
# 1、App.vue文件,生命周期钩子的函数
<template>
<div>欧阳克</div>
</template>
<script>
export default {
beforeCreate() {
console.log("1在创建组件之前调用");
},
created() {
console.log("2组件创建完成调用");
},
beforeMount() {
console.log("3模版挂载之前调用");
},
mounted() {
console.log("4模版挂载完成调用");
}
};
</script>
# 2、App.vue文件,内容改变会执行 生命周期钩子的函数
<template>
<div>
<input type="text" v-model="php" />
</div>
</template>
<script>
export default {
data() {
return {
php : "php中文网"
};
},
beforeUpdate() {
console.log("5改变内容之前调用");
},
updated() {
console.log("6改变内容之后调用");
}
};
</script>
# 3、OneCom文件,每个vue文件都有生命周期钩子的函数
<template>
<div>
欧阳克
</div>
</template>
<script>
export default {
beforeUnmount() {
console.log("9组件销毁之前调用");
},
unmounted() {
console.log("10组件销毁之后调用");
}
};
</script>
# 3.1、App.vue,引入组件文件
<template>
<div>
// 如果用v-show,就不会销毁
<one-com v-if="show"></one-com>
<button @click="show = !show">销毁</button>
// keep-alive 缓存,跟v-show一样,不会被销毁,也有自己的事件。 属于v-if和v-show的结合体,又能保留,又能执行事件
<keep-alive>
<one-com v-if="show"></one-com>
</keep-alive>
</div>
</template>
<script>
import OneCom from "./components/OneCom";
export default {
components: {
OneCom
},
data() {
return {
show: true
}
}
};
</script>
# 4、OneCom文件,keep-alive 缓存组件事件
<template>
<div>
欧阳克
</div>
</template>
<script>
export default {
activated() {
console.log("11组件缓存前调用");
},
deactivated() {
console.log("12组件缓存后调用");
}
};
</script>
本文含有隐藏内容,请 开通VIP 后查看