Vue.Js의 계산 속성에서 매개 변수를 전달할 수 있습니까


198

Vue.Js의 계산 속성에서 매개 변수를 전달할 수 있습니다. 계산 된 것을 사용하여 getter / 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은 함수가 아닙니다 (…)

그러한 경우에 방법을 사용해야합니까?


4
아니요, 계산 된 속성에는 매개 변수를 전달할 수 없습니다. 예, 방법을 사용하는 것이 가장 쉬운 방법입니다.
NILS

답변:


265

아마도 방법을 사용하고 싶을 것입니다.

<span>{{ fullName('Hi') }}</span>

methods: {
  fullName(salut) {
      return `${salut} ${this.firstName} ${this.lastName}`
  }
}

더 긴 설명

기술적으로 다음과 같은 매개 변수와 함께 계산 된 특성을 사용할 수 있습니다.

computed: {
   fullName() {
      return salut => `${salut} ${this.firstName} ${this.lastName}`
   }
}

(이에 Unirgy대한 기본 코드를 주셔서 감사 합니다.)

계산 된 속성과 메서드의 차이점은 계산 된 속성이 캐시 되고 종속성이 변경 될 때만 변경 된다는 것입니다. 방법은이 호출 할 때마다 평가합니다 .

매개 변수가 필요한 경우 일반적으로 이러한 경우 메서드보다 계산 된 속성 함수를 사용하면 이점이 없습니다. Vue 인스턴스에 바인딩 된 getter 함수를 매개 변수화 할 수는 있지만 캐싱을 잃어 실제로 아무런 이득을 얻지 못하므로 실제로는 반응성을 깰 수 있습니다 (AFAIU). Vue 문서 https://vuejs.org/v2/guide/computed.html#Computed-Caching-vs-Methods 에서 이에 대한 자세한 내용을 볼 수 있습니다.

유용한 상황은 게터 사용해야하고 매개 변수화해야하는 경우입니다. 이 상황은 예를 들어 Vuex 에서 발생 합니다. Vuex에서는 상점에서 매개 변수화 된 결과를 동 기적으로 얻을 수있는 유일한 방법입니다 (동작은 비동기 임). 따라서이 방법은 공식 Vuex 설명서에 나와 있으며 getter https://vuex.vuejs.org/guide/getters.html#method-style-access


1
<span v-text="fullName('Hi')"></span>대신 사용하면 작동합니다.
SalchiPapa

2
문제는 그 것이었다 <span :text="message"></span>, 뷰 2.0 더 이상 작품은, 하나 대신 사용할 수 없습니다 : <span v-text="message"></span>또는 <span>{{ message }}</span>이 codepen와 같이 codepen.io/Ismael-VC/pen/dzGzJa
SalchiPapa

1
네가 옳아. 이것이 2.0에서 변경된 것을 보지 못했습니다. 정정 주셔서 감사합니다!
damienix

4
계산 된 속성은 ES5 getter 구문을 사용하며 매개 변수를 사용하여 호출하는 것을 지원하지 않습니다 (괄호 없음). 따라서 언어 수준의 제한 사항이며 Vue.js에 통합되는 방식입니다.
damienix

1
@PedroMoreira의 답변이 늦어서 죄송합니다. 방금 분석 할 시간이있었습니다. 실제로 당신은 내가 쓴 것이 명확하지 않고 혼동되지 않았다는 것이 옳습니다. 분명한지 알려주세요. 감사.
damienix

27

메서드를 사용할 수 있지만 데이터를 변경하지 않거나 외부 효과가없는 경우 메서드 대신 계산 된 속성을 사용하는 것이 좋습니다.

이 방법으로 계산 된 속성에 인수를 전달할 수 있습니다 (문서화되어 있지 않지만 관리자가 제안한 위치는 기억하지 않습니다).

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

편집 :이 솔루션을 사용하지 마십시오, 그것은 아무런 이점없이 코드를 복잡하게합니다.


참조를 제공 할 수 있다면 정말 도움이 될 것입니다. 이 작동합니다.
Saurabh

@saurabh 미안 그것은 github에서 설명이 아닌 문제에 대한 해결책 이었기 때문에 지금 그것을 찾을 수 없습니다 ...
Unirgy

이것은 나를 위해 작동하지만 팬이 아닌 유일한 것은 실제 속성이 아닌 함수를 반환하므로 VueJS devtools가 결과를 어디에도 표시하지 않는다는 것입니다. 이것이 계산 된 속성에 일반적인 것인지 확실하지 않지만 문제 해결을 조금 어렵게 만듭니다.
Nate Ritter

4
캐싱을 어떻게 처리합니까? 매개 변수가 변경되면 제대로 작동합니까?
damienix

리턴 함수 안에 아무것도 캐시하지 않을 것이라고 생각합니다. 방법과의 차이점은 순전히 관례입니다 (방법은 효과가 있으며 계산은 검색 전용입니다)
Unirgy

8

기술적으로 말하자면 vuex에서 매개 변수를 getter 함수에 전달할 수있는 것과 같은 방법으로 매개 변수를 계산 함수에 전달할 수 있습니다. 이러한 함수는 함수를 반환하는 함수입니다.

예를 들어, 상점 게터에서 :

{
  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를 가진 항목이 상점에서 변경되면보기 가이 항목의 새로운 속성으로 내용을 자동으로 새로 고칩니다 (바인딩은 제대로 작동하는 것 같습니다).


woah 그래서 이것은 vuex를 사용하지 않고 나를 위해 일했다. 또한 이것이 계산 된 속성을 수행하는 합법적 인 방법인지 알고 싶습니다.
yeahdixon

1
이것이 작동하는 동안 본질적으로 계산 된 속성을 메소드와 동일하게 취급합니다. 즉, 계산 된 속성의 캐싱 이점을 잃게됩니다. 따라서이 방법을 사용하면 실제 이득이 없습니다. "메서드를 통해 액세스 한 게터는 호출 할 때마다 실행되며 결과는 캐시되지 않습니다."
James

@ james.brndwgn 그러나 기본 데이터가 변경 될 때 메소드가 다시 실행되지 않을 것이라고 확신합니다. 그것이 내가 정말로 찾고있는 전부입니다.
Alex

@Alex는 감시자를 사용해야합니다. vuejs.org/v2/guide/computed.html#Watchers
James

@ james.brndwgn 가능한 경우 감시자보다 계산 속성을 사용하는 것이 좋습니다. 나는 당신의 진술과 관련하여 문제를 겪고있었습니다. 캐싱 없이도 큰 차이가 있습니다.
Alex

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. 유닉스에 익숙하다면, 그것은 유닉스 파이프 연산자입니다. 이것은 오퍼레이션의 출력을 다음 입력으로 전달하는 데 사용됩니다.

구성 요소의 filters 속성은 객체입니다. 단일 필터는 값을 받아들이고 다른 값을 반환하는 함수입니다.

반환 된 값은 실제로 Vue.js 템플릿에 인쇄 된 값입니다.


3

함수를 반환하여 getter에 인수를 전달할 수도 있습니다. 이것은 상점에서 배열을 조회 할 때 특히 유용합니다.

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

메소드를 통해 액세스 된 getter는 호출 할 때마다 실행되며 결과는 캐시되지 않습니다.

이를 Method-Style Access라고 하며 Vue.js docs에 문서화되어 있습니다.


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'로 변경됩니다.

아래에는 계산이 getter 및 setter와 함께 사용되는 일반적인 사용 사례가 있습니다. 다음과 같은 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

계산 기능이 있다고 생각할 수 있습니다. 따라서 valdiation에 대한 예를 들어 다음과 같이 분명히 할 수 있습니다.

    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

params를 사용하는 방법이 있습니다. 위에서 언급 한 답변과 마찬가지로 예제에서는 실행이 매우 적기 때문에 메소드를 사용하는 것이 가장 좋습니다.

참고로, 방법이 복잡하고 비용이 높은 상황에서는 다음과 같이 결과를 캐시 할 수 있습니다.

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

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

참고 : 이것을 사용할 때 수천을 다루는 경우 메모리를 조심하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.