【发布时间】:2020-08-12 05:54:18
【问题描述】:
我正在尝试扩展 vuetify VTextField 组件以创建可重用的 password-field。有许多 props 可以控制我们需要改变的组件。 Vuejs 认为 prop 突变是一种“反模式”并警告它。
我已经尝试过声明一个计算属性来覆盖有效的道具,但它会在网络控制台中抛出有关冲突的警告。
这是一个简单的例子:
import Vue from 'vue'
import { VTextField } from 'vuetify/lib'
export default Vue.extend({
name: 'password-field',
mixins: [VTextField],
data: () => ({
reveal: false
}),
computed: {
function type () {
return this.reveal ? 'text' : 'password'
}
}
})
感觉应该不用使用 mixins 来扩展 VTextField 并有选择地删除我们想要用计算属性替换的道具。最后,我们需要该值是响应式的,并且在 password-field 组件的控制之下 -- 不 由父组件控制。
我是不是走错方向了?
更新
借助Yom S () 提供的专家建议,我能够创建VTextField 的自定义扩展。我们采纳了他的建议 #2,一个 SFC 模板化组件。
对于任何偶然发现这个主题的人,这里是 Typescript 兼容的实现:
<!-- put this in components/password-field.vue -->
<template>
<v-text-field
v-bind="computedProps"
v-on:click:append="reveal = !reveal"
v-on="listeners$"
></v-text-field>
</template>
<script lang="ts">
import Vue from 'vue'
import { VTextField } from 'vuetify/lib'
export default {
name: 'PasswordField',
extends: VTextField,
props: {
label: {
type: String,
default: 'Password'
},
rules: {
type: Array,
default: () => [(v: string) => {
return /((?=.*\d)(?=.*[a-z])(?=.*[!@#$%^&*()?.]).{8,})/i.test(v) ||
'At least 8 char; upper and lowercase, a number and a special char'
}]
}
},
data: () => ({
reveal: false
}),
computed: {
computedProps: function () {
return {
...this.$props,
type: this.reveal ? 'text' : 'password',
appendIcon: this.reveal ? 'mdi-eye' : 'mdi-eye-off'
}
}
}
} as Vue.ComponentOptions<Vue>
</script>
这里有一个如何使用这个组件的简单例子
<template>
<v-form v-model="formValid">
<password-field v-model="newPassword/>
<v-btn :disabled="!formValid">Change</v-btn>
</v-form>
</template>
<script lang="ts">
import Vue from 'vue'
import PasswordField from '@/components/password-field.vue'
export default Vue.extend({
name: 'ChangePasswordForm',
data: () => ({
formValid: false,
newPassword: ''
})
})
</script>
【问题讨论】:
-
感谢您的链接...但这还不是答案。我们可以轻松地覆盖扩展中的道具。问题是我们需要它具有反应性并受子组件的控制。这需要我们改变 prop,这是不能/不应该做的。
-
我为不同的目的定制了几个 Vuetify 组件,但与您想要实现的目标不同。对于我的案例,我使用了计算的 props,但也使用了作为函数传递的 props,允许自定义组件根据它获得的 props 函数列表做出不同的响应和行为
标签: typescript vue.js vuetify.js