'প্রপস' পরিবর্তনগুলির জন্য কীভাবে শুনবেন


255

ইন VueJs 2.0 ডক্স আমি কোনো আঙ্গুলসমূহ যে শুনবে খুঁজে পাচ্ছি না propsপরিবর্তন।

VueJs এর মতো হুকগুলি কি onPropsUpdated()অনুরূপ বা অনুরূপ রয়েছে?

হালনাগাদ

@ ওয়েস্টেক্সের পরামর্শ অনুসারে, আমি watchআমার সম্পত্তি চেষ্টা করেছি কিন্তু কিছুই পরিবর্তন হয়নি। তখন আমি বুঝতে পারি যে আমার একটি বিশেষ কেস হয়েছে:

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

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

আমি যাচ্ছি myPropযে প্যারেন্ট উপাদানটি উপাদানটিতে প্রাপ্ত হয় child। তারপর watch: {myProp: ...}কাজ করছে না।



1
আমি নিশ্চিত না যে আমি আপনার কেসটি সঠিকভাবে বুঝতে পেরেছি। আপনার সঠিক লক্ষ্যটি কি আপনি ব্যাখ্যা করতে পারেন? "যখন কিছু ঘটে তখন আমি এখানে কিছুটা শক্ত করতে চাই (কোথায়?)"। আপনি কি পিতামাতার প্রপ মানটি ম্যানুয়ালি পরিবর্তন করার চেষ্টা করছেন? যদি হ্যাঁ এটি সম্পূর্ণ ভিন্ন ক্ষেত্রে।
ডিম স্ট্যাম্বাকিও

@ ওয়েস্টেক্স, এখানে কোডপেন । খারাপ জিনিস কলমে এটি কাজ করছে ...
Amio.io

1
আমি দেখছি, সমস্যাটি অন্য কোথাও আছে। আমাকে আপনার কোডটি দেখান, আমি একবার দেখব।
ডিম স্ট্যাম্বাকিও

1
হ্যালো. এখানে: চ্যানেলডেটেল.ভ্যু আপনি ফেসবুক পেজডেটেল উপাদানটি কোথাও আমদানি করবেন না, তবে এটি ঘোষণা করুন: gist.github.com/zatziky/… আমার ধারণা এটি ফেসবুক চ্যানেলডেটেল.ইউইউতে ফেসবুক পেজডেটেল হিসাবে আমদানি করা উচিত, এটি অন্যটি দেখতে ভাল লাগছে
ডিম্বাকৃতি স্টামবাকিও

উত্তর:


320

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>


1
Wostex জন্য Thx, আমি ইতিমধ্যে চেষ্টা করেছি watch। আপনার উদাহরণের কারণে আমি বুঝতে পারি যে আমার মামলাটি কিছুটা আলাদা। আমি আমার প্রশ্ন আপডেট করেছি।
Amio.io

1
এটি উপাদান হিসাবে দেখতে দেখতে দেখুন যেমন
রিয়েলসিপপ্রস

@ ইউসান হ্যাঁ, তবে এটি আপনাকে একটি ট্র্যাক রাখতে হবে এমন একক প্রপতে প্রয়োগ করা হয়েছে।
Egor Stambakio

1
আমি জানি ঘড়িটি নিরুৎসাহিত করা হয়েছে কারণ এটি একটি গণনা করা সম্পত্তি ব্যবহার করা সাধারণত আরও ভাল তবে ঘড়িটি ব্যবহারে কোনও পারফরম্যান্সের সমস্যা আছে কি?
শেঠওহাইট

1
@ শেঠহাইট পর্যবেক্ষক প্যাটার্ন ব্যবহার করে ভিউতে কীভাবে প্রতিক্রিয়াশীলতা পরিচালনা করা হয় তা আমি বুঝতে পেরেছি , পর্যবেক্ষকগণ গণনা করা বা অন্যান্য প্রতিক্রিয়াশীল ডেটার চেয়ে অগত্যা কম দক্ষ হয় না। যে কোনও ক্ষেত্রে কোনও সম্পত্তির মান অনেকগুলি মানের উপর নির্ভর করে, ফলাফলের উপর নির্ভর করে প্রতিটি মানের জন্য একটি পৃথক ঘড়ি কলব্যাক বনাম একটি গণিত প্রপ একটি একক ফাংশন চালাবে। আমি মনে করি বেশিরভাগ সাধারণ ব্যবহারের ক্ষেত্রে, একটি গণনা করা সম্পত্তিটির পছন্দসই ফলাফল হবে।
প্লাগ 0

83

আপনি কি এই চেষ্টা করেছেন?

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


7
এটি আমার পক্ষে কাজ করেছিল, যেখানে উত্তরটি দেয় নি - সম্ভবত এটি কোনও আপডেট। ধন্যবাদ বিয়ারআইনবক্স :)
অনুদান দিন

2
তাত্ক্ষণিক: সত্য আমার জন্য এটি স্থির করে
বাসবেস

2
এইভাবে ঘড়িটি সেট করা আমার পক্ষে এটিও ঠিক করে দিয়েছে, ধন্যবাদ!
adamk22

2
আমার জন্য কাজ করে। এটি গ্রহণযোগ্য উত্তর হওয়া উচিত
টাইটু 10

1
আমার পক্ষেও কাজ করেছেন যদিও গৃহীত উত্তরটি দেয় নি। +1
রবার্তো

25

তিনি

আমার ক্ষেত্রে আমার এমন একটি সমাধানের প্রয়োজন ছিল যেখানে যে কোনও সময় যে কোনও প্রপস পরিবর্তিত হয়, আমাকে আবার আমার ডেটা পার্স করা দরকার। আমি আমার সমস্ত প্রপসের জন্য পৃথক প্রহরী তৈরি করতে ক্লান্ত ছিলাম, তাই আমি এটি ব্যবহার করেছি:

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

এই উদাহরণ থেকে সরিয়ে নেওয়ার মূল পয়েন্টটি হ'ল ব্যবহার করা deep: trueতাই এটি কেবল প্রপসগুলিকেই দেখে না তবে এটি যেমন নেস্টেড মানগুলি যেমনprops.myProp

আপনি এই বর্ধিত ঘড়ির বিকল্পগুলি সম্পর্কে এখানে আরও জানতে পারেন: https://vuejs.org/v2/api/#vm-watch


এটি এগিয়ে দিতে পেরে আনন্দিত! শুভকামনা!
জোএসচার

7

আপনার বুঝতে হবে, আপনার যে উপাদানটির ক্রমক্রমটি রয়েছে এবং আপনি কীভাবে প্রপসগুলি পার করছেন তা অবশ্যই আপনার ক্ষেত্রে বিশেষ এবং এটি সাধারণত ডিভস দ্বারা মুখোমুখি হয় না।

অভিভাবক উপাদান - MyProp-> শিশু উপাদান - MyProp-> নাতনী উপাদান

মাইপ্রপ যদি প্যারেন্ট উপাদানগুলিতে পরিবর্তিত হয় তবে এটি সন্তানের উপাদানগুলিতেও প্রতিফলিত হবে।

এবং যদি মাইপ্রপ চাইল্ড উপাদানগুলিতে পরিবর্তন করা হয় তবে এটি নাতির অংশেও প্রতিফলিত হবে

সুতরাং মাইপ্রপ যদি প্যারেন্ট উপাদানগুলিতে পরিবর্তিত হয় তবে এটি নাতি-অংশে প্রতিফলিত হবে । (এ পর্যন্ত সব ঠিকই).

সুতরাং স্তরক্রম নিচে আপনি কিছু করতে হবে না সহজাত প্রতিক্রিয়াশীল হবে।

এখন শ্রেণিবিন্যাসে উঠে যাওয়ার কথা বলছি

মাইপ্রপ যদি গ্র্যান্ডচিল্ড উপাদানগুলিতে পরিবর্তন করা হয় তবে এটি সন্তানের উপাদানগুলিতে প্রতিফলিত হবে না । আপনাকে চাইল্ডে। Sync সংশোধক ব্যবহার করতে হবে এবং গ্র্যান্ডচিল্ড উপাদানটি থেকে ইভেন্ট নির্গত করতে হবে।

মাইপ্রপ যদি শিশু উপাদানগুলিতে পরিবর্তন করা হয় তবে এটি প্যারেন্ট উপাদানগুলিতে প্রতিফলিত হবে না । আপনাকে পিতামাতায়। Sync সংশোধক ব্যবহার করতে হবে এবং সন্তানের উপাদান থেকে ইভেন্ট নির্গত করতে হবে।

মাইপ্রপ যদি গ্র্যান্ডচিল্ড উপাদানগুলিতে পরিবর্তন করা হয় তবে এটি প্যারেন্ট উপাদানগুলিতে প্রতিফলিত হবে না (স্পষ্টতই)। আপনাকে। Sync মডিফায়ার চাইল্ড ব্যবহার করতে হবে এবং নাতির অংশ থেকে ইভেন্ট নির্গত করতে হবে, তারপরে চাইল্ড কম্পোনেন্টে প্রপটি দেখুন এবং পরিবর্তনের ক্ষেত্রে একটি ইভেন্ট প্রেরণ করুন যা পিতৃ উপাদান দ্বারা সিঙ্ক মোডিফায়ার ব্যবহার করে শোনা যাচ্ছে।

বিভ্রান্তি এড়ানোর জন্য কিছু কোড দেখুন

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

Grandchild.vue

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

তবে এর পরে আপনি মান্য বলার চেঁচামেচি সতর্কতাগুলি লক্ষ্য করতে সহায়তা করবেন না

'যখন কোনও প্যারেন্ট উপাদান পুনরায় রেন্ডার করে তখন মানটি ওভাররাইট করা হবে বলে সরাসরি কোনও প্রপকে পরিবর্তন করতে এড়াতে হবে' '

আবার আমি যেমন আগেই উল্লেখ করেছি বেশিরভাগ দেবগণ এই সমস্যাটির মুখোমুখি হয় না, কারণ এটি একটি বিরোধী নিদর্শন। এজন্য আপনি এই সতর্কতাটি পান।

তবে আপনার সমস্যাটি সমাধান করার জন্য (আপনার নকশা অনুযায়ী)। আমি বিশ্বাস করি আপনাকে উপরের কাজগুলি চারপাশে করতে হবে (সৎ হতে হ্যাক)। আমি এখনও আপনাকে পরামর্শ দিচ্ছি যে আপনার নকশাটি পুনর্বিবেচনা করা উচিত এবং তৈরি করা ত্রুটিগুলির চেয়ে কম প্রবণ।

আমি আসা করি এটা সাহায্য করবে.


6

আপনি এটি সমাধান করেছেন কিনা তা নিশ্চিত নন (এবং আমি যদি সঠিকভাবে বুঝতে পারি) তবে আমার ধারণাটি এখানে:

যদি পিতামাতাই মাইপ্রপ পান এবং আপনি এটি সন্তানের কাছে পাঠাতে চান এবং এটি শিশুকে দেখতে চান, তবে পিতামাতার কাছে মাইপ্রপের অনুলিপি থাকতে হবে (রেফারেন্স নয়)।

এটা চেষ্টা কর:

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

এবং এইচটিএমএলে:

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

আসলে এই ধরনের পরিস্থিতিতে জটিল সংগ্রহের উপর কাজ করার সময় আপনাকে খুব সতর্কতা অবলম্বন করতে হবে (কয়েক বার নিচে)


ভাল ধারণা. আমি এই মুহুর্তে এটি কেবল বৈধতা দিতে পারি না। আমি আবার যখন মান দিয়ে কাজ করব, আমি এটি যাচাই করব।
Amio.io

1
আপনাকে @ এম.সিচ্যাকজ ধন্যবাদ, একই ভুলটি করে ফেলেছে এবং সন্তানের কাছে একটি অনুলিপি জমা দেওয়ার জন্য আপনার পরামর্শটি অবিলম্বে ধন্যবাদ জানানো হয়েছে
অপরিশোধিত

4

দুই উপায় বাইন্ডিংয়ের জন্য আপনাকে। sync সংশোধক ব্যবহার করতে হবে

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

আরো বিস্তারিত...

এবং কোনও পরিবর্তন শুনতে এবং আপডেট করতে আপনাকে চাইল্ড উপাদানটিতে ঘড়ি সম্পত্তি ব্যবহার করতে হবে

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

সত্য, সন্তানের উপাদানগুলির প্রপস পরিবর্তনের জন্য এটি দেখার নতুন উপায়।
Amio.io

2

আমি একটি গণিত সম্পত্তি সঙ্গে কাজ:

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

সম্পদ এক্ষেত্রে একটি সম্পত্তি:

props: [ 'resources' ]

1

আমার কাছে এটি একটি নির্দিষ্ট প্রোপ (গুলি) পরিবর্তন পেতে এবং এর সাথে যুক্তি তৈরি করার জন্য একটি নম্র সমাধান

আমি পরিবর্তনগুলি প্রাপ্ত করার পরে যুক্তি তৈরি করতে 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 
  }
}

সুতরাং, আমরা এইচটিএমএল রেন্ডারে _ অবজেক্টডেটেল ব্যবহার করতে পারি

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

বা কোনও পদ্ধতিতে:

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

0

পরিবর্তনগুলি সনাক্ত করতে আপনি ঘড়ি মোডটি ব্যবহার করতে পারেন:

পারমাণবিক স্তরে সবকিছু করুন। সুতরাং প্রথমে ঘড়ির পদ্ধতিটি কোনও অভ্যন্তরকে সান্ত্বনা দিয়ে কল করা হচ্ছে কিনা তা পরীক্ষা করে দেখুন। একবার এটি প্রতিষ্ঠিত হয়ে গেলে যে ঘড়িটি ডাকা হচ্ছে, আপনার ব্যবসায়িক যুক্তি দিয়ে তা ছড়িয়ে দিন।

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

0

পরিবর্তনগুলি পাওয়ার পরে যদি যুক্তি তৈরি করতে আমার প্রয়োজন হয় তবে আমি propsভেরিয়েবলের computedবৈশিষ্ট্যগুলি ব্যবহার করি

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

        if (someValidation)
        ...
    }
}

-1

মাইপ্রপ যদি কোনও বস্তু হয় তবে এটি স্বাভাবিকভাবে পরিবর্তিত হতে পারে না। সুতরাং, ঘড়ি কখনই ট্রিগার হবে না। মাইপ্রপকে কেন পরিবর্তন করা হবে না তার কারণ হ'ল আপনি বেশিরভাগ ক্ষেত্রে সবেমাত্র মাইপ্রপের কিছু কী সেট করে রেখেছেন। মাইপ্রপ নিজেই এখনও এক। "মাইপ্রপ.এ" এর মতো মাইপ্রপের প্রপসগুলি দেখার চেষ্টা করুন, এটি কাজ করা উচিত।



-1

@ জোএসচারের একটি ভাল উত্তর রয়েছে। আপনি যদি 'গভীর: সত্য' না চান তবে এটি করার আরও একটি উপায় এখানে।

 mounted() {
    this.yourMethod();
    // re-render any time a prop changes
    Object.keys(this.$options.props).forEach(key => {
      this.$watch(key, this.yourMethod);
    });
  },
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.