なぜ Ref は Dom を操作するのに使いやすく効率的なのでしょうか?次の記事では、Ref の操作について説明し、Ref による Dom 取得の本質、Vue2.x と Vue3.x の違いなどを紹介します。皆さんの参考になれば幸いです。
プロジェクトを開発する前に、最初にニーズ分析を行うことがよくありますが、フロントエンドについては、作業効率を向上させるために基本的なコンポーネント ライブラリを調査または選択できます。結局のところ、時間コストを気にする企業にとって、カレンダーのようなコンポーネントを開発するためにテレビシリーズを見たりゲームをしたりする時間は得られません。ただし、市販されているすべてのコンポーネント ライブラリがニーズを満たすことができるわけではありません。現時点では、コンポーネントをプロジェクトに適用するには自分でコンポーネントを手書きする必要があります。
そして、これが私が言いたいことです: スケーラビリティを向上させ、需要の変化とその後のメンテナンスを容易にしながら、適用しやすいように (またはコードの量を減らして) コンポーネントを設計するにはどうすればよいでしょうか?
色々な方法があり、Refを使ってDomを操作するのもその一つですが、この方法だとModalやPopupの維持・操作、Domの表示やインタラクティブ非表示時の頻繁な操作が可能になります。コンポーネントに大きな利点をもたらします。 [関連する推奨事項: vuejs ビデオ チュートリアル 、Web フロントエンド開発 ]
Ref を操作する Dom の関連知識ポイントとアプリケーション例がいくつかに分かれています。分析してみましょう
Ref は Dom
Vue オブジェクトの本質を取得しますVue2.x では、属性 $refs は実際には登録されているすべての ref のコレクションであり、ref はテンプレート内のさまざまなコンポーネントまたは通常の Dom 要素に関連付けられた ref="xx" に対応します。ソース コードで ref を取得する実際の方法は次のとおりです。また、ネイティブ メソッド getElementById を使用して取得した Dom ノード; は、document.getElementById
の糖衣構文であると言えます。 vue3 の ref は vue2 の使用を継続し、レスポンシブ データを作成する機能も追加します。
ref と getElementById の両方で Dom を取得できるため、プロジェクト内で疑問に思う人もいるかもしれません。開発の場合、どちらの方法を選択しても違いはありませんか?
この問題に関しては、$refs を使用すると、document.getElementById メソッドと比較して dom ノードの取得の消費量が削減されることがデータで示されています。具体的な理由については、次の記事で詳しく説明します。
#Vue2.x と Vue3.x
<user-and-dep-tree-select-modal ref="avaUserTreeSelect" title="選擇可見範圍" :project-id="currentProjectId" :visible.sync="avaUserModalVisible" @ok="editAvailableUser" /> 或者 <div class="user" ref="user">dd</div>
// $refs showManagerModal () { this.$refs.avaUserTreeSelect.showModal(this.form.managers) console.log(this.$refs.user.text) },
//普通Dom <div class="user" ref="user"></div> //组件 <batch-adjust-department-modal ref="batchAdjustDepartmentRef" />
<script setup> import { ref } from 'vue'; // modal调整部门弹层Dom const batchAdjustDepartmentRef = ref(null); const user = ref(null); </script>
おそらくここで、テンプレートの参照と同じ名前の定数がなぜ使用されるのかについて質問している人がいるかもしれません。が宣言されています 変数は対応する DOM にバインドされていますか? ここで少し追加説明します:
Vue3 の以前のバージョン (3.0.0-beta.21 より前) でのコンポジション API のサポートは、使用されるコンポーネント オプション
<script> import { defineComponent, ref } from 'vue' export default defineComponent({ name: 'HelloWorld', setup(props, ctx) { const count = ref(0) function add() { count.value++ } // 使用return {} 把变量、方法暴露给模板 return { count, add, } }, }) </script>
<script setup>
がまだ実験機能段階にあることを示すメッセージが表示されます。
バージョン 3.2.0 の <script setup>
が正式にリリースされることが発表されています。常用化され安定したフレームワークとなるのも特徴の一つです。
コンポーネント オプションの setup
関数、<script setup>
と比較すると、記述する必要があるコードは少なくなり、より簡潔になるだけであり、return {}## を使用する必要はありません。 # 変数とメソッドを公開するには、コンポーネントを使用するときに積極的に登録する必要はありません。自動的にバインドされます。
したがって、 のように Vue オブジェクト自体がこの中に自動的に追加されます<script> |
|
---|---|
this.$ ref.user
| <p><strong><span style="font-size: 18px;">Ref操作组件Dom和父子组件单向传递</span></strong></p><p>props父传子,子通过emits传父,这样单方向传递,在控制弹层组件的显示和隐藏方面也可以实现,但是如此一来,我们就会像下面一样
父组件</p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false;"><template>
<exchange-valid-modal-vue v-model:visible="visibleExchange" />
</template>
<script setup>
// 转让管理员组件
import ExchangeValidModalVue from &#39;./modal/ExchangeValidModal.vue&#39;;
// modal弹层
const visibleExchange = ref(false); // 转让管理员可视化
const onExchangeAdmin = () => {
visibleExchange.value = true;
};
</script></pre><div class="contentsignin">ログイン後にコピー</div></div><p>子组件<code>ExchangeValidModalVue.vue <template> <t-dialog v-model:visible="visibleExchange" header="转让主管理员" attach="body" width="384px" :confirm-on-enter="true" :on-close="onCloseExchange" /> </template> <script setup> const visibleExchange = ref(false); const props = defineProps({ data: { type: Object, default: () => {}, }, visible: { type: Boolean, default: false, }, }); watch( () => props.visible, (cur, pre) => { visibleExchange.value = cur; if (cur) { firstTag.value = 1; } }, ); watch( () => visibleExchange.value, (cur, pre) => { emits('update:visible', cur); }, ); </script> ログイン後にコピー 从代码里面我们就可以发现通过用父子组件单向传递的方式去实现一个组件的显示和隐藏功能,我们需要如此费劲地声明多个变量,还要做两次监听,万一后面不止一个这样的参数进行传递,那么代码量可想而知,而且也不易维护。 其实显示和隐藏的功能可以直接在内部中进行值的响应即可,并不需要在父级别中操作,如下将上面代码改变一下: 子组件 <template> <t-dialog v-model:visible="visible" header="转让主管理员" attach="body" width="384px" :confirm-on-enter="true" :on-close="onCloseExchange" /> </template> <script setup> import { ref } from 'vue'; const visible = ref(false); const emits = defineEmits(['call']); const onEmitSelectSuperiod = () => { // 省略 emits('call'); }; const onOpen = () => { visible.value = true; }; const onClose = () => { visible.value = false; }; defineExpose({ onOpen, onClose, }); </script> ログイン後にコピー 那么在父组件中,我们只需要通过ref得到该组件Dom,然后操作Dom内部的方法即可; 如:父组件改写 <template> <exchange-valid-modal-vue ref="exchangeRef" /> </template> <script setup> // 转让管理员组件 import ExchangeValidModalVue from './modal/ExchangeValidModal.vue'; // modal弹层 const exchangeRef = ref(null); // 转让管理员可视化 const onExchangeOpen = () => { exchangeRef.onOpen() // 直接操作dom里defineExpose暴露出来的方法 }; </script> ログイン後にコピー 如此,是不是比父子单向数据传递的方式更加高效易用?当然上面所说的只是我举的一个例子,当后续需要在组件内扩展功能也可按类似的方法代替单向数据流的方式扩展 但,请注意;这种操作dom方式,并不是什么场景下都是最佳的选择;我们可以分情况选择,比如当一些数据只需要在子组件的范畴中实现,而不需要父组件外加干涉的情况下,选择ref操作dom更为高效; 补充知识点:
|