自定义vue指令v-drag & 封装自定义可拖拽弹框 & id定义样式、computed实现动态style动态class & 具名插槽name属性定义slot & 引入全局组件 & 定义全局样式
效果
代码
1、主页面
index.vue
<template> <div> <el-button type="primary" size="default" @click="abc">点击</el-button> <ModalFrame v-model="isShowModel" v-drag="greet"></ModalFrame> </div> </template> <script> export default { data() { return { isShowModel:false, } }, methods: { abc(){ this.isShowModel = true }, } } </script>
2、封装组件
2.1、自定义弹框组件
src\components\modalFrame\modalFrame.vue
<template> <div id="shade-model" :class="isMark?'bg':'noBg'" v-show="modelValue"> <div id="model-frame" :style="frameStyle"> <div class="model-frame-title" v-show="title"> <slot name="title"> <p>提示</p> </slot> <span class="close-model-button" @click.stop="closeModelFrame" v-show="shut">×</span> </div> <div class="model-frame-content"> <slot name="content"></slot> </div> <div class="model-frame-footer"> <button class="cancel" @click.stop="closeModelFrame" v-show="cancel">取消</button>  <slot name="footer"></slot> </div> </div> </div> </template> <script> export default { props: { modelValue: { type: Boolean }, width: { type: Number, default: 460 }, height: { type: Number, default: 270 }, cancel: { type: Boolean, default: true }, title: { type: Boolean, default: true }, shut: { type: Boolean, default: true }, isMark:{ type: Boolean, default: true } }, methods: { //关闭模态框 closeModelFrame() { this.$emit('update:modelValue',false) this.$emit('cancelReply') //通知父组件调用函数 } }, computed: { frameStyle: function() { return { width: this.width + "px", height: this.height + "px", marginLeft: -(this.width / 2) + "px", marginTop: -(this.height / 2) + "px" } } } } </script> <style> #shade-model{ width:100%; height:100%; z-index: 11; top: 0; left: 0; position:fixed; } .bg{ background-color:rgba(0,0,0,0.3); } .noBg{ background-color:transparent; } #model-frame{ background:white; position:absolute; left:50%; top:50%; border: 1px solid #cccccc; border-radius: 4px; } #model-frame .close-model-button{ position: absolute; right: 10px; top: 12px; cursor: pointer; border-radius: 50%; width: 32px; height: 32px; text-align: center; line-height: 32px; color: #999; } #model-frame .model-frame-title { width: 100%; height: 56px; border-bottom: 1px solid #d9d9d9; font-weight: 700; font-style: normal; font-size: 16px; position: relative; } #model-frame .model-frame-title p{ padding-left: 24px; color: #000; height:56px; line-height: 56px; text-align: left; } #model-frame .model-frame-content { width: 100%; overflow: hidden; font-size: 14px; color: rgb(51, 51, 51); box-sizing: border-box; padding: 16px 20px 16px; } #model-frame .model-frame-footer { text-align: right; border-top: 1px solid #d9d9d9; position: absolute; bottom: 0; height: 56px; line-height: 56px; width: 100%; padding-right: 20px; box-sizing: border-box; } #model-frame .model-frame-footer>div{ display: inline-block; } #model-frame .model-frame-footer .cancel { background-color: #fff; font-size: 14px; color: rgb(74, 74, 74); text-decoration: underline; cursor: pointer; } #model-frame .model-frame-footer .ok{ width: 80px; height: 32px; line-height: 32px; text-align: center; color: #fff; font-weight: 400; font-style: normal; font-size: 14px; background-color: #4385f4; border-radius: 23px; margin-left: 20px; cursor: pointer; margin-right: 20px; } #model-frame .model-frame-footer .ok:hover{ transition: all .4s; background-color: #6CA0F8; } </style>
2.2、自定义vue指令
src\directive\drag.vue
<script> export default{ mounted(el, binding) { let oDiv = el; //当前元素 let self = this; //上下文 oDiv.onmousedown = function (e) { if(e.target.value == undefined){ //鼠标按下,计算当前元素距离可视区的距离 let disX = e.clientX - oDiv.offsetLeft; let disY = e.clientY - oDiv.offsetTop; document.onmousemove = function (e) { //通过事件委托,计算移动的距离 let l = e.clientX - disX; let t = e.clientY - disY; //移动当前元素 oDiv.style.left = l + 'px'; oDiv.style.top = t + 'px'; //将此时的位置传出去 binding.value({x:e.pageX,y:e.pageY}) }; document.onmouseup = function (e) { document.onmousemove = null; document.onmouseup = null; }; } }; } } </script>
3、注册全局组件和指令
src\main.ts
import {
createApp, ref } from 'vue' import App from './App.vue' const app = createApp(App) /*公共模态框组件*/ app.component('ModalFrame', ModalFrame); import ModalFrame from './components/modalFrame/modalFrame.vue'; /*拖拽*/ app.directive('drag', Drag) import Drag from './directive/drag.vue'
实例
效果
代码
index.vue
<template> <div> <el-button type="primary" size="default" @click="abc">点击</el-button> <ModalFrame v-model="isShowModel" v-drag="greet" :width="380" :height="315"> <template v-slot:title> <p>确认报名</p> </template> <template v-slot:content> <div class="gamePage_content"> <p><span>姓名</span><span>: {
{ userInfo.userName}}</span></p> <p><span>公司名称</span><span>: {
{ userInfo.baseOrgName }}</span></p> <!-- <p><span>所属部门</span><span>: {
{ userInfo.orgNameChineseTotal }}</span></p> <p><span>邮箱</span><span>: {
{ idCard(userInfo.email)}}</span></p> <p><span>联系方式</span><span>: {
{ idCard(userInfo.mobilePhone)}}</span></p> --> <!-- --------------------------------------------------------------------------------------- --> <!-- <p><span>姓名</span><span>: {
{ userInfo.userName | sm }}</span></p> <p><span>公司名称</span><span>: {
{ userInfo.orgName }}</span></p> <p><span>所属部门</span><span>: {
{ userInfo.orgNameChineseTotal }}</span></p> <p><span>邮箱</span><span>: {
{ userInfo.email | sm | idCard }}</span></p> <p><span>联系方式</span><span>: {
{ userInfo.mobilePhone | sm | idCard }}</span></p> --> <div class="gamePage_footer"> <input type="checkbox" v-model="gamePopingAgreement" /> 同意<span class="gameKnow" @click="application">《报名须知》</span><span v-show="allMessage" style="font-size:12px;color:red">请勾选同意按钮</span> </div> </div> </div> </template> <script> import { activityEnrollApi } from '@/api/activity' export default { data() { return { isShowModel:false, gamePopingAgreement: false, } }, methods: { abc(){ this.isShowModel = true }, //报名须知 application() { this.gameInformation = true; }, //确定报名 async gamePopingAgree() { try { let result = await activityEnrollApi({activityId: this.$route.query.id}) if(result.data.code == 200){ this.message.success('活动报名成功,可前往个人中心查看我参与的活动') this.showPersonalApply = false // this.gonuew = true; // if (this.questionType == "0" || this.questionType == "1") { // // 0 1 自抽 null 不抽提 // window.sessionStorage.setItem('actId', this.$route.query.id); // this.$router.push("/activity/Randomquestions") // } } } catch (error) { console.log(error) } }, } } </script> <style lang="scss" > /*马上报名弹框*/ .modalFrame { .gamePage_content { p { line-height: 28px; span:first-child { width: 60px; display: inline-block; text-align: justify; text-align-last: justify; margin-right: 4px; } } } .gamePage_footer { margin-top: 10px; } </style>
src\components\constant.js
export default {
ieopActivity: "/ieop-mtg-activity", // 申请表网关标识 }
src\api\activity\index.js
import axios from '@/utils/request' import {
getApiUrl } from "@/utils/tool"; import constant from "@/components/constant"; const baseUrl = getApiUrl(); // 活动报名 export const activityEnrollApi = (params)=>{
return axios.post(baseUrl + constant.ieopActivity + '/activity/compete/enroll',params) }
src\utils\tool.js
export function getApiUrl(v) {
return process.env.VUE_APP_API_HOST }
.env.dev
VUE_APP_API_HOST = '/gp'
vue.config.js
const {
defineConfig } = require('@vue/cli-service') module.exports = defineConfig({
transpileDependencies: true, lintOnSave: false, devServer: {
proxy: {
'/gp': {
target: 'http://27.196.111.15:18080', changeOrigin: true, pathRewrite: {
'^/gp': '/' } }, // '/img': {
// target: 'http://192.168.67.86:9595', // changeOrigin: true, // pathRewrite: {
// '^/img': '/' // } // }, }, port: 9000, // host:'27.196.104.110', host:'0.0.0.0', open:true }, })
定义公共样式
public\css\CommonStyle.css
/*列表标题hover效果*/ .listHover:hover{
color:#4385f4; } /* element plus 分页器 位置 */ .pagination_center{
justify-content: center; } .pagination_right{
justify-content: right; } /* 阴影 */ .Public-Shaow{
color: #DCDFE6; box-shadow: 0 0 18px 0 rgba(0, 0, 0, 0.15); } .mb20{
margin-bottom: 20px; } .ml20{
margin-left: 20px; } .mt20{
margin-top: 20px; } .mr20{
margin-right: 20px; } /* element plus 分页器 位置 */ .pagination_center{
justify-content: center; } .pagination_right{
justify-content: right; } /* div p span 英文换行 */ div,p,span{
word-break: break-all; } .el-popper:focus{
outline: none !important; } .el-input__wrapper:focus{
outline: none !important; } .swiper-button-prev:focus{
outline: none !important; } .swiper-button-next:focus{
outline: none !important; } .el-input-number .el-input__inner{
text-align: left !important; }
src\App.vue
<template> <div id="app" > <my-header></my-header> </div> </template> <script setup> import "../public/css/CommonStyle.css" </script> <style lang="scss" scoped> #app { background: #fff; width: 100%; height: 100%; } </style>
到此这篇自定义vue指令v-drag & 封装自定义可拖拽弹框 & id定义样式、computed实现动态style动态class & 具名插槽name属性定义slot & 引入全局组件 & 定义全局样式的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!
版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/qdvuejs/10671.html