一笛臣、巧用兩次watch監(jiān)聽控制彈窗的顯示
1.在component文件夾下創(chuàng)建文件夾chooseIcon,創(chuàng)建對應文件
2.在views下面注冊組件,然后在router下面配置路由
{
path:'/chooseIcon',
component:() => import ('../views/chooseIcon/index.vue')
}
3.代碼
(1)component/chooseIcon/src/index.vue
<template>
<el-button @click="handleClick" type="primary">
<slot></slot>
</el-button>
<el-dialog :title="title" v-model="dialogVisible">哇大美女</el-dialog>
</template>
<script lang="ts" setup>
import { ref, watch } from "@vue/runtime-core"
let props = defineProps<{
//彈出框的標題
title:string,
//控制彈出框的顯示與隱藏
visible:boolean
}>()
let emits = defineEmits(['update:visible'])
//拷貝一份父組件傳遞過來的visible
let dialogVisible = ref<boolean>(props.visible)
let handleClick = ()=>{
//需要修改父組件的數(shù)據
emits('update:visible',!props.visible)
}
//監(jiān)聽visible的變化,只能監(jiān)聽第一次變化尸饺,val為變化之后的數(shù)據
watch(()=>props.visible,val =>{
dialogVisible.value=val
//emits('update:visible',val)
})
//監(jiān)聽組件內部dialogVisible的變化
watch(()=>dialogVisible.value,val=>{
emits('update:visible',val)
})
</script>
<style lang="scss" scoped>
</style>
這里采用了兩次watch監(jiān)聽进统,來控制彈框的顯示與隱藏
拷貝之后,使用dialogVisible所有監(jiān)聽的visible變化只有第一次與父組件有關浪听,后面的變化都有只與自己內部的visible有關螟碎,與父組件無關
(2)views/chooseIcon/index.vue
<template>
<div>
<m-choose-icon title="選擇圖標" v-model:visible="visible">
選擇圖標
</m-choose-icon>
</div>
</template>
<script lang="ts" setup>
import { ref } from '@vue/reactivity'
import mChooseIcon from '../../components/chooseIcon/src/index.vue'
let visible = ref<boolean>(false)
</script>
<style lang="scss" scoped>
</style>
二、巧用component動態(tài)組件顯示所有圖標
component/chooseIcon/src/index.vue
<template>
<el-button @click="handleClick" type="primary">
<slot></slot>
</el-button>
<el-dialog :title="title" v-model="dialogVisible">
<div class="container">
<div
class="item"
v-for="(item,index) in Object.keys(ElIcons)"
:key="index"
>
<div class="text">
<component :is="`el-icon-${toLine(item)}`"></component>
</div>
<div class="icon">{{item}}</div>
</div>
</div>
</el-dialog>
</template>
<script lang="ts" setup>
import * as ElIcons from '@element-plus/icons';
import { ref, watch } from "@vue/runtime-core";
import { toLine } from '../../../utils';
let props = defineProps<{
//彈出框的標題
title:string,
//控制彈出框的顯示與隱藏
visible:boolean
}>()
let emits = defineEmits(['update:visible'])
//拷貝一份父組件傳遞過來的visible
let dialogVisible = ref<boolean>(props.visible)
let handleClick = ()=>{
//需要修改父組件的數(shù)據
emits('update:visible',!props.visible)
}
//監(jiān)聽visible的變化,只能監(jiān)聽第一次變化,val為變化之后的數(shù)據
watch(()=>props.visible,val =>{
dialogVisible.value=val
//emits('update:visible',val)
})
//監(jiān)聽組件內部dialogVisible的變化
watch(()=>dialogVisible.value,val=>{
emits('update:visible',val)
})
</script>
<style lang="scss" scoped>
.container{
display: flex;
align-items: center;//垂直方向居中
flex-wrap: wrap;//換行
}
.item{
width: 25%;
height: 70px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;//水平方向居中
margin-bottom: 20px;
cursor: pointer;//使得到時候可以點進去復制
}
.text{
font-size: 14px;
}
.icon{
flex: 1;
}
svg{
width: 2em;
height: 2em;
}
</style>
*不能循環(huán)對象迹栓,所有在取圖標庫的使用要用
v-for="(item,index) in Object.keys(ElIcons)"
三掉分、利用命名空間修改dialog樣式
修改組件庫內部樣式
1.自定義一個類名空間
2.現(xiàn)在瀏覽器里面調試樣式
3.把調試好的類名放在入這個類名里面
4.在App.vue里面引入這個文件
5.在組件內需要改樣式的元素的父元素加上這個類名
代碼
index.vue
<template>
<el-button @click="handleClick" type="primary">
<slot></slot>
</el-button>
<div class="m-choose-icon-dialog-body-height">
<el-dialog :title="title" v-model="dialogVisible">
<div class="container">
<div
class="item"
v-for="(item,index) in Object.keys(ElIcons)"
:key="index"
>
<div class="text">
<component :is="`el-icon-${toLine(item)}`"></component>
</div>
<div class="icon">{{item}}</div>
</div>
</div>
</el-dialog>
</div>
</template>
<script lang="ts" setup>
import * as ElIcons from '@element-plus/icons';
import { ref, watch } from "@vue/runtime-core";
import { toLine } from '../../../utils';
let props = defineProps<{
//彈出框的標題
title:string,
//控制彈出框的顯示與隱藏
visible:boolean
}>()
let emits = defineEmits(['update:visible'])
//拷貝一份父組件傳遞過來的visible
let dialogVisible = ref<boolean>(props.visible)
let handleClick = ()=>{
//需要修改父組件的數(shù)據
emits('update:visible',!props.visible)
}
//監(jiān)聽visible的變化,只能監(jiān)聽第一次變化,val為變化之后的數(shù)據
watch(()=>props.visible,val =>{
dialogVisible.value=val
//emits('update:visible',val)
})
//監(jiān)聽組件內部dialogVisible的變化
watch(()=>dialogVisible.value,val=>{
emits('update:visible',val)
})
</script>
<style lang="scss" scoped>
.container{
display: flex;
align-items: center;//垂直方向居中
flex-wrap: wrap;//換行
}
.item{
width: 25%;
height: 70px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;//水平方向居中
margin-bottom: 20px;
cursor: pointer;//使得到時候可以點進去復制
}
.text{
font-size: 14px;
}
.icon{
flex: 1;
}
svg{
width: 2em;
height: 2em;
}
</style>
styles/ui.scss
.m-choose-icon-dialog-body-height{
.el-dialog__body{
height: 500px;
overflow: scroll;
}
}
App.vue
<template>
<router-view></router-view>
</template>
<style>
@import './styles/base.scss';
@import './styles/ui.scss';
</style>
(1)這里記得,一些基本的樣式我們都可以將它們封裝到styles文件夾下面的一個文件下克伊,然后進行引入
(2)我在這里把之前的App.vue中的基本樣式封裝到了styles下面的base.scss
*{
margin: 0;
padding: 0;
}
html,body,#app,.el-container,.el-menu{
height: 100%;
}
svg{
width: 1em;
height: 1em;
}
四酥郭、通過自定義hooks函數(shù)實現(xiàn)復制功能
1.創(chuàng)建hooks文件夾,在下面的文件中定義useCopy函數(shù)
hooks/useCopy/useCopy.ts
import { ElMessage } from "element-plus"
//復制文本
export const useCopy = (text:string)=>{
//1.創(chuàng)建一個input框
let input = document.createElement('input')
//2.給輸入框value賦值
input.value=text
//3.追加到body里面去
document.body.appendChild(input)
//4.選擇輸入框的操作
input.select()
//5.執(zhí)行復制操作
document.execCommand('Copy')
//刪除加入的輸入框
document.body.removeChild(input)
//提示用戶
ElMessage.success('復制成功')
}
component/chooseIcon/src/index.vue
<template>
<el-button @click="handleClick" type="primary">
<slot></slot>
</el-button>
<div class="m-choose-icon-dialog-body-height">
<el-dialog :title="title" v-model="dialogVisible">
<div class="container">
<div
class="item"
v-for="(item,index) in Object.keys(ElIcons)"
:key="index"
@click="()=>clickItem(item)"
>
<div class="text">
<component :is="`el-icon-${toLine(item)}`"></component>
</div>
<div class="icon">{{item}}</div>
</div>
</div>
</el-dialog>
</div>
</template>
<script lang="ts" setup>
import * as ElIcons from '@element-plus/icons';
import { ref, watch } from "@vue/runtime-core";
import { toLine } from '../../../utils';
import { useCopy } from '../../../hooks/useCopy/useCopy'
let props = defineProps<{
//彈出框的標題
title:string,
//控制彈出框的顯示與隱藏
visible:boolean
}>()
let emits = defineEmits(['update:visible'])
//拷貝一份父組件傳遞過來的visible
let dialogVisible = ref<boolean>(props.visible)
//點擊按鈕顯示彈出框
let handleClick = ()=>{
//需要修改父組件的數(shù)據
emits('update:visible',!props.visible)
}
//監(jiān)聽visible的變化,只能監(jiān)聽第一次變化,val為變化之后的數(shù)據
watch(()=>props.visible,val =>{
dialogVisible.value=val
//emits('update:visible',val)
})
//監(jiān)聽組件內部dialogVisible的變化
watch(()=>dialogVisible.value,val=>{
emits('update:visible',val)
})
//點擊圖標
let clickItem = (item:string) =>{
let text = `<el-icon-${toLine(item)} />`
//復制文本
useCopy(text)
//關閉彈框
dialogVisible.value=false
}
</script>
<style lang="scss" scoped>
.container{
display: flex;
align-items: center;//垂直方向居中
flex-wrap: wrap;//換行
}
.item{
width: 25%;
height: 70px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;//水平方向居中
margin-bottom: 20px;
cursor: pointer;//使得到時候可以點進去復制
}
.text{
font-size: 14px;
}
.icon{
flex: 1;
}
svg{
width: 2em;
height: 2em;
}
</style>
四運行出來的界面
圖標選擇器.png
圖標選擇.png
圖標復制.png
***點擊選擇圖標才會彈出來選擇框愿吹,點擊選擇框右上角的叉叉或者其他地方都可隱藏選擇框,點擊圖標會進行復制不从,然后彈框會隱藏