在平常封装组件时候,需要子组件和父组件的值是响应式的,就是子组件的值初始状态由父组件决定,当子组件改变后,父组件需要接受到变化后的值
子组件
<template>
<div>
<h3>这是子组件;假如子组件初始值是父组件传过来的,当数据变化,实时需要父组件监听到子组件变化</h3>
<button @click="changeHandle">改变子组件值</button>
</div>
</template>
<script>
export default {
props: {
msg: {
type:String,
default:""
}
},
methods: {
changeHandle() {
this.msg = "改变后的值"
// 在这里发送 input事件,外面父组件通过v-model可以监听到input事件,因为v-model底层就是通过监听input事件
this.$emit("input", this.msg);
}
},
}
</script>
父组件
<template>
<div>
<!-- <p>通过v-model获取子组件的响应数据</p> -->
<Vmodel v-model="msg"/>
<P>改变后的值:{{msg}}</P>
</div>
</template>
<script>
import Vmodel from "@/components/vmodel/Vmodel.vue"
export default {
components: {Vmodel},
data() {
return {
msg:"这是父组件初始值"
}
}
}
</script>
<style scoped>
</style>
一般开发时封装子组件都是自定义事件,父组件监听自定义事件,这样可以监控到每一个过程中数据,方便自己可以在什么时机内写入自己的逻辑
建议一般 图片上传组件,和富文本组件,使用v-model指令监听子组件的变化
通过v-model封装图片上传组件
- 子组件
<template>
<div class="component-upload-image">
<el-upload
:action="uploadImgUrl"
list-type="picture-card"
:on-success="handleUploadSuccess"
:before-upload="handleBeforeUpload"
:on-error="handleUploadError"
name="file"
:show-file-list="false"
:headers="headers"
style="display: inline-block; vertical-align: top"
>
<el-image v-if="!value" :src="value">
<div slot="error" class="image-slot">
<i class="el-icon-plus" />
</div>
</el-image>
<div v-else class="image">
<el-image :src="value" :style="`width:150px;height:150px;`" fit="fill"/>
<div class="mask">
<div class="actions">
<span title="预览" @click.stop="dialogVisible = true">
<i class="el-icon-zoom-in" />
</span>
<span title="移除" @click.stop="removeImage">
<i class="el-icon-delete" />
</span>
</div>
</div>
</div>
</el-upload>
<el-dialog :visible.sync="dialogVisible" title="预览" width="800" append-to-body>
<img :src="value" style="display: block; max-width: 100%; margin: 0 auto;">
</el-dialog>
</div>
</template>
<script>
import { getToken } from "@/utils/auth";
export default {
data() {
return {
dialogVisible: false,
uploadImgUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址
headers: {
Authorization: "Bearer " + getToken(),
},
};
},
props: {
value: {
type: String,
default: "",
},
},
methods: {
removeImage() {
this.$emit("input", "");
},
handleUploadSuccess(res) {
this.$emit("input", res.url);
this.loading.close();
},
handleBeforeUpload() {
this.loading = this.$loading({
lock: true,
text: "上传中",
background: "rgba(0, 0, 0, 0.7)",
});
},
handleUploadError() {
this.$message({
type: "error",
message: "上传失败",
});
this.loading.close();
},
},
watch: {},
};
</script>
<style scoped lang="scss">
.image {
position: relative;
.mask {
opacity: 0;
position: absolute;
top: 0;
width: 100%;
background-color: rgba(0, 0, 0, 0.5);
transition: all 0.3s;
}
&:hover .mask {
opacity: 1;
}
}
</style>
- 父组件:方便进行新增和修改操作
<el-form>
<el-form-item label="图片路径">
<imageUpload v-model="form.tpurl"/>
</el-form-item>
</el-form>
富文本组件
敬请期待
网友评论