Могу ли я передавать параметры в вычисленных свойствах в Vue.Js
можно передать параметр в вычисленных свойствах в Vue.Js. Я вижу, когда с помощью вычислений getters/setter они могут принимать параметр и назначать его переменной. как здесь из документация:
// ...
computed: {
fullName: {
// getter
get: function () {
return this.firstName + ' ' + this.lastName
},
// setter
set: function (newValue) {
var names = newValue.split(' ')
this.firstName = names[0]
this.lastName = names[names.length - 1]
}
}
}
// ...
Возможно ли это:
// ...
computed: {
fullName: function (salut) {
return salut + ' ' + this.firstName + ' ' + this.lastName
}
}
// ...
Если вычисляемое свойство принимает аргумент и возвращает желаемый результат. Однако, когда я пытаюсь это сделать, я получаю эту ошибку:
vue.common.js: 2250 Uncaught TypeError: fullName не является функцией (...)
Должен ли я использовать методы для таких случаев?
Ответы
Ответ 1
Скорее всего, вы хотите использовать метод
<span>{{ fullName('Hi') }}</span>
methods: {
fullName(salut) {
return '${salut} ${this.firstName} ${this.lastName}'
}
}
Более длинное объяснение
Технически вы можете использовать вычисляемое свойство с таким параметром, как этот:
computed: {
fullName() {
return salut => '${salut} ${this.firstName} ${this.lastName}'
}
}
(Спасибо Unirgy
за базовый код для этого.)
Разница между вычисляемым свойством и методом заключается в том, что вычисляемые свойства кэшируются и изменяются только при изменении их зависимостей. Метод будет оцениваться каждый раз, когда вызывается.
Если вам нужны параметры, то в таком случае обычно нет преимущества использования вычисляемой функции свойства по сравнению с методом. Хотя это позволяет вам связать параметризованную функцию-получатель с экземпляром Vue, вы теряете кеширование, поэтому не получаете никакого усиления, фактически вы можете нарушить реактивность (AFAIU). Вы можете прочитать больше об этом в документации Vue https://vuejs.org/v2/guide/computed.html#Computed-Caching-vs-Methods
Единственная полезная ситуация - когда вам приходится использовать геттер и вам необходимо его параметризовать. Такая ситуация возникает, например, в Vuex. в Vuex это единственный способ синхронно получить параметризованный результат из хранилища (действия асинхронные). Таким образом, этот подход указан в официальной документации Vuex для его получателей.https://vuex.vuejs.org/guide/getters.html#method-style-access
Ответ 2
Вы можете использовать методы, но я предпочитаю использовать вычисляемые свойства вместо методов, если они не мутируют данные или не имеют внешних эффектов.
Вы можете передать аргументы в вычисленные свойства таким образом (не документированные, но предлагаемые сопровождающими, не помнят где):
computed: {
fullName: function () {
var vm = this;
return function (salut) {
return salut + ' ' + vm.firstName + ' ' + vm.lastName;
};
}
}
EDIT: Пожалуйста, не используйте это решение, это только усложняет код без каких-либо преимуществ.
Ответ 3
Ну, с технической точки зрения, мы можем передать параметр вычисляемой функции, так же, как мы можем передать параметр функции getter в vuex. Такая функция является функцией, которая возвращает функцию.
Например, в геттерах магазина:
{
itemById: function(state) {
return (id) => state.itemPool[id];
}
}
Этот геттер может быть сопоставлен с вычисленными функциями компонента:
computed: {
...mapGetters([
'ids',
'itemById'
])
}
И мы можем использовать эту вычислительную функцию в нашем шаблоне следующим образом:
<div v-for="id in ids" :key="id">{{itemById(id).description}}</div>
Мы можем применить тот же подход для создания вычисленного метода, который принимает параметр.
computed: {
...mapGetters([
'ids',
'itemById'
]),
descriptionById: function() {
return (id) => this.itemById(id).description;
}
}
И используйте его в нашем шаблоне:
<div v-for="id in ids" :key="id">{{descriptionById(id)}}</div>
Говоря это, я не говорю здесь, что это правильный способ делать вещи с Vue.
Тем не менее, я мог заметить, что когда элемент с указанным ID мутируется в хранилище, представление автоматически обновляет его содержимое новыми свойствами этого элемента (привязка, кажется, работает очень хорошо).
Ответ 4
Вы можете передавать параметры, но либо это не способ vue.js, либо то, как вы делаете, неверно.
Однако есть случаи, когда вам нужно это сделать. Я покажу вам простой пример передачи значения вычисляемому свойству с использованием getter и setter.
<template>
<div>
Your name is {{get_name}} <!-- John Doe at the beginning -->
<button @click="name = 'Roland'">Change it</button>
</div>
</template>
И сценарий
export default {
data: () => ({
name: 'John Doe'
}),
computed:{
get_name: {
get () {
return this.name
},
set (new_name) {
this.name = new_name
}
},
}
}
Когда кнопка нажата, мы переходим к вычисленному свойству имя "Roland", а в set()
мы меняем имя от "John Doe" до "Roland".
Ниже приведен общий пример использования, когда вычисленный используется с геттером и сеттер. Скажем, у вас есть следующий магазин vuex:
export default new Vuex.Store({
state: {
name: 'John Doe'
},
getters: {
get_name: state => state.name
},
mutations: {
set_name: (state, payload) => state.name = payload
},
})
А в вашем компоненте вы хотите добавить v-model
к входу, но используя vuex store.
<template>
<div>
<input type="text" v-model="get_name">
{{get_name}}
</div>
</template>
<script>
export default {
computed:{
get_name: {
get () {
return this.$store.getters.get_name
},
set (new_name) {
this.$store.commit('set_name', new_name)
}
},
}
}
</script>
Ответ 5
Фильтры - это функциональность, предоставляемая компонентами Vue, которая позволяет применять форматирование и преобразования к любой части динамических данных вашего шаблона.
Они не изменяют данные компонентов или что-либо еще, но влияют только на вывод.
Скажем, вы печатаете имя:
new Vue({
el: '#container',
data() {
return {
name: 'Maria',
lastname: 'Silva'
}
},
filters: {
prepend: (name, lastname, prefix) => {
return '${prefix} ${name} ${lastname}'
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="container">
<p>{{ name, lastname | prepend('Hello') }}!</p>
</div>
Ответ 6
Вычисляемый можно считать имеет функцию. Таким образом, для примера на valdiation вы можете сделать что-то вроде:
methods: {
validation(attr){
switch(attr) {
case 'email':
const re = /^(([^<>()\[\]\.,;:\[email protected]\"]+(\.[^<>()\[\]\.,;:\[email protected]\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\[email protected]\"]+\.)+[^<>()[\]\.,;:\[email protected]\"]{2,})$/i;
return re.test(this.form.email);
case 'password':
return this.form.password.length > 4
}
},
...
}
Что вы будете использовать, как:
<b-form-input
id="email"
v-model="form.email"
type="email"
:state="validation('email')"
required
placeholder="Enter email"
></b-form-input>
Просто имейте в виду, что вы все равно пропустите кэширование, специфичное для computed.
Ответ 7
Да, существуют методы для использования параметров. Как и ответы, изложенные выше, в вашем примере лучше всего использовать методы, поскольку выполнение очень легкое.
Только для справки, в ситуации, когда метод является сложным и стоимость высокая, вы можете кэшировать результаты следующим образом:
data() {
return {
fullNameCache:{}
};
}
methods: {
fullName(salut) {
if (!this.fullNameCache[salut]) {
this.fullNameCache[salut] = salut + ' ' + this.firstName + ' ' + this.lastName;
}
return this.fullNameCache[salut];
}
}
Примечание: при использовании этого, отслеживание памяти при работе с тысячами
Ответ 8
Вы также можете передать аргументы геттерам, возвращая функцию. Это особенно полезно, если вы хотите запросить массив в хранилище:
getters: {
// ...
getTodoById: (state) => (id) => {
return state.todos.find(todo => todo.id === id)
}
}
store.getters.getTodoById(2) // -> { id: 2, text: '...', done: false }
Обратите внимание, что получатели, получаемые с помощью методов, будут запускаться каждый раз, когда вы их вызываете, и результат не кэшируется.
Это называется Access Method-Style Access, и оно документировано в документах Vue.js.
Ответ 9
computed: {
fullName: (app)=> (salut)=> {
return salut + ' ' + this.firstName + ' ' + this.lastName
}
}
когда вы хотите использовать
<p>{{fullName('your salut')}}</p>
Ответ 10
Я не совсем уверен, чего вы пытаетесь достичь, но выглядит так, как будто вы просто отлично используете метод вместо вычислений!