Чи можу я передавати параметри в обчислюваних властивостях у Vue.Js


199

чи можливо це передавати параметр у обчислюваних властивостях у 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 не є функцією (…)

Чи слід використовувати методи для таких випадків?


5
Ні, ви не можете передавати параметри обчисленим властивостям. Так, використання методів - це найпростіший спосіб зробити це.
nils

Відповіді:


269

Найімовірніше, ви хочете скористатися методом

<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


1
Використання <span v-text="fullName('Hi')"></span>натомість також працює.
SalchiPapa

2
Проблема полягала в тому <span :text="message"></span>, що більше не працює Vue 2.0, замість цього потрібно використовувати: <span v-text="message"></span>або <span>{{ message }}</span>як показано в цьому codepen: codepen.io/Ismael-VC/pen/dzGzJa
SalchiPapa

1
Ти маєш рацію. Я не помітив, що це було змінено в 2.0. Дякуємо за виправлення!
damienix

4
Для обчислених властивостей використовується синтаксис Getter ES5, який не підтримує виклик його жодними параметрами (немає дужок). Отже, це обмеження на рівні мови, і саме тому він включений у Vue.js.
damienix

1
Вибачте за дуже пізню відповідь @PedroMoreira, я просто знайшов час, щоб проаналізувати це. Дійсно, ти маєш рацію, що те, що я написав, було не зрозумілим і переплутаним :) Я зафіксував відповідь і зробив все можливе, щоб перефразовувати її, щоб зробити більш зрозумілою та точною. Ви можете мені повідомити, якщо зараз це зрозуміло. Дякую.
damienix

27

Ви можете використовувати методи, але я все ж віддаю перевагу використовувати обчислювані властивості замість методів, якщо вони не мутують дані або не мають зовнішніх ефектів.

Ви можете передавати аргументи обчислюваним властивостям таким чином (не задокументовано, але запропоновано обслуговуючими особами, не пам'ятайте, де):

computed: {
   fullName: function () {
      var vm = this;
      return function (salut) {
          return salut + ' ' + vm.firstName + ' ' + vm.lastName;  
      };
   }
}

EDIT: Будь ласка, не використовуйте це рішення, воно лише ускладнює код без будь-яких переваг.


Буде дуже корисно, якщо ви зможете надати довідку. Це має спрацювати.
Саурах

@saurabh вибачте, що це було рішення не дуже описового питання в github, і я не можу його знайти зараз ...
Unirgy

Це працює для мене, але єдине, що я не фанат, - це те, що він повертає функцію, а не власне властивість, тому розробники VueJS ніде не показують результати. Я не впевнений, що це характерно для обчислених властивостей, але це робить усунення несправностей трохи складніше.
Нейт Ріттер

4
Як він обробляє кешування? Чи справно працюватиме при зміні параметра?
damienix

Я не вірю, що це би кешувало щось у функції повернення. Відмінність від методів
полягала

8

Ну, технічно кажучи, ми можемо передати параметр обчисленій функції, так само, як ми можемо передати параметр функції 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.

Однак я міг зауважити, що коли елемент із зазначеним ідентифікатором мутується у магазині, представлення автоматично оновить його вміст новими властивостями цього елемента (прив’язка, здається, працює чудово).


Так, це працювало для мене, не використовуючи vuex. Також хотілося б знати, чи це законний спосіб робити обчислені властивості.
yeahdixon

1
Хоча це і працює, воно по суті трактує обчислену властивість так само, як і метод. тобто він втрачає переваги кешування обчисленої властивості. Отже, фактичного виграшу від використання цього методу немає. "Зауважте, що користувачі, доступ до яких здійснюється за допомогою методів, запускатимуться кожного разу, коли ви їх будете викликати, а результат не буде кешований." Дивіться vuex.vuejs.org/uk/getters.html
Джеймс

@ james.brndwgn, але я впевнений, що методи не будуть повторені, коли змінити основні дані. Це все, що я справді шукаю.
Алекс

@ Алекс, то ви повинні використовувати вахту. vuejs.org/v2/guide/computed.html#Watchers
Джеймс

@ james.brndwgn Я набагато скоріше використовую обчислюване властивість, ніж спостерігач, якщо це можливо. Я лише заперечував із вашою заявою: "Отже, реальної вигоди від використання цього методу немає". оскільки існує значна різниця навіть без кешування.
Алекс

4

Фільтри - це функція, що надається компонентами 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>

Зауважте синтаксис, щоб застосувати фільтр, який є | filterName. Якщо ви знайомі з Unix, це оператор труб Unix, який використовується для передачі результату операції як вхід до наступного.

Властивість фільтрів компонента є об'єктом. Один фільтр - це функція, яка приймає значення і повертає інше значення.

Повернене значення - це те, що фактично надруковано у шаблоні Vue.js.


3

Ви також можете передавати аргументи Getters, повертаючи функцію. Це особливо корисно, коли ви хочете запитувати масив у магазині:

getters: {
  // ...
  getTodoById: (state) => (id) => {
    return state.todos.find(todo => todo.id === id)
  }
}
store.getters.getTodoById(2) // -> { id: 2, text: '...', done: false }

Зауважте, що користувачі, доступ до яких здійснюється за допомогою методів, запускатимуться кожного разу, коли ви їх будете викликати, а результат не буде кешований.

Це називається метод-Style доступ і документовано на документах Vue.js .


2

Ви можете передавати параметри, але або це не спосіб 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.

<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>

1

Я не повністю впевнений, чого ви намагаєтеся досягти, але схоже, що вам буде ідеально добре, використовуючи метод замість обчислених!


1
computed: {
  fullName: (app)=> (salut)=> {
      return salut + ' ' + this.firstName + ' ' + this.lastName    
  }
}

коли ви хочете використовувати

<p>{{fullName('your salut')}}</p>

1

Обчислена, можна вважати, має функцію. Отже, для прикладу валідації ви можете чітко зробити щось на кшталт:

    methods: {
        validation(attr){
            switch(attr) {
                case 'email':
                    const re = /^(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{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>

Пам’ятайте лише про те, що ви все одно будете пропускати кешування, характерне для обчислених.


0

Так, існують методи використання парам. Як і відповіді, зазначені вище, у вашому прикладі найкраще використовувати методи, оскільки виконання дуже легке.

Тільки для довідок, у випадку, коли метод складний, а вартість висока, ви можете кешувати результати таким чином:

data() {
    return {
        fullNameCache:{}
    };
}

methods: {
    fullName(salut) {
        if (!this.fullNameCache[salut]) {
            this.fullNameCache[salut] = salut + ' ' + this.firstName + ' ' + this.lastName;
        }
        return this.fullNameCache[salut];
    }
}

Примітка. Використовуючи це, слідкуйте за пам'яттю, якщо маєте справу з тисячами

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.