在 Option API 使用 ref 來操控 DOM 元素

在原生的 Java Script 中常常會使用 id 來取得 DOM 元素,但是開發到最後常常會用了太多的 id,搞的 id 的名稱互相衝突。在 VUE 中提供了 $refs 的方法,讓我們用 ref 代替 id 來取得 DOM 元素。

ref 的作用:

  • 用來選取與操控 DOM 元素。
  • 用來取得元件的內容。
  • Bootstrap Modal 元件的封裝。

使用 ref 取得 DOM 元素

input 標籤中加入 ref="inputDom",就可以在 Vue 中使用 this.$refs.inputDom選取到 input 輸入框。

HTML 部分

<div id="app">
  <h3>使用 ref 定義元素</h3> 
  message: <br>
  <input type="text" ref="inputDom">
</div>

Vue.js 部分

const app = {
  data() {
    return {     
    }
  },
  methods:{
   
  },
  mounted() {
    console.log(this.$refs);
  }
}
Vue.createApp(app).mount('#app')

如圖所示,console.log(this.$refs);顯示取得的 DOM 元素。

讓 輸入框 一載入就 focus

https://codepen.io/popeye_ux/pen/ExeZKKM?editors=1111

使用 ref 來取得 DOM 元素的內容

我們在 Vue 的實體上註冊了一個 <card> 元件,在 HTML 中插入 <card ref="card"> </card>,同時可以看到在 ref 屬性中定義了 card 的 DOM 名稱。

HTML 的部分

<div id="app">
  <h3>使用 ref 更新元件內容</h3>  
  <card ref="card"> </card>
  <button @click="getComponentInfo">取得元件資訊</button>
</div>

Vue.js 的部分

我們在 card 元件的 data 中定義了:

title:'文件標題',
content:'文件內文',

然後在父元件中定義了這樣的方法:

getComponentInfo(){
    console.log(this.$refs.card)
    this.$refs.card.title = '被更新的元件標題'
    this.$refs.card.content = '被更新的內文'
}

然後把 getComponentInfo() 方法綁定到 HTML 的 <button> 上面,就可以取得 <car> 元件裡的內容。

Vue.js 的完整內容

const app = Vue.createApp( {
  data() {
    return {     
    }
  },
  methods:{
   getComponentInfo(){
     console.log(this.$refs.card)
     this.$refs.card.title = '被更新的元件標題'
     this.$refs.card.content = '被更新的內文'
   }
  },
  mounted() {
    console.log(this.$refs);
  }
})
app.component('card',{
  data(){
    return{
      title:'文件標題',
      content:'文件內文',
    }
  },
  template: `
  <div class="card" width="18rem">
  <h3>{{title}}</h3>
  <p>{{content}}</p>
  </div>
  `
})
app.mount('#app')

在 CodePen 上看看如何實作:

Bootstrap Modal 封裝

我們也可以利用 ref 來操作 Bootstrap Modal 的開關。

首先到 Bootstrap 官網把 Modal 的 HTML 碼 COPY 過來。

<div id="app">
<div class="btn btn-primary" @click="openModal"> 開啟 Modal </div>
    
<-- Modal -->
  <div class="modal" tabindex="-1" ref="modal">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title">Modal title</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>
      <div class="modal-body">
        <p>Modal body text goes here.</p>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
        <button type="button" class="btn btn-primary">Save changes</button>
      </div>
    </div>
  </div>
</div>
</div>


其次把 Bootstrap 使用 JavaScript 操控 Modal 的方法 COPY 到 Mounted() 中:

var myModal = new bootstrap.Modal(document.getElementById('myModal'), options)

接著改成下面這樣,new bootstrap.Modal 是用來建立一個 Modal 實體,this.bsModal 要在 data 中定義:

this.bsModal = new bootstrap.Modal(this.$refs.modal);

methods 中定義打開 Modal 的方法,然後綁定到按鈕上面,(.show() 是 Bootstrap Modal 所提供的方法):

openModal() {
      this.bsModal.show();
    }
const app = Vue.createApp({
  data() {
    return {
      bsModal: ""
    };
  },
  methods: {
    openModal() {
      this.bsModal.show();
    }
  },
  mounted() {
    console.log(this.$refs);
    // var myModal = new bootstrap.Modal(document.getElementById('myModal'), options)
    // 建立實體
    this.bsModal = new bootstrap.Modal(this.$refs.modal);
  }
});

app.mount("#app");

在 Option API 使用 ref 來操控 DOM 元素
https://popeye-ux.github.io/2023/02/28/vue-option-ref-basics/
作者
POPEYE
發布於
2023年2月28日
許可協議