ホームページ ウェブフロントエンド jsチュートリアル v-model の使用方法と vue ポップアップ コンポーネントの実装を約束する方法

v-model の使用方法と vue ポップアップ コンポーネントの実装を約束する方法

May 28, 2018 pm 03:00 PM
promise v-model

今回はv-modelの使い方とvueポップアップコンポーネントの実装の注意点を紹介します。実際のケースを見てみましょう。

最近、会社は既存のバックエンド システムで書かれているバックエンド業務を持っていますが、この業務用に新しいバックエンド システムを別途作成するにはそれを引き出す必要があるため、vue コンポーネント ライブラリ既存のバックエンドシステムは使用できません(将来のシステムがどのようなコンポーネントライブラリをベースにするかわからないため、今後の移植プロジェクトに迷惑をかけないようにするため)。私のビジネスでは、手動でしか書くことができませんでした(ただし、ポップアップ ウィンドウ コンポーネントは非常に単純です。私はそれを自分で要約したいだけです。間違いがあれば指摘してください)。従来の props と $emit を使用しました。最初に説明しましたが、キャンセルと確認の 2 つのコールバックのロジックが分散していると感じたので、コールバック メソッドを 2 つまとめて記述していますが、これは必ずしも良いアイデアを提供しているとは言えません。

1. 概要

最初に最後の呼び出しメソッドを見てみましょう

props $emit メソッド

<chat-modal ref="chat-modal" v-model="showModal" cancelText="取消" sureText="确认" title="弹窗标题" small @on-ok="onOK" @on-cancel="onCancel">
  <p>slot的东西,想向弹窗中添加自定义的内容</p>
</chat-modal>
methods: {
  display() {
   this.showModal = true;//交互点击手动触发显示弹窗 
  },
  onOK() {},//点击确认的回调
  onCancel() {}//点击取消的回调
}
ログイン後にコピー

promise コールバック メソッド

<chat-modal ref="chat-modal"></chat-modal>
methods: {
  display() {
    this.$refs["chat-modal"].openModal({
      title: "弹窗标题",
      sureText: "确认",
      cancelText: "取消"
    }).then(res => {
      //点击确认的回调
    }, res => {
      //点击取消的回调
    })
  }
}
ログイン後にコピー

2 番目のメソッドの利点は、すべてのロジックが集中化されていることです。メソッドに。

2. コンポーネントのソースコードを見てください

ヒント: スタイルが少し悪いです...

<template>
  <p>
    <p class="shadow" v-show="showModal"></p>
    <p class="modal" :class="{&#39;smSize&#39;: otherText.small || small}" v-show="showModal">
      <p class="header">{{ otherText.title || title}}</p>
      <p class="body">
        <slot></slot>
      </p>
      <p class="footer">
        <p class="item success" id="sure" ref="sure" @click="makeSure" v-show="otherText.sureText || sureText">{{ otherText.sureText || sureText }}</p>
        <p class="item red" id="cancel" ref="cancel" @click="makeCancel" v-show="otherText.cancelText || cancelText">{{ otherText.cancelText || cancelText }}</p>
      </p>
    </p>
  </p>
</template>
<script>
//此组件提供两种调用方法,可以在组件上v-model一个表示是否显示弹窗的对话框,然后需要的一些值通过props传入,然后$emit在组件上@监听做回调
//第二中方法所有的传值回调都只需要在组件内部的一个方法调用然后在组件外部this.$refs[xxx].open调用然后.then触发回调,比上一种方便些
var initOtherText = {
  sureText: "",
  cancelText: "",
  title: "",
  small: false
};
export default {
  props: {
    title: {
      type: String
    },
    sureText: {
      type: String
    },
    cancelText: {
      type: String
    },
    value: {
      type: Boolean
    },
    small: {
      type: Boolean
    }
  },
  watch: {
    value(newVal) {
      this.showModal = newVal;
    }
  },
  data() {
    return {
      otherText: JSON.parse(JSON.stringify(initOtherText)),
      showModal: this.value
    };
  },
  methods: {
    makeSure() {
      this.$emit("on-ok");
      this.$emit("input", false);
    },
    makeCancel() {
      this.$emit("on-cancel");
      this.$emit("input", false);
    },
    openModal(otherText) {
      this.otherText = { ...otherText };
      this.showModal = true;
      var pms = new Promise((resolve, reject) => {
        this.$refs["sure"].addEventListener("click", () => {
          this.showModal = false;
          resolve("点击了确定");
        });
        this.$refs["cancel"].addEventListener("click", () => {
          this.showModal = false;
          reject("点击了取消");
        });
      });
      return pms;
    }
  }
};
</script>
<style lang="scss" scoped>
.shadow {
  background-color: rgba(0, 0, 0, 0.5);
  display: table;
  height: 100%;
  left: 0;
  position: fixed;
  top: 0;
  transition: opacity 0.3s ease;
  width: 100%;
  z-index: 50;
}
.modal {
  display: table-cell;
  vertical-align: middle;
  overflow-x: hidden;
  position: fixed;
  background-color: white;
  box-shadow: rgba(0, 0, 0, 0.33) 0px 2px 8px;
  border-radius: 5px;
  outline: 0px;
  overflow: hidden;
  transition: all 0.3s ease;
  width: 600px;
  height: 400px;
  top: 50%;
  left: 50%;
  margin-top: -200px;
  margin-left: -300px;
}
.header {
  align-items: center;
  background-color: #62a39e;
  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.16);
  color: #fff;
  font-weight: bold;
  display: -ms-flexbox;
  display: flex;
  height: 3.5rem;
  padding: 0 1.5rem;
  position: relative;
  z-index: 1;
}
.body {
  align-items: center;
  padding: 1.5rem;
}
.footer {
  justify-content: flex-end;
  padding: 1.5rem;
  position: absolute;
  bottom: 0;
  width: 100%;
  float: right;
}
.item {
  color: white;
  text-align: center;
  border-radius: 5px;
  padding: 10px;
  cursor: pointer;
  display: inline-block;
}
.info {
  background-color: #2196f3;
}
.success {
  background-color: #62a39e;
}
.red {
  background-color: #e95358;
}
.smSize {
  height: 200px;
}
</style>
ログイン後にコピー

まず最初のメソッドを分析します: 呼び出し元は変数を v にバインドする必要があります-model (例: showModal) をコンポーネントの外に追加し、ポップアップ ウィンドウを表示するかどうかを指定します。コンポーネントの外で this.showModal = true を手動で設定する必要があります。この値を値として受け取るプロパティを定義します: {type: Boolean } 。同時に、コンポーネント内で変数が宣言され、外部から渡された props 値を同期します。デフォルト値は showModal: this.value (内部的に宣言された値は showModal とも呼ばれます)、監視で同期が監視されます。 watch: { value(newVal) { this.showModal = newVal } } ;次に、コンポーネント内の showModal 値を DOM にバインドします。表示または非表示にする必要がある要素。このイベントは、コンポーネント内の [OK] ボタンと [閉じる] ボタンがクリックされるとスローされます this.showModal = true ,组件内部props定义一个属性来接这个值为 value: {type: Boolean} ,同时在组件内部在用声明一个变量用来同步外部传进来的props值 默认值为 showModal: this.value (内部声明的值也叫了showModal),在watch中监听进行同步 watch: { value(newVal) { this.showModal = newVal } } ;然后把组件内部的这个showModal值绑定在需要显示或者隐藏的DOM元素上。向外抛出事件的时候是在点击组件内部的确定与关闭按钮时候

makeSure() {
      this.$emit("on-ok");
      this.$emit("input", false);
    },
makeCancel() {
      this.$emit("on-cancel");
      this.$emit("input", false);
    }
ログイン後にコピー

this.$emit("on-ok");this.$emit("on-cancel"); 这两句的是向外抛出事件在组件外部@接一下然后写自己需要的回调函数。这时就可以实现弹窗的显示与隐藏了,你可能发现并没有一句代码去设置this.showModal = false;弹窗就隐藏了。主要是因为这几句代码 v-model = 'showModal' 和 组件内部的 props: {value: {type: Boolean}} this.$emit("input", false) 。v-model其实是vue的语法糖, <chat-modal v-model="showModal"> 其实可以写为 <chat-modal :value="showModal" @input="showModal = arguments[0]"> 所以要求我们在组件内部必须规定props的名字必须为value, 然后在组件内部触发确定或者取消的时候在组件内部触发 this.$emit("input", false) 这样实现了直接隐藏弹窗而不必打扰用户让用户在组件外部在手动将showModal置为false.

然后来看promise的方式: 第一种方式传进来的值都通过props来接的,这种方式通过在组件内部定义了另一个对象来接传进来的值,

var initOtherText = {
  sureText: "",
  cancelText: "",
  title: "",
  small: false
};
otherText: JSON.parse(JSON.stringify(initOtherText)),
ログイン後にコピー

然后在menthods里定义了一个名为openModal的方法,然后把传进来的一系列参数赋值给组件内部的对象 this.otherText = { ...otherText }; this.showModal = true; 并且将showModal置为true,然后每次触发的时候新建一个promise对象,里面的异步事件为点击确定和取消的两个点击事件,这里要操作DOM了

this.$refs["sure"].addEventListener("click", () => {
  this.showModal = false;
  resolve("点击了确定");
});
ログイン後にコピー

获取确定按钮的DOM元素绑定点击事件,回调里将showModal置为false并且resolve,

this.$refs["cancel"].addEventListener("click", () => {
  this.showModal = false;
  reject("点击了取消");
});
ログイン後にコピー

获取取消按钮的DOM绑定点击事件,回调里reject.

遇到的坑

这之前遇到了一个坑,因为第一次已经绑定了点击事件,第二次resolve和reject就会失败,本想取消一下绑定事件,但是因为将整个弹窗v-show="showModal"

this.showModal = true;
var pms = new Promise((resolve, reject) => {
  this.$refs["sure"].addEventListener.xxx//省略
});
return pms;
ログイン後にコピー
ログイン後にコピー
this.$emit("on-ok");this.$emit("on-cancel") code>これら 2 つの文は、イベントをスローし、コンポーネントの外でイベントを取得し、必要なものを記述します コールバック関数🎜。このとき、ポップアップ ウィンドウを表示または非表示にすることができます。これを設定するコードがない場合があります。showModal = false; ポップアップ ウィンドウは非表示になります。主な原因は、コンポーネント内の v-model = 'showModal' および props: {value: {type: Boolean}} this.$emit("input", false) というコード行によるものです。 v-model は実際には vue の糖衣構文です。 <chat-modal v-model="showModal"> は実際には したがって、プロパティの名前がコンポーネント内の値である必要があることを指定し、確認またはキャンセル時にコンポーネント内で this をトリガーする必要があります。 $emit("input", false) このようにして、ユーザーの邪魔をせずにポップアップ ウィンドウを直接非表示にし、ユーザーがコンポーネントの外側で showModal を手動で false に設定できるようにすることができます。 🎜次に、Promise メソッドを見てください: 最初のメソッドは、渡された値をすべて props を通じて受け取ります。このようにして、渡された値を受け取る別のオブジェクトがコンポーネント内に定義されます。次に、openModal という名前のメソッドがあります。 menthods で定義され、コンポーネント this.otherText = { ...otherText }; this.showModal = true 内のオブジェクトに一連のパラメーターを割り当て、showModal を true に設定します。次に、オブジェクトがトリガーされるたびに新しい Promise を作成します。内部の非同期イベントは、クリック OK とキャンセルの 2 つのクリック イベントです。ここでは、DOM を操作する必要があります🎜
this.$refs["chat-modal"].openModal({
  title: "服务小结",
  sureText: "提交并结束",
  cancelText: "取消"
  }).then();
ログイン後にコピー
ログイン後にコピー
🎜クリック イベントをバインドするために OK ボタンの DOM 要素を取得します。コールバックで showModal を false に設定して解決し、🎜rrreee🎜get クリック イベントを cancel ボタンの DOM にバインドします。クリック イベントが初めてバインドされており、2 回目は解決して拒否されるため、バインド イベントをキャンセルしたいのですが、ポップアップ ウィンドウ全体が v-show="showModal" になっているためです。 " が表示されました: none;、DOM 全体を手動でバインド解除する必要はありません。 2つ目は、ポップアップウィンドウを非表示にするためにv-ifを使用するかv-showを使用するかについてです。最初はv-ifを使用していましたが、このステップでそれが判明しました🎜。
this.showModal = true;
var pms = new Promise((resolve, reject) => {
  this.$refs["sure"].addEventListener.xxx//省略
});
return pms;
ログイン後にコピー
ログイン後にコピー

将showModal置为true时然后就去绑定事件这时候还没有DOM还没有解析玩DOM树上还没有,要不就得用this.$nextTick增加了复杂度,最后采用了v-show;

关于优先级问题

如果既在组件上用prop传了值(title,sureText之类的)如 <chat-modal" title="xx" sureText="xxx"></chat-modal> 也在方法里传了

this.$refs["chat-modal"].openModal({
  title: "服务小结",
  sureText: "提交并结束",
  cancelText: "取消"
  }).then();
ログイン後にコピー
ログイン後にコピー

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

如何使用Vue内父子组件通讯todolist组件

如何使用Vue整合AdminLTE模板

以上がv-model の使用方法と vue ポップアップ コンポーネントの実装を約束する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

v-model.number を使用して Vue で入力ボックスのデータ型変換を実装する方法 v-model.number を使用して Vue で入力ボックスのデータ型変換を実装する方法 Jun 11, 2023 am 08:54 AM

Vue では、v-model は双方向バインディングの実装に使用される重要な命令であり、ユーザー入力を Vue のデータ属性に簡単に同期できるようにします。ただし、ユーザーが入力した文字列型を数値型に変換するなど、データを変換する必要がある場合には、v-model の .number 修飾子を使用する必要があります。 v-model.number の基本的な使い方 v-model.number は v-model を修正したものです

約束を守る: 約束を守ることの長所と短所 約束を守る: 約束を守ることの長所と短所 Feb 18, 2024 pm 08:06 PM

日常生活では、約束と履行の間で問題に遭遇することがよくあります。個人的な関係でもビジネス取引でも、約束を守ることが信頼を築く鍵となります。ただし、コミットメントの是非についてはしばしば議論の余地があります。この記事では、約束の長所と短所を検討し、約束を守る方法についていくつかのアドバイスを提供します。約束されたメリットは明らかです。まず、コミットメントは信頼を築きます。人が約束を守るとき、その人は信頼できる人であると他人に信じ込ませます。信頼は人々の間に確立される絆であり、それは人々をより良くすることができます

Vue アプリケーションで Uncaught (in Promise) TypeError が発生した場合はどうすればよいですか? Vue アプリケーションで Uncaught (in Promise) TypeError が発生した場合はどうすればよいですか? Jun 25, 2023 pm 06:39 PM

Vue は人気のあるフロントエンド フレームワークであり、アプリケーションを開発するときにさまざまなエラーや問題に遭遇することがよくあります。このうち、Uncaught(inpromise)TypeError は一般的なエラー タイプです。この記事では、その原因と解決策について説明します。 Uncaught(inpromise)TypeError とは何ですか? Uncaught(inpromise)TypeError エラーは通常、次の場所に表示されます。

Promise.resolve() について詳しく見る Promise.resolve() について詳しく見る Feb 18, 2024 pm 07:13 PM

Promise.resolve() の詳細な説明には、特定のコード例が必要です。Promise は、非同期操作を処理するための JavaScript のメカニズムです。実際の開発では、順番に実行する必要があるいくつかの非同期タスクを処理する必要があることがよくあり、満たされた Promise オブジェクトを返すために Promise.resolve() メソッドが使用されます。 Promise.resolve() は Promise クラスの静的メソッドであり、

Vue で v-model の双方向バインディングを使用してアプリケーション データのパフォーマンスを最適化する Vue で v-model の双方向バインディングを使用してアプリケーション データのパフォーマンスを最適化する Jul 17, 2023 pm 07:57 PM

Vue で v-model の双方向バインディングを使用してアプリケーション データのパフォーマンスを最適化する Vue では、v-model ディレクティブをよく使用して、フォーム要素とデータの間の双方向バインディングを実現します。この双方向バインディングにより、開発プロセスが大幅に簡素化され、ユーザー エクスペリエンスが向上します。ただし、v-model は form 要素の入力イベントをリッスンする必要があるため、データ量が多い場合、この双方向バインディングにより特定のパフォーマンスの問題が発生する可能性があります。この記事では、v-model を使用してデータ パフォーマンスを最適化し、

Vue エラー: v-model は双方向データ バインディングに正しく使用できません。解決方法は? Vue エラー: v-model は双方向データ バインディングに正しく使用できません。解決方法は? Aug 19, 2023 pm 08:46 PM

Vue エラー: v-model は双方向データ バインディングに正しく使用できません。解決方法は?はじめに: 双方向データ バインディングは、Vue で開発する場合に非常に一般的で強力な機能です。ただし、場合によっては問題が発生することがあります。つまり、双方向データ バインディングに v-model を使用しようとすると、エラーが発生します。この記事では、この問題の原因と解決策について説明し、問題の解決方法を示すコード例を示します。問題の説明: Vue で v-model を使用しようとすると

Vue エラーの解決方法: 双方向データ バインディングに v-model を正しく使用できません Vue エラーの解決方法: 双方向データ バインディングに v-model を正しく使用できません Aug 25, 2023 pm 04:13 PM

Vue エラーを解決する方法: 双方向データ バインディングに v-model を正しく使用できません はじめに: Vue は、双方向データ バインディングを実装するための v-model ディレクティブなど、多くの便利な機能を提供する人気のあるフロントエンド フレームワークです。ただし、v-model を使用するとき、特に複雑なデータ構造を扱うとき、エラーが発生することがあります。この記事では、いくつかの一般的な v-model エラーを紹介し、解決策とコード例を示します。エラー: v-model プロパティとオブジェクト プロパティの双方向バインディング

Vue エラーの解決: 双方向データ バインディングに v-model を使用できません Vue エラーの解決: 双方向データ バインディングに v-model を使用できません Aug 25, 2023 pm 04:49 PM

Vue エラーの解決: 双方向データ バインディングに v-model を使用できません。Vue で開発する場合、双方向データ バインディングを実現するために v-model 命令がよく使用されますが、v-An エラーを使用すると問題が発生することがあります。モデルの使用時に報告され、双方向のデータ バインディングを正しく実行できません。これは、いくつかの一般的なエラーが原因である可能性がありますので、以下にいくつかの一般的な状況とそれに対応する解決策を紹介します。コンポーネントの props 属性が正しく設定されていません。コンポーネントを使用するときに、v- を渡す必要がある場合は、

See all articles