Vue 사용자 정의 render 통합 프로젝트 그룹 탄 상자 기능
pick
2.왜 탄 틀 을 통일 적 으로 포장 해 야 합 니까?
어떻게 포장 해 야 합 니까?
일반적인 탄창 을 예 로 들 어 쓰 는 방법.보통 한 페이지 를 팝 업 하려 면 페이지
normalDialog.vue
패키지dialogBody.vue
(탄 상자 주체)를 만들어 야 한 다 는 것 을 알 수 있 습 니 다.parent.vue
flag 제어 탄 상 자 를 설정 하여 숨 기 고normalDialog.vue
닫 을 때parent.vue
대응flag
을 설정 해 야 합 니 다.단점:절차 가 복잡 하고 배치 가 번 거 롭 고 유연성 이 없 으 며 스타일 이 일치 하지 않 고 매개 변수 전달 이 번 거 로 운 등.한 항목 의 탄창 이 많 을 때 단점 이 더욱 뚜렷 해 지고 대량의isXxxDialogShow
,대량의vue
파일 이 있 을 것 이다.따라서 프로젝트 팀 은 탄 상 자 를 간단하게 설정 할 수 있 는API
이 급히 필요 하 다.1.일반적인 탄 틀 표기 법
dialoBody.vue
(탄 틀 주체)은 이곳 에서Composition API
의 표기 법 을 사용한다.간단 한 페이지 만 만 만 들 었 습 니 다.검증 을 포함 하고 데 이 터 를 저장 하 는 일반적인 논 리 를 추출 합 니 다.
<template>
<div class="dialog-body">
<div class="item">
<div> </div>
<el-input v-model="name"></el-input>
</div>
<div class="item">
<el-radio-group v-model="attention">
<el-radio label=" "></el-radio>
<el-radio label=" "></el-radio>
</el-radio-group>
</div>
<div class="item">
<el-radio-group v-model="like">
<el-radio label=" "></el-radio>
<el-radio label=" "></el-radio>
</el-radio-group>
</div>
</div>
</template>
<script>
import { reactive, toRefs } from '@vue/composition-api'
import pick from 'lodash/pick'
import { Message } from 'element-ui'
export default {
props: {
defaultName: String,
},
setup(props, ctx) {
const ATTENTIONED = ' '
const LIKED = ' '
const state = reactive({
name: props.defaultName, //
attention: ' ', //
like: ' ', //
})
/*************************************************************
*
* :
* 1. methods
* 2. ,
* methods.onXxx = ()=>{ // }
* 1: onXxx
* 2: ...methods setup
* 3: , , ;
* ;
* API handleXxx(methods,state), methods;
* Vue2 , .
*/
const methods = {}
//
methods.onNameBlur = () => {}
// ************************ API ************************
const apiMethods = {
//
isCanSave() {
if (state.attention !== ATTENTIONED || state.like !== LIKED) {
Message.error(' , , ')
return false
}
return true
},
//
getSaveData() {
// ******* lodash pick
return pick(state, ['name', 'attention', 'like'])
},
}
return {
...toRefs(state),
...methods,
apiMethods,
}
},
}
</script>
<style lang="less">
.dialog-body {
width: 100%;
height: 100px;
}
</style>
2.normalDialog.vue
소포 탄 틀 주체dialoBody.vue
<template>
<el-dialog
title=" , , "
:visible.sync="isShow"
width="30%"
:before-close="onClose"
>
<dialog-body default-name=" " ref="inner"></dialog-body>
<span slot="footer" class="dialog-footer">
<el-button @click="onClose"> </el-button>
<el-button type="primary" @click="onOK"> </el-button>
</span>
</el-dialog>
</template>
<script>
import dialogBody from './dialogBody.vue'
export default {
components: {
dialogBody,
},
data() {
return {
isShow: true,
}
},
methods: {
onClose() {
// *********** parent.vue ********
this.$parent.isNormalDialogShow = false
},
// ******* ********
onOK() {
const inner = this.$refs.inner
//
if (inner.apiMethods.isCanSave()) {
//
const postData = inner.apiMethods.getSaveData()
console.log('>>>>> postData >>>>>', postData)
//
this.onClose()
}
},
},
}
</script>
parent.vue
// html
<normal-dialog v-if="isNormalDialogShow" />
// Js
data(){
isNormalDialogShow:false
}
methods:{
onDialogShow(){ // ****** *****
this.isNormalDialogShow = true
}
}
2.어떻게 포장 할 지2.1 API 요구 사항:
isXxxDialogShow
el-dialog
2.2 이상 API:
import dialogBody from './dialogBody.vue'
const dialog = new JSDialog({
comonent: dialogBody,
dialogOpts: { //
title: 'JSDialog ',
width: '400px'
},
props: {
defaultName: 'JSDialog ',
},
onOK() {
const inner = dialog.getInner() // dialogBody
//
if (inner.apiMethods.isCanSave()) {
//
const postData = inner.apiMethods.getSaveData()
console.log('>>>>> postData >>>>>', postData)
//
dialog.close()
}
},
onCancel() {
dialog.close() //
},
})
dialog.show() //
3.어떻게 포장 합 니까?동적 제어 디 스 플레이 내용,머 릿 속 에 떠 오 르 는 세 가지 방안:카드 슬롯,동적 구성 요소 와 render.다음은 동적 탄 틀 장면 에서 세 가지 방안 을 간단하게 비교 합 니 다.
먼저 코드 를 전체적으로 미리 보고 다음 에 세분 화하 여 설명 하 겠 습 니 다.
import Vue from 'vue'
import merge from 'lodash/merge'
import orderBy from 'lodash/orderBy'
//
function btnBuilder(options) {
const defaultBtn = {
text: ' ', //
clickFn: null, //
type: 'default', //
isHide: false, //
order: 2 //
}
return { ...defaultBtn, ...options }
}
export default class JSDialog {
constructor(originOptions) {
this.options = {}
this.vm = null
this._mergeOptions(originOptions)
this._initVm()
}
//
_mergeOptions(originOptions) {
const defaultOptions = {
component: '', // vue
// el-dialog api , aaaBbbCcc
dialogOpts: {
width: '40%',
title: ' '
},
// vue
props: {},
//
onOK: () => {
console.log('JSDialog default OK'), this.close()
},
//
onCancel: () => {
console.log('JSDialog default cancel'), this.close()
},
footer: {
ok: btnBuilder({
text: ' ',
type: 'primary',
order: 0
}),
cancel: btnBuilder({
text: ' ',
order: 1
})
}
}
// this.options
merge(this.options, defaultOptions, originOptions)
const footer = this.options.footer
Object.entries(footer).forEach(([key, btnOptions]) => {
//
if (['ok', 'cancel'].includes(key)) {
const clickFn = key === 'ok' ? this.options.onOK : this.options.onCancel
// : footer clickFn > options onOK onCancel
btnOptions.clickFn = btnOptions.clickFn || clickFn
} else {
//
//
footer[key] = btnBuilder(btnOptions)
}
})
}
_initVm() {
const options = this.options
const beforeClose = this.options.footer.cancel.clickFn //
this.vm = new Vue({
data() {
return {
//
footer: options.footer, //
visible: false //
}
},
methods: {
show() {
//
this.visible = true
},
close() {
//
this.visible = false
},
clearVm() {
// vm
this.$destroy()
}
},
mounted() {
// body
document.body.appendChild(this.$el)
},
destroyed() {
// body
document.body.removeChild(this.$el)
},
render(createElement) {
//
const inner = createElement(options.component, {
props: options.props, //
ref: 'inner' //
})
//
const showBtns = Object.values(this.footer).filter(btn => !btn.isHide)
//
const sortBtns = orderBy(showBtns, ['order'], ['desc'])
// jsx
const footer = (
<div slot="footer">
{sortBtns.map(btn => (
<el-button type={btn.type} onClick={btn.clickFn}>
{btn.text}
</el-button>
))}
</div>
)
//
const elDialog = createElement(
'el-dialog',
{
// el-dialog
props: {
...options.dialogOpts,
visible: this.visible,
beforeClose
},
// **** ,visible false ,el-dialog *****
on: {
closed: this.clearVm
},
ref: 'elDialog'
},
// :
[inner, footer]
)
return elDialog
}
}).$mount()
}
// API
//
close() {
this.vm.close()
}
//
show() {
this.vm.show()
}
// ,
getInner() {
return this.vm.$refs.inner
}
}
2.매개 변수 통합API 요구 사항 을 수행 하려 면 호출 이 간단 하고 전송 이 간편 하 며 확장 가능 한 제어 탄 상자 스타일 을 사용 해 야 합 니 다.매개 변수 통합 은 원가 가 가장 적은 실현 방안 으로 TS 에 맞 추 는 효과 가 더욱 좋다.기본 매개 변 수 를 정의 합 니 다.lodash 의 merge 를 통 해 심층 속성 을 합 칩 니 다.매개 변수 통합 을 통 해 사용자 정의 footer 단 추 를 누 르 고 텍스트,스타일,순서 와 리 셋 을 제어 할 수 있 습 니 다.
//
_mergeOptions(originOptions) {
const defaultOptions = {
component: '', // vue
// el-dialog api , aaaBbbCcc
dialogOpts: {
width: '40%',
title: ' '
},
// vue
props: {},
//
onOK: () => {
console.log('JSDialog default OK'), this.close()
},
//
onCancel: () => {
console.log('JSDialog default cancel'), this.close()
},
footer: {
ok: btnBuilder({
text: ' ',
type: 'primary',
order: 0
}),
cancel: btnBuilder({
text: ' ',
order: 1
})
}
}
// this.options
merge(this.options, defaultOptions, originOptions)
const footer = this.options.footer
Object.entries(footer).forEach(([key, btnOptions]) => {
//
if (['ok', 'cancel'].includes(key)) {
const clickFn = key === 'ok' ? this.options.onOK : this.options.onCancel
// : footer clickFn > options onOK onCancel
btnOptions.clickFn = btnOptions.clickFn || clickFn
} else { //
//
footer[key] = btnBuilder(btnOptions)
}
})
}
3.렌 더 링 함수렌 더 링 함수&JSX 공식 문서 에서 render 에 대한 설명 을 추출 합 니 다.Vue 는 대부분의 경우 템 플 릿 을 사용 하여 HTML 을 만 드 는 것 을 추천 합 니 다.그러나 일부 장면 에서 자 바스 크 립 트 의 완전한 프로 그래 밍 능력 이 필요 하 다.이 때 는 템 플 릿 보다 컴 파일 러 에 더 가 까 운 렌 더 링 함 수 를 사용 할 수 있 습 니 다.공식 문 서 는 렌 더 링 함수 에 대한 쓰기,매개 변수,JSX 쓰기 에 대한 소개 가 상세 하 므 로 더 이상 군말 하지 않 습 니 다.다음 코드 는 최신 vue-cli 생 성 프로젝트 에서 실 행 됩 니 다.JS 매개 변수 생 성 요소 와 JSX 생 성 요소 두 가지 쓰기 방법 을 시도 하 였 습 니 다.
render(createElement) {
//
const inner = createElement(options.component, {
props: options.props, //
ref: 'inner' //
})
//
const showBtns = Object.values(this.footer).filter(btn => !btn.isHide)
//
const sortBtns = orderBy(showBtns, ['order'], ['desc'])
// jsx
const footer = (
<div slot="footer">
{sortBtns.map(btn => (
<el-button type={btn.type} onClick={btn.clickFn}>
{btn.text}
</el-button>
))}
</div>
)
//
const elDialog = createElement(
'el-dialog',
{
// el-dialog
props: {
...options.dialogOpts,
visible: this.visible
},
on: {
closed: this.clearVm
},
ref: 'elDialog'
},
// :
[inner, footer]
)
return elDialog
}
4.봉인 API일시 적 으로 세 개의 API 만 봉 인 했 고 서로 다른 장면 에 따라 API 를 확장 할 수 있 습 니 다.예 를 들 어 탄 상자 가 숨 김,탄 상자 새로 고침 등 입 니 다.
show(),탄 상자 표시
디 스 플레이 는 주로 el-dialog 의 visible 을 true 로 수정 하여 body 에 마 운 트 된 탄 상자 디 스 플레이 를 제어 합 니 다.
show() {
this.vm.show()
}
close(),탄 상자 닫 기처리 프로 세 스 닫 기:el-dialog 의 visible 을 false 로 수정 합 니 다.el-dialog 의 closed 이벤트 실행 하기;clearVm 실행 하기;vm 의$destroy()실행 하기;destroyed()리 셋 에서$el 을 body 에서 제거 합 니 다.
close() {
this.vm.close()
}
getInner(),탄 상자 의 주체 인 스 턴 스 를 가 져 옵 니 다.인 스 턴 스 에 접근 하 는 방법,제어 단추 프로 세 스 에 사용 할 수 있 습 니 다.
getInner() {
return this.vm.$refs.inner
}
어떻게 사용1.가장 간단 한 장면,페이지 만 설정
단추 이벤트 리 셋 은 기본 리 셋 을 사용 합 니 다.확인 과 취소 단 추 를 누 르 면 탄 상 자 를 닫 을 수 있 습 니 다.
import dialogBody from './renderJsx/dialogBody'
const dialog = new JSDialog({
component: dialogBody,
})
dialog.show() //
효 과 는 다음 과 같 습 니 다:2.탄 틀 스타일 제어 및 절차 확정
el-dialog 가 지원 하 는 설정 항목 을 사용자 정의 할 수 있 습 니 다.Dialog 대화 상 자 를 보십시오.예 를 들 어 title,custom Class.customeClass 를 통 해 프로젝트 내 탄 틀 의 스타일 을 통일 적 으로 제어 할 수 있 습 니 다.취소 버튼 코드 리 셋 을 제어 할 수 있 습 니 다.
import dialogBody from './renderJsx/dialogBody'
const dialog = new JSDialog({
component: dialogBody,
dialogOpts: {
title: ' , ',
customClass:'js-dialog'
},
props: {
defaultName: 'JSDialog '
},
onOK() {
const inner = dialog.getInner() // dialogBody
//
if (inner.apiMethods.isCanSave()) {
//
const postData = inner.apiMethods.getSaveData()
console.log('>>>>> postData >>>>>', postData)
//
dialog.close()
}
},
onCancel() {
dialog.close() //
}
})
효 과 는 다음 과 같 습 니 다:3.사용자 정의 footer
사용자 정의 단 추 를 누 르 면 리 셋,스타일,순서,표시 와 숨 김 을 제어 할 수 있 습 니 다.
import dialogBody from './renderJsx/dialogBody'
const dialog = new JSDialog({
component: dialogBody,
footer: {
ok: { //
text: ' '
},
cancel: { //
isHide: true
},
add: { //
text: ' ',
clickFn() {
dialog.close()
},
order: -1 // ,order
},
add2: {
text: ' 2',
clickFn() {
dialog.close()
},
order: 3
}
}
})
dialog.show() //
효 과 는 다음 과 같 습 니 다:총결산
Vue 사용자 정의 render 통합 프로젝트 그룹 탄 상자 기능 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 Vue 사용자 정의 render 프로젝트 그룹 탄 상자 내용 은 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 많은 지원 바 랍 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Vue Render 함수로 DOM 노드 코드 인스턴스 만들기render에서createElement 함수를 사용하여 DOM 노드를 만드는 것은 직관적이지 않지만 일부 독립 구성 요소의 디자인에서 특수한 수요를 충족시킬 수 있습니다.간단한 렌더링 예는 다음과 같습니다. 또한 v...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.