2017-06-15 34 views
1

如何獲取引用Vue.js中引發方法的元素? 我有HTML這樣的:獲取Vue.js中引用元素的方法

<input type="text" v-model="dataField" v-bind:class="dataFieldClass" /> 

在我Vue.js的ViewModel我有一個方法:

dataFieldClass: function() { 
    // Here I need the element and get its ID 
    // Pseudo code 
    var elementId = $element.id; 
} 

我知道,它可以從事件獲得元素(V-上:點擊),但這不是一個事件,它是根據viewmodel的少數條件爲元素返回CSS類的簡單方法。它也應該是可以計算的,但問題是一樣的。

+0

的'dataFieldClass'方法不知道它使用了什麼元素當綁定到一個屬性。爲什麼要引用元素?什麼是用例? – thanksd

+0

我使用它來找到相應的CSS來顯示,並在類似的情況下確定是否啓用或禁用該元素(而不僅僅是這一個 - 如果其中一個輸入無效,則禁用其他幾個控件)。 有3-4個條件決定是否啓用該元素,所以我不想將一行長條件語句放入HTML綁定中,並且想要在方法中封裝該功能。 我使用vee-validate自動收集元素名稱的錯誤,並在決策過程中使用VeeValidate $ errors集合。 –

+0

但是那些基於html元素的條件?或者'dataField'對象? – thanksd

回答

-1

你可以簡單地傳遞參數給你的方法

<input type="text" v-model="dataField" v-bind:class="dataFieldClass(1) /> 

那麼你就可以抓住它

dataFieldClass (reference) { 
    var elementId = reference 
} 
+0

我知道我可以傳遞一個參數。但這不是我所需要的。 如何將引用傳遞給元素?或者也許只是它的一個屬性?當然,不是硬編碼的字符串。 –

+0

參數不一定是硬編碼的字符串。 –

+0

我們都知道如何傳遞參數。他想要DOM元素。最有可能的是,他可以從中獲得數據屬性。 – Grandizer

2

也許你可以使用ref

<input type="text" v-model="dataField" v-bind:class="dataFieldClass" ref="el" /> 

而且使用這樣的:

dataFieldClass: function() { 
    var elementId = this.$refs.el; 
} 

查看文檔在這裏:https://vuejs.org/v2/api/#ref

+0

好吧,dataFieldClass方法是從HTML中的許多輸入中調用的。我需要知道他們中的哪一個是呼叫者。然後捕獲其名稱(或ID)做一些測試並返回適當的類。 –

+0

你可以做''?然後使'dataFieldClass'成爲一個方法而不是一個計算的屬性。 –

+0

是的,我可以。其實這是我現在使用的解決方法,但我想知道是否有一種更優雅的方式來獲取函數中的調用元素。 jQuery有它,另一個JS框架Knockout.js有它,所以我希望Vue.js也有它。 如果不是使用id硬編碼字符串,而是動態地傳遞類似$ attribute(id)的東西,那就足夠了。 –

0

有關使用ref pattern什麼。將ref="someName"放入您的DOM元素中,並在您的方法中使用this.$refs["someName"]訪問它(您可以將'someName'作爲參數傳遞給您的方法)。

請注意,這不是一個很好的模式,除非由於某種原因您確實需要DOM元素。否則,只需將相關參數傳遞給您的方法。

這不是一個好方法,主要是因爲它有一個主要缺點:第一次渲染vue時沒有$ refs(因爲元素還沒有出現)。所以你應該強制vue渲染兩次。

如果在v-for循環中有多個元素,那麼這個.refs [「someName」]就成爲一個數組。你可以把它與一些適應工作,這裏有一個例子:

new Vue({ 
 
    el: '#app', 
 
    data() { 
 
    return { 
 
     fields: [{ 
 
      name: 'field1', 
 
      value: 'value1' 
 
     }, 
 
     { 
 
      name: 'field2', 
 
      value: 'value2' 
 
     } 
 
     ] 
 
    }; 
 
    }, 
 
    methods: { 
 
    dataFieldClass(index) { 
 
     if (!this.$refs.fields) { 
 
     // First render, the element is not there yet 
 
     return ''; 
 
     } else { 
 
     // Here is the element 
 
     console.log(this.$refs.fields[index]); 
 
     } 
 
    } 
 
    }, 
 
    mounted() { 
 
    // Force the instance to render a second time 
 
    this.$forceUpdate(); 
 
    } 
 
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.js"></script> 
 

 
<div id="app"> 
 
    <label v-for="(field, index) in fields"> 
 
    {{ field.name }}: 
 
    <input ref="fields" :value="field.value" v-bind:class="dataFieldClass(index)"> 
 
    </label> 
 
</div>