如何将Vue指令应用于Vuetify自定义组件



我有一些vuetify自定义组件(输入组件(,如下所示:

// Component 
<v-text-field 
background-color="#ffffff"
outlined 
dense
hide-details
class="text-field"
:class="textFieldClass"
v-model="content"
:disabled="disabled"
:rules="textFieldRules"
@keydown="handleKeydown"
:maxlength="maxLength"
:error="textFieldError"
></v-text-field>

//Parent
<v-container>
<v-row class="d-flex justify-center">
<v-col cols="4">
<div class="d-flex justify-center">
<label class="input-label"> Insert data </label>
</div>
<InputTextField v-uppercase :textFieldRules="[rules.inputDataFormat]" :textFieldContent.sync="inputData"></InputTextField>
</v-col>
</v-row>
</v-container>

我正在尝试使用一个名为";大写";在我的组件上:

import Vue from "vue";
export const InputCase = {
update: function (el) {
el.value = el.value.toUpperCase();
}
};
Vue.directive("uppercase", InputCase);

但我发现vuetify组件没有value属性,所以它不起作用。我该怎么解决这个问题?

您将指令应用于自定义组件InputTextField,而不是直接应用于Vuetify的v-text-field,因此我发现Vuetify组件没有value属性的语句是不正确的您的组件没有value属性。v-text-field支持v-model

但这在这里并不重要。问题是Vue指令的级别相当低。来自文档:

请注意,在Vue 2.0中,代码重用和抽象的主要形式是组件,但在某些情况下,您可能需要对普通元素进行一些低级DOM访问,而这正是自定义指令仍然有用的地方。

So指令直接在DOM级别上操作,而不是在组件级别上操作。传递到指令挂钩中的el不是组件实例,它始终是在呈现组件时生成的DOM元素。这一点现在已经在Vue 3 docs 中得到了适当的记录

所以你的指令(可能取自这个So的答案(不会起作用。一个解决方案可以基于另一个答案-自定义指令v-focus不适用于vuetify组件-但它对vuetify组件的呈现方式进行了一些假设。也可以查看这个论坛线程的复杂性和其他解决方案。。。

就我个人而言,我不会走指令路线,并坚持Vue作者给出的建议-代码重用和抽象的主要形式是组件

注意:我真的不喜欢InputTextField自定义输入的界面。Vue中的输入处理是基于v-model的,而您团队中的其他开发人员已经习惯了它。为什么要让您的自定义输入(本质上是一个包装器(有所不同?

您已经有了一个自定义组件InputTextField,因此应该可以很容易地添加简单的布尔属性,例如uppercase,并将其与基于计算的v-model实现一起使用,如下所示:

Vue.component('custom-input', {
props: {
value: {
type: String,
required: true
}, 
uppercase: {
type: Boolean,
default: false
}
},
template: `<input type="text" v-model="model">`,
computed: {
model: {
get() { return this.value },
set(newVal) {
this.$emit('input', this.uppercase ? newVal.toUpperCase() : newVal)
}
}
},
watch: {
value: {
// to handle the situation when model value set by parent is not uppercase
handler: function(newValue) {
if(this.uppercase && newValue !== newValue.toUpperCase())
this.model = newValue
},
immediate: true
}
}
})
new Vue({
el: "#app",
data() {
return {
text: "Hello"
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.14/vue.js"></script>
<div id="app">
<custom-input v-model="text" :uppercase="true"></custom-input>
<pre>{{ text }}</pre>
</div>

当升级到Vue 3时,你可以去掉作为uppercase的独立道具,并轻松地重写你的组件,使用自定义的v-model修饰符

最新更新