简言
前面我们已经构建了一个项目。现在我们在那个项目里面学习组件的用法。
构建项目文章-》构建vue3项目
话不多说,不玩虚的,let’s go! ——ZSK666
创建组件
1.创建之前
如果在ts文件中,导入.vue文件报错(不影响执行)。这是因为ts配置文件没有声明vue文件。
如果你觉得比较烦,可以做以下配置:
// vue.d.ts声明文件(声明文件.d.ts结尾)
declare module "*.vue" {
import { defineComponent } from "vue";
const Component: ReturnType<typeof defineComponent>;
export default Component;
}
2. 创建vue文件
创建组件就是创建普通的vue文件。首先我们先给项目瘦身,把无用的东西全部删除掉。瘦身结果:
并且我们自定义了一些文件:
- assets-》自定义css文件,存放css文件。创建images文件存放图片。创建存放js文件(也可以改成ts)。
- src-》创建pages(存放代码)、plugins(存放插件)、utils(存放工具函数文件)。
然后在pages里写第一个vue文件,index.vue。
<template>
<div class="container">
<h1>hello,World!</h1>
</div>
</template>
<script lang="ts" setup>
import { reactive, toRefs, onBeforeMount, onMounted } from "vue";
</script>
<style lang="scss" scoped></style>
3.在componts创建公共组件
在componts创建common文件夹,再创建Calculate组件。创建好后使用,效果如下:
改进组件
上面只是介绍组件介绍和使用,下面来改进这个计算组件。
计算组件:
<!--
* @Date: 2022-10-27 15:33:33
* @LastEditors: zhangsk
* @LastEditTime: 2022-10-27 17:31:18
* @FilePath: \basic-demo\src\components\common\Calculate.vue
* @Label: Do not edit
-->
<template>
<div class="calculate">
<h1>计算吧!公用组件</h1>
<div class="calculate_main">
<div>
<input
class="input"
type="number"
:value="valueOne"
@input="(event) => emit('update:valueOne', event)"
/>
</div>
<div>
<select
class="input"
style="text-align: center; height: 25px"
:value="selected"
@change="(event) => emit('update:selected', event)"
>
<option v-for="item of calculationSymbolList" :value="item.value">
{{ item.label }}
</option>
</select>
</div>
<div>
<input
class="input"
type="number"
:value="valueTwo"
@input="(event) => emit('update:valueTwo', event)"
/>
</div>
<div>
<button class="button" @click="calculateClick">计算</button>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { reactive, toRefs, onBeforeMount, onMounted } from "vue";
// 定义可传入变量
const props = defineProps({
// 第一个值
valueOne: {
type: Number,
default: 0,
},
// 第二个值
valueTwo: {
type: Number,
default: 0,
},
selected: {
type: String,
},
});
// 定义外调事件
const $emit = defineEmits([
"update:valueOne",
"update:valueTwo",
"update:selected",
"calculate",
]);
// 计算方式
const calculationSymbolList = [
{
id: 0,
label: "➕",
value: "+",
},
{
id: 1,
label: "➖",
value: "-",
},
{
id: 2,
label: "✖",
value: "*",
},
{
id: 4,
label: "➗",
value: "/",
},
];
// emit方法
const emit = (
ename: "update:valueOne" | "update:valueTwo" | "update:selected",
event: any
) => {
if (event.target) $emit(ename, event.target.value);
};
//
const calculateClick = () => {
// 先校验
const { selected, valueOne } = props;
if (selected === "/" && valueOne == 0) {
alert("除法被除数不能为0");
return false;
}
$emit("calculate");
};
</script>
<style lang="scss" scoped>
.calculate {
width: 100%;
position: relative;
}
.calculate_main {
display: flex;
justify-content: space-evenly;
max-width: 450px;
padding: 30px 0;
border: thick double #000;
}
.input {
width: 100px;
height: 20px;
outline: none;
border: 1px solid #eaeaea;
border-radius: 5px;
}
.button {
width: 60px;
padding: 3px 8px;
background-color: rgb(46, 197, 92);
color: #fff;
border: 0;
border-radius: 10px;
cursor: pointer;
// 使用了scss,&代表.button
&:hover {
background-color: rgb(27, 133, 58);
}
}
</style>
使用:
<template>
<div class="container">
<h1>hello,World!</h1>
<!-- 公用组件使用 -->
<CalculateVue
v-model:value-one="form.valueOne"
v-model:value-two="form.valueTwo"
v-model:selected="form.selected"
@calculate="calculateFun"
></CalculateVue>
<div>{{ form.valueOne }} -{{ form.selected }} - {{ form.valueTwo }}</div>
<div>计算结果:{{ result ? result : "-" }}</div>
</div>
</template>
<script lang="ts" setup>
import CalculateVue from "@/components/common/Calculate.vue";
import { reactive, toRefs, ref, onBeforeMount, onMounted } from "vue";
const form = reactive({
valueOne: 0,
selected: "+",
valueTwo: 0,
});
let result = ref(0);
// 计算
const calculateFun = () => {
const { selected, valueOne, valueTwo } = form;
console.log(selected, valueOne, valueTwo);
switch (selected) {
case "+":
result.value = valueOne * 1 + valueTwo * 1;
break;
case "-":
result.value = valueOne - valueTwo;
break;
case "*":
result.value = valueOne * valueTwo;
break;
case "/":
result.value = valueOne / valueTwo;
}
};
</script>
<style lang="scss" scoped></style>
效果如下:
这个组件主要运用了props和emits的语法。实现了组件的v-demo:moduleValue。