IT이야기

'제안' 변경사항을 청취하는 방법

cyworld 2022. 3. 9. 10:02
반응형

'제안' 변경사항을 청취하는 방법

VueJs 2.0 문서에서는 들을 수 있는 후크를 찾을 수 없다.props변화들

VueJs는 다음과 같은 갈고리를 가지고 있는가?onPropsUpdated()아니면 비슷한가?

갱신하다

@wostex의 말대로 하려고 했다.watch쳉은 쳉은 쳉지 쳉어. 나는 것을 그리고 나서 나는 내가 특별한 경우를 가지고 있다는 것을 깨달았다.

<template>
    <child :my-prop="myProp"></child>
</template>

<script>
   export default {
      props: ['myProp']
   }
</script>

지나간다myProp상위 구성 요소가 에 수신하는 경우child구성 요소그러면.watch: {myProp: ...}작동하지 않는다.

넌 할 수 있다.watch소품 변경 시 일부 코드를 실행하는 소품:

new Vue({
  el: '#app',
  data: {
    text: 'Hello'
  },
  components: {
    'child' : {
      template: `<p>{{ myprop }}</p>`,
      props: ['myprop'],
      watch: { 
      	myprop: function(newVal, oldVal) { // watch it
          console.log('Prop changed: ', newVal, ' | was: ', oldVal)
        }
      }
    }
  }
});
<script src="https://unpkg.com/vue/dist/vue.js"></script>

<div id="app">
  <child :myprop="text"></child>
  <button @click="text = 'Another text'">Change text</button>
</div>

이거 먹어봤어?

watch: {
  myProp: {
    // the callback will be called immediately after the start of the observation
    immediate: true, 
    handler (val, oldVal) {
      // do your stuff
    }
  }
}

https://vuejs.org/v2/api/#watch

내 경우에는 어떤 소품이라도 언제든 바뀔 수 있는 해결책이 필요했고, 내 데이터를 다시 구문 분석해야 했다.나는 내 모든 소품들을 위해 분리된 감시자를 만드는 것에 싫증이 나서 이렇게 사용했다.

  watch: {
    $props: {
      handler() {
        this.parseData();
      },
      deep: true,
      immediate: true,
    },
  },

이 예에서 빼놓을 수 있는 요점은 사용법이다.deep: true그래서 그것은 단지 지켜보는 것만이 아니다.$props내포된 값들이기도 하지 props.myProp

https://vuejs.org/v2/api/#vm-watch의 확장된 워치 옵션에 대해 자세히 알아보십시오.

당신은 당신이 가지고 있는 구성요소 계층 구조와 소품 전달 방법을 이해해야 한다. 확실히 당신의 경우는 특별하며 보통 개발자들에 의해 마주치지 않는다.

상위 구성 요소 -myProp-> 하위 구성 요소 -myProp-> 손자 구성 요소

myProp이 상위 구성 요소에서 변경되면 하위 구성 요소에도 반영된다.

그리고 myProp이 아동 구성요소에서 변경되면 손자녀 구성요소에도 반영될 것이다.

따라서 myProp이 상위 구성요소에서 변경되면 손자 구성요소에 반영될 것이다.(지금까지 좋아.

그러므로 당신이 어떤 소품도 할 필요가 없는 계층 아래에서는 본질적으로 반응할 것이다.

이제 계층 구조로 올라가는 것에 대해 이야기 하고 있다.

myProp이 handChild 구성 요소에서 변경되면 하위 구성 요소에는 반영되지 않는다.아동에게 .sync 수식어를 사용해야 하며, grandChild 구성 요소에서 이벤트를 내보내야 한다.

myProp이 하위 구성요소에서 변경되면 상위 구성요소에 반영되지 않는다.부모에서 .sync 수식어를 사용하고 자식 구성 요소에서 이벤트를 내보내야 한다.

myProp이 grandChild 구성 요소에서 변경되면 상위 구성 요소(확실히)반영되지 않는다.손주 컴포넌트에서 .sync 수식어를 사용하고 이벤트를 내보낸 다음, 자식 컴포넌트에서 소품을 보고, 부모 컴포넌트가 .sync 수식어를 사용하여 듣고 있는 변경에 대한 이벤트를 내보내야 한다.

혼동을 피하기 위한 코드를 봅시다.

상위.vue

<template>
    <div>
    <child :myProp.sync="myProp"></child>
    <input v-model="myProp"/>
    <p>{{myProp}}</p>
</div>
</template>

<script>

    import child from './Child.vue'

    export default{
        data(){
            return{
                myProp:"hello"
            }
        },
        components:{
            child
        }
    }
</script>

<style scoped>
</style>

Child.vue

<template>
<div>   <grand-child :myProp.sync="myProp"></grand-child>
    <p>{{myProp}}</p>
</div>

</template>

<script>
    import grandChild from './Grandchild.vue'

    export default{
        components:{
            grandChild
        },
        props:['myProp'],
        watch:{
            'myProp'(){
                this.$emit('update:myProp',this.myProp)

            }
        }
    }
</script>

<style>

</style>

손주.부에를 하다

<template>
    <div><p>{{myProp}}</p>
    <input v-model="myProp" @input="changed"/>
    </div>
</template>

<script>
    export default{
        props:['myProp'],
        methods:{
            changed(event){
                this.$emit('update:myProp',this.myProp)
            }
        }
    }
</script>

<style>

</style>

하지만 이 일이 있은 후 당신은 부에가 말하는 소리나는 경고에 주목하지 않을 것이다.

'부모 구성 요소가 다시 렌더링될 때마다 값을 덮어쓰게 되므로 직접 프로펠러를 변형하지 않도록 하십시오.'

내가 앞서 언급했듯이 대부분의 개발자들은 이 문제에 직면하지 않는다. 왜냐하면 그것은 반 패턴이기 때문이다.그래서 이런 경고를 받는 겁니다.

그러나 (당신의 설계에 따라) 당신의 문제를 해결하기 위해서입니다.나는 네가 위와 같은 일을 해야 한다고 믿는다.나는 여전히 당신이 당신의 디자인을 재고해야 하고 벌레가 덜 생기도록 만들어야 한다고 권고한다.

도움이 되었으면 좋겠다.

양방향 바인딩은 .bullet 수식어를 사용해야 한다.

<child :myprop.sync="text"></child>

더 자세한 건...

변경 내용을 듣고 업데이트하려면 하위 구성 요소의 감시 속성을 사용해야 함

props: ['myprop'],
  watch: { 
    myprop: function(newVal, oldVal) { // watch it
      console.log('Prop changed: ', newVal, ' | was: ', oldVal)
    }
  }

당신이 그것을 해결했는지는 확실하지 않지만(그리고 내가 제대로 이해했는지는 확실하지 않다) 내 생각은 다음과 같다.

부모가 myprop을 받은 경우, 이를 자녀에게 전달하고 자녀에게 보고하려면 부모에게 myprop 사본(참고가 아님)이 있어야 한다.

다음을 시도해 보십시오.

new Vue({
  el: '#app',
  data: {
    text: 'Hello'
  },
  components: {
    'parent': {
      props: ['myProp'],
      computed: {
        myInnerProp() { return myProp.clone(); } //eg. myProp.slice() for array
      }
    },
    'child': {
      props: ['myProp'],
      watch: {
        myProp(val, oldval) { now val will differ from oldval }
      }
    }
  }
}

및 html:

<child :my-prop="myInnerProp"></child>

실제로 그런 상황에서 복잡한 컬렉션을 작업할 때는 매우 조심해야 한다(몇 번 다운됨)

다음과 같은 계산된 속성으로 작업한다.

    items:{
        get(){
            return this.resources;
        },
        set(v){
            this.$emit("update:resources", v)
        }
    },

리소스는 이 경우 자산:

props: [ 'resources' ]

소품 및 v-모델 처리.부모에서 자녀로, 자식에서 부모로 값을 전달하는 방법.

시계는 필요 없다!또한 부에에서 돌연변이를 일으키는 소품은 반패턴적이므로 아이나 성분의 소품 값을 절대로 변경해서는 안 된다.$emit를 사용하여 값을 변경하면 Vue는 항상 예상대로 작동한다.

/* COMPONENT - CHILD */
Vue.component('props-change-component', {
  props: ['value', 'atext', 'anumber'],
  mounted() {
    var _this = this
    
    this.$emit("update:anumber", 6)
    
    setTimeout(function () {
      // Update the parent binded variable to 'atext'
      _this.$emit("update:atext", "4s delay update from child!!")
    }, 4000)
    
    setTimeout(function () {
      // Update the parent binded v-model value
      _this.$emit("input", "6s delay update v-model value from child!!")
    }, 6000)
  },
  template: '<div> \
    v-model value: {{ value }} <br> \
    atext: {{ atext }} <br> \
    anumber: {{ anumber }} <br> \
    </div>'
})

/* MAIN - PARENT */
const app = new Vue({
  el: '#app',
  data() {
    return {
      myvalue: 7,
      mynumber: 99,
      mytext: "My own text",
    }
  },
  mounted() {
    var _this = this
    
    // Update our variable directly
    setTimeout(function () {
      _this.mytext = "2s delay update mytext from parent!!"
    }, 2000)
  },
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">

  <props-change-component
    v-model='myvalue'
    :atext.sync='mytext'
    :anumber.sync='mynumber'>
    
  </props-change-component>
  
</div>

나에게 있어 이것은 하나의 구체적인 지지자 변화를 얻어 그것으로 논리를 창조하는 정중한 해결책이다.

나는 할 것이다props 및 수 있다.computed변경 사항을 수신한 후 논리를 만드는 속성

export default {
name: 'getObjectDetail',
filters: {},
components: {},
props: {
  objectDetail: { // <--- we could access to this value with this.objectDetail
    type: Object,
    required: true
  }
},
computed: {
  _objectDetail: {
    let value = false
    // ...
    // if || do || while -- whatever logic
    // insert validation logic with this.objectDetail (prop value)
    value = true
    // ...
    return value 
  }
}

따라서 html 렌더에 _objectDetail을 사용할 수 있다.

<span>
  {{ _objectDetail }}
</span>

또는 어떤 방법으로:

literallySomeMethod: function() {
   if (this._objectDetail) {
   ....
   }
}

일부 사용 사례에 대한 흥미로운 관찰.

소품을 통해 스토어에서 데이터 항목을 보고 동일한 스토어 돌연변이로 데이터 항목을 여러 번 변경하면 감시되지 않는다.

그러나 데이터 항목 변경을 동일한 돌연변이의 여러 호출로 분리하면 감시된다.

  • 이 코드는 감시자를 트리거하지 않는다.

    // Somewhere in the code:
    this.$store.commit('changeWatchedDataItem');
    
    // In the 'changeWatchedDataItem' mutation:
    state.dataItem = false;
    state.dataItem = true;
    
  • 이 코드는 각 돌연변이에 감시자를 트리거한다.

    // Somewhere in the code:
    this.$store.commit('changeWatchedDataItem', true);
    this.$store.commit('changeWatchedDataItem', false);
    
    // In the 'changeWatchedDataItem' mutation:
    changeWatchedDataItem(state, newValue) {
        state.dataItem = newValue;
    }
    

Watch 기능은 Child 구성 요소에 배치되어야 한다.부모가 아니다.

watch 모드를 사용하여 변경 사항을 감지할 수 있다.

모든 것을 원자 수준에서 하라.그러므로 먼저 내부의 무언가를 위로하여 시계 방법 자체가 호출되고 있는지 아닌지를 확인한다.일단 시계가 불리고 있다는 것이 확립되면, 당신의 사업 논리로 시계가 고장나도록 하라.

watch: { 
  myProp: function() {
   console.log('Prop changed')
  }
}

나는 사용한다props및 변수computed변경 사항을 수신한 후 로직을 생성해야 하는 경우 속성

export default {
name: 'getObjectDetail',
filters: {},
components: {},
props: {
    objectDetail: {
      type: Object,
      required: true
    }
},
computed: {
    _objectDetail: {
        let value = false
        ...

        if (someValidation)
        ...
    }
}

@JoeSchr이 답을 가지고 있다.당신이 원하지 않는다면 또 다른 방법이 있다.deep: true

 mounted() {
    this.yourMethod();
    // re-render any time a prop changes
    Object.keys(this.$options.props).forEach(key => {
      this.$watch(key, this.yourMethod);
    });
  },

만약 당신의 소품이라면myProp중첩된 항목이 있으면 중첩된 항목은 반응하지 않으므로 lodash 딥클론 같은 항목을 사용하십시오.

<child :myProp.sync="_.deepClone(myProp)"></child>

그게 다야, 감시자나 다른 건 필요 없어.

아래 답변은 컴포지션 API가 있는 Vue 2를 사용하는 사람이면 가능하다.따라서 설정 기능은

setup: (props: any) => {
  watch(() => (props.myProp), (updatedProps: any) => {
    // you will get the latest props into updatedProp
  })
}

단, composition API에서 watch 기능을 가져와야 한다.

나는 대부분의 경우 Vue가 구성 요소의 DOM을 지원 변경으로 업데이트한다고 생각한다.

만약 이것이 당신의 경우라면 당신은 사용할 수 있다.beforeUpdate()또는updated()으로 소품을 구경하다

관심만 있으면 할 수 있다.newVal그리고 필요 없다oldVal

new Vue({
  el: '#app',
  data: {
    text: ''
  },
  components: {
    'child': {
      template: `<p>{{ myprop }}</p>`,
      props: ['myprop'],
      beforeUpdate() {
        console.log(this.myprop)
      },
      updated() {
        console.log(this.myprop)
      }
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <child :myprop="text"></child>
  <input v-model="text" placeholder="Type here to view prop changes" style="width:20em">
</div>

myProp이 객체인 경우, 평상시에는 변경되지 않을 수 있다.시계는 절대 발동되지 않을 거야myProp을 변경하지 않는 이유는 대부분의 경우 myProp의 일부 키만 설정하기 때문이다.myprop 자체가 아직 유일한 것이다. myprop.a와 같은 myprop의 소품들을 보도록 노력하라. 그것은 효과가 있을 것이다.

참조URL: https://stackoverflow.com/questions/44584292/how-to-listen-for-props-changes

반응형