Vue.js, ElementUI의 Dialog를 동적으로 생성해 보십시오.

13283 단어 ElementUIDialogVue.js

배경


서버가 없는 상황에서 자신이 사용하는 가계수지부식 웹 서비스를 동시에 배워 개발 중이다.
데이터 입력 화면, 일람 화면과 개발이 끝났고 다음은 데이터 편집 기능으로 당시의 실현 방법이 고민이었다.다른 페이지로 이동하는 편집도 선택이지만 다음과 같은 관점에서 모델 대화상자를 사용하기로 결정했다.
  • 일람 화면에서 편집으로 옮겨 편집이 끝나면 일람 화면으로 돌아가고 싶습니다.
  • 되돌아갈 때 편집 내용을 반영하고 싶지만 다시 읽는 것은 위치가 되돌아오거나 동작이 느려지는 한 가지 원인이기 때문에 좋아하지 않는다.
  • 편집된 요소 수가 적다(5개 정도).
  • Let's try


    정보 수집


    element.웹 페이지 정보
    대화 상자 페이지를 봅니다.샘플은 당연히 정상적으로 실행되지만, 샘플 원본을 보면 대화상자는 독립된 것이 아니라 페이지를 사용하는 원본을 쓰는 느낌이다.입력 대화상자는 여러 화면에서 같은 대화상자를 사용하고자 합니다.
    많은 것을 찾은 후에 아래의 자료를 발견하였다.정말 하고 싶은 일이야.
    잃어버리기 쉬운 구성 요소를 만드는 이야기
    다음은 Vue 어셈블리의 라이프 사이클에 대한 정보도 중요합니다.공식 홈페이지인가요?
    구성 요소 기반
    믹스라는 기술의 모습도 있다.여러 구성 요소에 같은 처리를 삽입할 수 있을 것 같습니다.하지만 이번에는 대화면 Vue에 끼워 쓰고 싶어서 안 쓸 것 같아요.
    믹스인

    방침


    나는 상술한 잃어버리기 쉬운 구성 요소를 만드는 이야기을 기초로 하고 싶다.그러나 자신이 하고 싶은 것은 입력 대화상자에 입력하면 메인 화면에 그 값을 반영하는 기능이 필요하기 때문에 대화상자 안의 값을 전달하는 방법은 좀 모르겠다.만약 내가 충분한 Vue의 지식을 가지고 있다면 이것을 확장할 수 있을 것이라고 생각하지만, 아직 그 단계는 아니다.잠시 이것을 참고하여 아래의 방침에 따라 실시하다.
  • 대화 상자의 요소, 공동 처리를 대화 상자용 Vue 소스에 통합합니다.
  • 호출자는 제작, 파라미터 설정, 호출, 후처리만 진행한다.
  • 매번 사용할 때마다 생성, 폐기하고 싶지만 이번에는 화면이 시작될 때 한 번만 제작한다(폐기는 고려하지 않는다).
  • 득점


    Dialog 측면
  • callback을 사용하여 데이터를 매개 변수에 전달하여 대화상자가 끝날 때 처리
  • 객체를 생성할 때 상위 요소에 DOM 요소 추가
  • 처리에 성공했을 때 상술한 콜백을 실행합니다.대화 상자에서 편집된 데이터도 전달됩니다.
  • 호출자
  • Vue.extend 명령을 사용하여 구조 함수 생성
  • 구조 함수에서 지정한 매개 변수로 동적 생성
  • 자신을 생성할 때 대화상자도 생성
  • callback 함수를 통해 대화 수신 성공 시 처리

  • this.$forceUpdate()를 사용하여 렌더링을 강제로 수행할 수 있습니다.패턴 요소 내용의 업데이트는 렌더링이 필요 없을 것 같아서 처리되었습니다.
  • 실제 출처


    Dialog 측면 Vue
    <template>
      <el-dialog title="入力" :visible.sync="slipDialogVisible">
        <el-form ref="form" :model="slip" label-width="60px">
          <!-- 中略 -->
        </el-form>
        <div class="dialog-footer">
          <el-button type="warning" :plain="true" @click="ondelsubmit">削除</el-button>
          <el-button type="danger" :plain="true" @click="slipDialogVisible = false">中止</el-button>
          <el-button type="primary" @click="onupdsubmit">登録</el-button>
        </div>
      </el-dialog>
    </template>
    
    <script>
    
    export default {
      name: 'SlipInputDlg',
      // 引数
      props: {
        // 親要素
        parent: {
          type: Element,
          require: true
        },
        // ・・中略・・
        // 更新時に親側に入力データを渡すためのcallback
        callbackprm: {
          type: Function,
          require: false
        }
      },
      data () {
        return {
          slipDialogVisible: false,
          "後略": duumy
          }
        }
      },
      mounted: function () {
        // 生成時に、親要素に追加
        this.parent.appendChild(this.$el)
      },
      methods: {
        // ダイアログにデータをセットする為の親から呼ばれる関数
        setSlipData: function (slipdata) {
          // ・・中略・・
        },
        // ダイアログを表示する為に親から呼ばれる関数
        show: function () {
          this.slipDialogVisible = true
        },
        // 削除ボタン押されたときの内部処理
        ondelsubmit: function () {
          this.onsubmitsub('del')
        },
        // 更新ボタン押されたときの内部処理
        onupdsubmit: function () {
          this.onsubmitsub('upd')
        },
        onsubmitsub: function (mode) {
          // ・・中略・・
          var self = this
          this.$axios.post(this.apienv.baseendpoint + 'slip', slipdata, config).then(
            response => {
              self.slipDialogVisible = false
              self.$message({message: '登録しました', type: 'success'})
              if (self.callbackprm !== undefined) {
                // 更新成功したらcallbak関数を呼ぶ
                self.callbackprm(mode, slipdata)
              }
            }
          )
        }
      }
    }
    </script>
    
    
    호출방.vue
    <template>
          <!-- 中略 -->
            <!-- 編集対象データクリック時にダイアログ表示 -->
            <div v-for="(item, index) in sliplist" class="slip-item" :key="index" @click="slipedit">
              <!-- 中略 -->
            </div>
          <!-- 中略 -->
    </template>
    // ダイアログ側Vueの読み込み
    import SlipInputDlg from '@/components/SlipInputDlg'
    // ・・略・・
    // コンストラクタ宣言部
    const SlipInputDlgConstructor = Vue.extend(SlipInputDlg)
    // ・・略・・
    export default {
      // ・・略・・
      // 呼び出し側生成時に、ダイアログ側も生成
      mounted (e) {
        this.inputDlg = new SlipInputDlgConstructor({
          propsData: {
            parent: this.$el,
            // ・・略・・
            callbackprm: this.dlgCloseCallback
          }
        })
        this.inputDlg.$mount()
      },
      methods: {
        // 更新操作時、ダイアログに選択データの情報をセットして、表示
        slipedit: function (e) {
          var elements = e.target.parentNode.childNodes
          const idx = [].slice.call(elements).indexOf(e.target) - 1
          this.dlgeditidx = idx - 1
          this.inputDlg.setSlipData(this.sliplist[this.dlgeditidx])
          this.inputDlg.show()
        },
        // ダイアログ側で更新処理がされたときのcallback
        dlgCloseCallback: function (mode, newSlipData) {
          if (mode === 'upd') {
            // ・・親側データ更新。略・・
            // データ再読み込みしたくないので強制表示更新
            this.$forceUpdate()
          } else {
            this.sliplist.splice(this.dlgeditidx, 1)
          }
        },
        // ・・後略・・
      }
    }
    
    대화 상자 전체 텍스트 여기 있습니다.
    호출자 전문 여기 있습니다.

    실제 화면



    총결산

  • 만약 원형을 유지한다면 각 페이지의 삽입 요소가 되어 Vue 파일을 사용할 수 없습니다.
  • 보기만 하면 편하지만 대화상자에서 데이터를 편집하려면 데이터 집합 + 추출이 필요하고 처리가 필요합니다.
  • 좋은 웹페이지 즐겨찾기