当前位置:网站首页 > Vue.js开发 > 正文

自定义vue指令v-drag & 封装自定义可拖拽弹框 & id定义样式、computed实现动态style动态class & 具名插槽name属性定义slot & 引入全局组件 & 定义全局样式

自定义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>&emsp; <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>:&emsp;{ 
  { userInfo.userName}}</span></p> <p><span>公司名称</span><span>:&emsp;{ 
  { userInfo.baseOrgName }}</span></p> <!-- <p><span>所属部门</span><span>:&emsp;{ 
  { userInfo.orgNameChineseTotal }}</span></p> <p><span>邮箱</span><span>:&emsp;{ 
  { idCard(userInfo.email)}}</span></p> <p><span>联系方式</span><span>:&emsp;{ 
  { idCard(userInfo.mobilePhone)}}</span></p> --> <!-- --------------------------------------------------------------------------------------- --> <!-- <p><span>姓名</span><span>:&emsp;{ 
  { userInfo.userName | sm }}</span></p> <p><span>公司名称</span><span>:&emsp;{ 
  { userInfo.orgName }}</span></p> <p><span>所属部门</span><span>:&emsp;{ 
  { userInfo.orgNameChineseTotal }}</span></p> <p><span>邮箱</span><span>:&emsp;{ 
  { userInfo.email | sm | idCard }}</span></p> <p><span>联系方式</span><span>:&emsp;{ 
  { userInfo.mobilePhone | sm | idCard }}</span></p> --> <div class="gamePage_footer"> <input type="checkbox" v-model="gamePopingAgreement" />&nbsp;同意<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 & 引入全局组件 & 定义全局样式的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!

版权声明


相关文章:

  • js封装,小写金额转化为大写金额,用于发票金额、合同资金等2024-11-27 14:54:08
  • eclipse 最新版本“Oxygen Release (4.7.0)”在线安装hibernate插件2024-11-27 14:54:08
  • 阿里云centos7安装mysql5.72024-11-27 14:54:08
  • vue缓存之动态keep-alive2024-11-27 14:54:08
  • 前端js常用正则验证2024-11-27 14:54:08
  • vue中,表单增加一行删除一行上移一行下移一行2024-11-27 14:54:08
  • vue3中,el-table级联表格——default-expand-all & row-key & show-overflow-tooltip & 树状表格计算总价合计总计2024-11-27 14:54:08
  • vue中,el-table树形数据与懒加载【实例】(二)——封装拖拽上传el-upload & 本地下载模板-public下的file文件夹 & JSON.parse转对象 & 表单禁止输入特殊字符2024-11-27 14:54:08
  • vue中,404页面——当前页面不存在,直接跳转首页2024-11-27 14:54:08
  • vue中,401页面——您没有权限访问当前页面,直接跳转登录页2024-11-27 14:54:08
  • 全屏图片