欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vue組件間傳值的實(shí)現(xiàn)解析

 更新時(shí)間:2022年09月30日 11:50:26   作者:月光曬了很涼快  
組件是?vue.js?最強(qiáng)大的功能之一,而組件實(shí)例的作用域是相互獨(dú)立的,這就意味著不同組件之間的數(shù)據(jù)無(wú)法相互引用,這篇文章主要介紹了Vue組件間傳值的實(shí)現(xiàn)

1. 父組件向子組件傳值

1.1 描述

父組件以屬性的形式綁定值到子組件身上。

子組件通過(guò)使用屬性 props 接收(props 是單向數(shù)據(jù)流【只讀屬性】:當(dāng)父組件的屬性變化時(shí),將傳導(dǎo)給子組件,但是反過(guò)來(lái)不會(huì),即子組件中不可以修改父組件的值,應(yīng)該通過(guò)給子組件傳數(shù)據(jù)的父組件修改)

1.2 props接收數(shù)據(jù)

語(yǔ)法:

props: 數(shù)組 | 對(duì)象

數(shù)組方式接收:

此方式,一般用于你自己定義組件給自己所用,是一種簡(jiǎn)寫(xiě)方式

數(shù)組中的元素就是你自定義的屬性名稱(注意這里是自定義的屬性名稱,而不是父組件數(shù)據(jù)源中的數(shù)據(jù)名稱)

示例:

子組件(child.vue):

<template>
<div>
    <div class="title">child</div>
    <br />
    <div>{{ title }}</div>
    </div>
</template>
<script>
    export default {
        // 在vue中接受父組件通過(guò)自定義屬性傳過(guò)來(lái)的數(shù)據(jù),通過(guò)配置props來(lái)接受
        props: ["title"],
        // 在方法中得到數(shù)據(jù)
        created() {
            console.log(this.title);
        },
    };
</script>
<style lang="scss" scoped>
    .title {
        color: red;
    }
</style>

父組件(App.vue):

<template>
<div>
    <h3 class="title">App組件</h3>
    <hr />
    <!-- vue中父組件中的數(shù)據(jù)可以通過(guò)自定義屬性的方式向子組件傳遞 -->
    <!-- 第一個(gè) title 是我們自定義的屬性名稱;第二個(gè) title 是當(dāng)前組件 data 中的數(shù)據(jù)名稱 -->
    <!-- 兩個(gè)名稱可以不一樣,但是一般情況下,我們寫(xiě)成一樣的 -->
    <child :title="title" />
    </div>
</template>
<script>
    import child from "./components/child.vue";
    export default {
        components: {
            child,
        },
        data() {
            return {
                title: "我是一個(gè)顯示內(nèi)容",
            };
        },
    };
</script>
<style lang="scss" scoped></style>

對(duì)象方式接收:

一般用于,封裝的組件提供給別人使用,它可以限制屬性的類型和默認(rèn)值

示例:

子組件(child.vue):

<template>
<div>
    <div class="title">child組件</div>
    <br />
    <div>{{ title }}--{{ age }}</div>
    </div>
</template>
<script>
    export default {
        props: {
            // key名稱就是你自定義屬性名稱
            // 類型首字母大寫(xiě)
            // attrtitle: String
            title: {
                // 接收的數(shù)據(jù)類型
                type: String,
                // 直接給值 [基礎(chǔ)類型] | 回調(diào)函數(shù) [基礎(chǔ)類型和引用類型都可以,引用類型設(shè)置默認(rèn)值必須是此方案]
                default: "我是一個(gè)字符串",
            },
            // 自定義方法驗(yàn)證接收的數(shù)據(jù)
            age: {
                type: Number,
                default: () => 10,
                // 驗(yàn)證操作
                validator: (value) => {
                    if (value > 90) {
                        // 返回一個(gè)警告
                        return false;
                    }
                    return true;
                }
            },
        },
    };
</script>
<style lang="scss" scoped>
    .title {
        color: red;
    }
</style>

父組件(App.vue):

<template>
<div>
    <h3 class="title">App組件</h3>
    <hr />
    <child :title="title" :age="100" />
    <child />
    <child :title="'100'" />
    </div>
</template>
<script>
    import child from "./components/child.vue";
    export default {
        components: {
            child,
        },
        data() {
            return {
                title: "我是一個(gè)顯示內(nèi)容",
            };
        },
    };
</script>
<style lang="scss" scoped></style>

2. 子組件向父組件傳值

上文提到props 是單向數(shù)據(jù)流,子組件中不可以修改父組件的值,應(yīng)該通過(guò)給子組件傳數(shù)據(jù)的父組件修改,這樣設(shè)計(jì)是為了防止子和父在修改數(shù)據(jù)時(shí),造成的數(shù)據(jù)混亂。

在 Vue 中,如果子組件修改了父組件傳過(guò)來(lái)的數(shù)據(jù),控制臺(tái)會(huì)報(bào)一個(gè)警告,但在 React 中會(huì)直接報(bào)錯(cuò)。

那么子組件要怎么向父組件傳值呢?

有兩種方式:

  • 子組件用$emit()定義自定義事件,$emit()第一個(gè)參數(shù)為 自定義的事件名稱 第二個(gè)參數(shù)為需要傳遞的數(shù)據(jù);父組件用v-on(@)綁定子組件定義的自定義事件名,監(jiān)聽(tīng)子組件的事件,實(shí)現(xiàn)通信
  • 父組件直接把修改數(shù)據(jù)的方法以屬性的方式傳給子組件(通過(guò)形參方式傳遞)

方法2實(shí)現(xiàn):

父組件:

<template>
<div>
    <h3 class="title">App組件</h3>
    <hr />
    <!-- 把修改age的方法以屬性的方式傳給子組件 -->
    <child :title="title" :age="age" :setAge="setAge" />
</div>
</template>
<script>
    import child from "./components/child.vue";
    export default {
        components: {
            child,
        },
        data() {
            return {
                title: "我是一個(gè)顯示內(nèi)容",
                age: 80,
            };
        },
        methods: {
            setAge(n = 1) {
                this.age += n;
            },
        },
    };
</script>
<style lang="scss" scoped></style>

子組件:

<template>
  <div>
    <div class="title">child組件</div>
    <br />
    <div>{{ title }}--{{ age }}</div>
    <br />
    <button @click="addAge">+++++</button>
  </div>
</template>
<script>
export default {
  props: {
    title: {
      // 接收的數(shù)據(jù)類型
      type: String,
      // 直接給值 [基礎(chǔ)類型] | 回調(diào)函數(shù) [基礎(chǔ)類型和引用類型都可以,引用類型設(shè)置默認(rèn)值必須是此方案]
      default: "我是一個(gè)字符串",
    },
    // 自定義方法驗(yàn)證接收的數(shù)據(jù)
    age: {
      type: Number,
      default: () => 10,
      // 驗(yàn)證操作
      validator: (value) => {
        if (value > 90) {
          // 返回一個(gè)警告
          return false;
        }
        return true;
      },
    },
    setAge: Function,
  },
  methods: {
    addAge() {
      this.setAge(2);
    },
  },
};
</script>
<style lang="scss" scoped>
.title {
  color: red;
}
</style>

方法1實(shí)現(xiàn):

子組件:

<template>
  <div>
    <div class="title">child組件</div>
    <br />
    <div>{{ title }}--{{ age }}</div>
    <br />
    <button @click="addAge">+++++</button>
  </div>
</template>
<script>
export default {
  props: {
    title: {
      // 接收的數(shù)據(jù)類型
      type: String,
      // 直接給值 [基礎(chǔ)類型] | 回調(diào)函數(shù) [基礎(chǔ)類型和引用類型都可以,引用類型設(shè)置默認(rèn)值必須是此方案]
      default: "我是一個(gè)字符串",
    },
    // 自定義方法驗(yàn)證接收的數(shù)據(jù)
    age: {
      type: Number,
      default: () => 10,
      // 驗(yàn)證操作
      validator: (value) => {
        if (value > 200) {
          // 返回一個(gè)警告
          return false;
        }
        return true;
      },
    },
    setAge: Function,
  },
  methods: {
    addAge() {
      // 通過(guò)給當(dāng)前的組件定義一個(gè)自定義的事情,完成子向父
      // 參數(shù)1:自定義事件的名稱,參數(shù)2以后,它是傳過(guò)去的數(shù)據(jù)
      // this.$emit('onSetAge',......參數(shù))
      this.$emit("onSetAge", 10);
    },
  },
};
</script>
<style lang="scss" scoped>
.title {
  color: red;
}
</style>

父組件:

<template>
  <div>
    <h3 class="title">App組件</h3>
    <hr />
    <!-- 父組件實(shí)現(xiàn)子組件創(chuàng)建的onSetAge自定義事件 -->
    <child :title="title" :age="age" @onSetAge="setAge" />
  </div>
</template>
<script>
import child from "./components/child.vue";
export default {
  components: {
    child,
  },
  data() {
    return {
      title: "我是一個(gè)顯示內(nèi)容",
      age: 80,
    };
  },
  methods: {
    setAge(n = 1) {
      this.age += n;
    },
  },
};
</script>
<style lang="scss" scoped></style>

3. 兄弟組件間傳值

概述:

兄弟間組件傳值,通過(guò)公共的父組件來(lái)進(jìn)行。這種方式使得兩個(gè)兄弟組件共用的數(shù)據(jù)得到提升,即狀態(tài)提升。

子組件通過(guò)修改父組件中自己和兄弟的公共數(shù)據(jù),來(lái)和自己的兄弟組件傳值。

示例:

子組件1:

<template>
  <div>
    <h3>child1 -- {{ age }}</h3>
    <button @click="$emit('onAddAge', 1)">++++</button>
  </div>
</template>
<script>
export default {
  props: ["age"],
};
</script>
<style lang="scss" scoped>
</style>

子組件2:

<template>
  <div>
    <h3>child2 -- {{ age }}</h3>
  </div>
</template>
<script>
export default {
  props: ["age"],
};
</script>
<style lang="scss" scoped>
</style>

父組件:

<template>
  <div>
    <h3 class="title">App組件</h3>
    <hr />
    <child1 :age="age" @onAddAge="addAge" />
    <child2 :age="age" />
  </div>
</template>
<script>
import child1 from "./components/child1.vue";
import child2 from "./components/child2.vue";
export default {
  components: {
    child1,
    child2,
  },
  data() {
    return {
      age: 80,
    };
  },
  methods: {
    addAge(n = 1) {
      this.age += n;
    },
  },
};
</script>
<style lang="scss" scoped></style>

4. 事件總線

概述:

兄第組件間通過(guò)狀態(tài)提升的方式來(lái)進(jìn)行傳值,適用于父子場(chǎng)景中,一旦涉及到子孫場(chǎng)景,狀態(tài)提升的操作就變得很復(fù)雜,這時(shí)候我們就要用到 Vue2 中給我們提供的事件總線來(lái)處理。

什么是事件總線?

非父子組件或更多層級(jí)間組件間傳值,在Vue中通過(guò)單獨(dú)的事件中心來(lái)管理組件間的傳值。

它相當(dāng)于一個(gè)全局的倉(cāng)庫(kù),任何組件都可以去這個(gè)倉(cāng)庫(kù)里獲取事件,它就類似溝通橋梁的概念,就像是所有組件共用相同的事件中心,可以向該中心注冊(cè)發(fā)送事件或接收事件,所以組件都可以上下平行的通知其他組件來(lái)進(jìn)行通信。

簡(jiǎn)單來(lái)說(shuō)就是,假設(shè)現(xiàn)在有一個(gè)組件 a 往全局倉(cāng)庫(kù)中塞數(shù)據(jù),另一個(gè)組件 b 只要訂閱了全局倉(cāng)庫(kù),就可以收到更新的數(shù)據(jù)。

事件總線只能進(jìn)行通知,不能進(jìn)行數(shù)據(jù)的存儲(chǔ)功能。

注意:實(shí)現(xiàn)事件總線的前提條件是,必須先訂閱和發(fā)布

語(yǔ)法:

  • 建立統(tǒng)一的事件中心:const bus = new Vue()
  • 傳遞數(shù)據(jù)方,通過(guò)一個(gè)事件觸發(fā):bus.$emit(方法名,傳遞的數(shù)據(jù))
  • 接收數(shù)據(jù)方,在生命周期函數(shù)中,通過(guò)bus.$on(方法名,(參數(shù))=>{})來(lái)監(jiān)聽(tīng)
  • 銷毀事件,在接受數(shù)據(jù)方,通過(guò)bus.$off(方法名)銷毀,銷毀之后無(wú)法監(jiān)聽(tīng)數(shù)據(jù)

示例:

建立統(tǒng)一的事件中心(即全局對(duì)象)可以在主 js 文件中寫(xiě)入如下代碼:

import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
// 事件總線  --- 是當(dāng)前文件的私有變量
// 因?yàn)樗薪M件對(duì)象都能看到 Vue 原型對(duì)象上的屬性和方法,所以我們可以在Vue的原型對(duì)象上通過(guò)設(shè)定一個(gè)eventBus對(duì)象,
// Vue.prototype.bus = new Vue(),此時(shí)所有的組件對(duì)象都能看到eventBus屬性對(duì)象。
const eventBus = new Vue()
Vue.prototype.$eventBus = eventBus
new Vue({
  render: h => h(App),
}).$mount('#app')

也可以使用插件的方式,建立全局對(duì)象:

新建一個(gè) bus.js 文件:

export default Vue => {
  Vue.prototype.$eventBus = new Vue()
}

在 main.js 中導(dǎo)入:

import Vue from 'vue'
import App from './App.vue'
import bus from './plugin/bus'
Vue.config.productionTip = false
Vue.use(bus)
new Vue({
  render: h => h(App),
}).$mount('#app')

父組件:

<template>
  <div>
    <h3 class="title">App組件</h3>
    <hr />
    <child1 :age="age" />
    <child2 :age="age" />
  </div>
</template>
<script>
import child1 from "./components/child1.vue";
import child2 from "./components/child2.vue";
export default {
  components: {
    child1,
    child2,
  },
  data() {
    return {
      age: 80,
    };
  },
  // 讓父組件也訂閱子組件的頻道,作為介質(zhì)向子組件2傳遞數(shù)據(jù)
  created() {
    this.$eventBus.$on("age", (value) => (this.age += value));
  },
  // 在訂閱的地方都要銷毀,相當(dāng)于關(guān)閉頻道
  beforeDestroy() {
    this.$eventBus.$off("age");
  },
};
</script>
<style lang="scss" scoped></style>

子組件1(發(fā)布者):

<template>
  <div>
    <h3>child1 -- {{ age }}</h3>
    <button @click="setAge">+++++</button>
  </div>
</template>
<script>
export default {
  props: ["age"],
  methods: {
    setAge() {
      // 傳遞數(shù)據(jù)方
      // 這里的作用是,往全局對(duì)象中塞數(shù)據(jù)
      // 參數(shù)1:頻道名稱,不能重復(fù)
      // 參數(shù)2-N,傳過(guò)去的數(shù)據(jù)
      this.$eventBus.$emit("age", 10);
    },
  },
};
</script>
<style lang="scss" scoped>
</style>

子組件2(訂閱者):

<template>
  <div>
    <h3>child2 -- {{ age }}</h3>
  </div>
</template>
<script>
export default {
  props: ["age"],
  // 接收數(shù)據(jù)方
  // 這里相當(dāng)于子組件2訂閱了 age 頻道,可以接收到更新后的數(shù)據(jù)
  created() {
    this.$eventBus.$on("age", (value) => {
      console.log(value);
    });
  },
  beforeDestroy() {
    this.$eventBus.$off("age");
  }
};
</script>
<style lang="scss" scoped>
</style>

5. Ref

概述:

ref 被用來(lái)給元素或子組件注冊(cè)引用信息。引用信息將會(huì)注冊(cè)在父組件的 $refs 對(duì)象上。如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子組件上,引用就指向組件實(shí)例。

ref 它不但可以實(shí)現(xiàn)組件通信,而且它還可以獲取dom對(duì)象。

使用ref來(lái)獲取普通元素的dom對(duì)象:

<template>
  <div>
    <h3 class="title">App組件</h3>
    <hr />
    <!-- 
      ref它可以實(shí)現(xiàn)組件通信,而且它還可以獲取dom對(duì)象
     -->
    <!-- 使用ref來(lái)獲取普通元素的dom對(duì)象 -->
    <div ref="username">張三</div>
    <button @click="getUsernameDom">獲取張三dom</button>
  </div>
</template>
<script>
export default {
  components: {
  },
  data() {
    return {
    }
  },
  methods: {
    getUsernameDom() {
      // ref 獲取dom對(duì)象
      console.log(this.$refs['username'].innerHTML)
    }
  }
}
</script>
<style lang="scss" scoped></style>

ref 獲取的 dom 列表并不是真實(shí)的 dom,因?yàn)楂@取 dom 是同步的,而視圖渲染是異步的。我們需要用到$nextTick,該方法用于獲取最新的dom的方法 等待視圖渲染完畢后才觸發(fā)執(zhí)行,得到真實(shí)dom。

ref 綁定到自定義組件:

父組件:

<template>
  <div>
    <h3 class="title">App組件 -- {{ ptitle }}</h3>
    <hr />
    <!-- 
      ref 實(shí)現(xiàn)組件通信
      如果ref綁定在自定義組件上,通可以得到當(dāng)前組件實(shí)例對(duì)象
     -->
    <child ref="childRef" />
    <button @click="getChild">父獲取child組件中的數(shù)據(jù)</button>
  </div>
</template>
<script>
import child from './components/child.vue'
export default {
  components: {
    child
  },
  data() {
    return {
      age: 100,
      ptitle: ''
    }
  },
  methods: {
    getChild() {
      // this.$refs.childRef.title = 'aaaaa'
      // this.ptitle = this.$refs.childRef.title
      this.ptitle = this.$refs.childRef.setTitle('afewfewfew')
    }
  },
  // 寫(xiě)在 mounted 中也可以實(shí)現(xiàn)
//   mounted(){
//     // console.log(this.$refs.childRef?.title)
//     this.ptitle = this.$refs.childRef.title
//   }
}
</script>
<style lang="scss" scoped></style>

子組件:

<template>
  <div>
    <h3>child組件</h3>
  </div>
</template>
<script>
export default {
  data() {
    return {
      title: '我是child組件中的數(shù)據(jù)'
    }
  },
  methods: {
    setTitle(title) {
      this.title = title+'#####3'
      return this.title
    }
  }
}
</script>
<style lang="scss" scoped></style>

6. root/parent/children

概述:

獲取父組件對(duì)象或子組件對(duì)象集合。

三個(gè)方法:

this.$root
this.$parent
this.$children

示例:

父組件:

<template>
  <div>
    <h3 class="title">App組件</h3>
    <button @click="getChild">父獲取child組件中的數(shù)據(jù)</button>
    <hr />
    <child />
  </div>
</template>
<script>
import child from './components/child.vue'
export default {
  components: {
    child
  },
  data() {
    return {
      title: 'parent'
    }
  },
  methods: {
    getChild() {
      console.log(this.$root,"---父組件中獲取");
      // console.log(this.$children);
      // 獲取子元素中的數(shù)據(jù)
      // console.log(this.$children[0].title);
      // 如果有多個(gè)孩子
      this.$children.forEach(node => {
        // console.log(node?.title)
        // 短路運(yùn)算
        console.log(node.title && node.title)
      })
    }
  }
}
</script>
<style lang="scss" scoped></style>

子組件:

<template>
  <div>
    <h3>child組件</h3>
    <button @click="getParent">獲取父組件中的數(shù)據(jù)</button>
  </div>
</template>
<script>
export default {
  data() {
    return {
      title: '我是child組件中的數(shù)據(jù)'
    }
  },
  methods: {
    getParent() {
      // 獲取到根上的元素(main.js),在任何層級(jí)都可以獲取
      console.log(this.$root,"---子組件中獲取")
      // 子組件獲取父組件
      console.log(this.$parent.title)
    }
  }
}
</script>
<style lang="scss" scoped></style>

7. provide/inject

概述:

provide 和 inject 主要為高階插件/組件庫(kù)提供用例。并不推薦直接用于應(yīng)用程序代碼中。

這對(duì)選項(xiàng)需要一起使用,以允許一個(gè)祖先組件向其所有子孫后代注入一個(gè)依賴,不論組件層次有多深,并在起上下游關(guān)系成立的時(shí)間里始終生效。

比如我們現(xiàn)在想要封裝一個(gè)組件,組件內(nèi)層級(jí)很多,我們想在組件內(nèi)實(shí)現(xiàn)很方便的通信,卻又想要與外界隔絕,這時(shí)候就需要用到 provide/inject。

父組件向子組件傳值:

父組件:

<template>
  <div>
    <h3 class="title">App組件</h3>
    <hr />
    <child />
  </div>
</template>
<script>
import child from "./components/child.vue";
export default {
  components: {
    child,
  },
  data() {
    return {
      msg: 'app中的標(biāo)題'
    };
  },
  // 發(fā)布,父組件的后代無(wú)論在哪個(gè)層級(jí)都能收到
  // 寫(xiě)法1:
  // provide: {
  //   title: "app中的標(biāo)題",
  // },
  // 如果你要使用當(dāng)前組件中的數(shù)據(jù)或方法,就需要把provide寫(xiě)成函數(shù)方式且返回一個(gè)對(duì)象
  // 寫(xiě)法2:
  provide() {
    return {
      title: this.msg,
    };
  },
  methods: {},
};
</script>

子組件:

<template>
  <div>
    <h3>child組件 --- {{ title }}</h3>
  </div>
</template>
<script>
export default {
  // 注入
  // 數(shù)組方式接收  寫(xiě)的比較的多
  // inject: ['title'],
  // 對(duì)象方式接收
  inject: {
    title: {
      // 默認(rèn)值
      default: () => '默認(rèn)值'
    },
  },
  data() {
    return {};
  },
  methods: {},
};
</script>

provide 和 inject 綁定并不是可響應(yīng)的,如果想要變成響應(yīng)式的,可以在父組件中 provide 返回一個(gè)函數(shù),并且在子組件中接收:

父組件:

<template>
  <div>
    <h3 class="title">App組件</h3>
    <input v-model="msg" />
    <hr />
    <child />
  </div>
</template>
<script>
import child from "./components/child.vue";
export default {
  components: {
    child,
  },
  data() {
    return {
      msg: 'app中的標(biāo)題'
    };
  provide() {
    return {
      title: () => this.msg
    };
  },
  methods: {},
};
</script>

子組件:

<template>
  <div>
    <h3>child組件 --- {{ title() }}</h3>
  </div>
</template>
<script>
export default {
  // 對(duì)象方式接收
  inject: {
  title: {
    // 默認(rèn)值
    default: () => () => "默認(rèn)值",
  },
  },
  data() {
    return {};
  },
  methods: {},
};
</script>

8. $attrs/$listeners

概述:

$attrs 獲取沒(méi)有在 props 中定義的屬性,把 props 沒(méi)有接收到的屬性進(jìn)行接收

$listeners 獲取父組件給子組件自定義事件

示例:

父組件:

<template>
  <div>
    <h3 class="title">App組件</h3>
    <hr />
    <child :msg="msg" uid="1" @setTitle="setTitle" />
  </div>
</template>
<script>
import child from './components/child.vue'
export default {
  components: {
    child
  },
  data() {
    return {
      msg: 'app中的標(biāo)題'
    }
  },
  methods: {
    setTitle(title) {
      this.msg = title
    }
  }
}
</script>

子組件:

<template>
  <div>
    <h3>child組件 --- {{ $attrs.msg }}</h3>
    <button @click="setMsg">修改msg</button>
  </div>
</template>
<script>
export default {
  props: ['uid'],
  data() {
    return {}
  },
  methods: {
    setMsg() {
      // console.log(this.$listeners)
      this.$listeners.setTitle(Date.now())
    }
  }
}
</script>

利用 attrs 來(lái)處理所以的自定義屬性數(shù)據(jù):

簡(jiǎn)單來(lái)說(shuō),就是拿一個(gè)組件(數(shù)據(jù)層容器)包裹另一個(gè)組件(最終顯示在頁(yè)面上的組件),增強(qiáng)了組件能力。

父組件:

<template>
  <div>
    <h3 class="title">App組件</h3>
    <hr />
    <child :phone="phone" :uid="100" />
  </div>
</template>
<script>
import child from './components/child.vue'
export default {
  components: {
    child
  },
  data() {
    return {
      phone: '1323125125'
    }
  },
  methods: {}
}
</script>

子組件(數(shù)據(jù)層容器,進(jìn)行數(shù)據(jù)包裝和處理):

<template>
  <div>
    <h3>child組件</h3>
    <showphone :attrs="attrs" />
  </div>
</template>
<script>
import showphone from './showphone.vue'
export default {
  components: {
    // child 組件不直接顯示數(shù)據(jù),而是將數(shù)據(jù)進(jìn)行包裝處理后,交給自己的子組件 showphone 來(lái)顯示
    // 這時(shí)的 child 相當(dāng)于一個(gè)數(shù)據(jù)層容器,包裹了 showphone 進(jìn)行了相關(guān)的數(shù)據(jù)處理
    showphone
  },
  data() {
    return {
      attrs: {}
    }
  },
  created() {
    this.attrs = { ...this.$attrs, phone: 'abc ---' + this.$attrs.phone }
  }
}
</script>

子組件的子組件(最終顯示在頁(yè)面數(shù)據(jù)的組件):

<template>
  <div>
    <h3>showphone顯示手機(jī)號(hào)碼 --- {{ attrs.phone }}</h3>
  </div>
</template>
<script>
export default {
  props: ['attrs']
}
</script>

9. v-model綁定到自定義組件中

默認(rèn)用法:

父組件:

<template>
  <div>
    <h3 class="title">App組件</h3>
    <!-- v-model它可以對(duì)于表單項(xiàng)進(jìn)行數(shù)據(jù)的雙項(xiàng)綁定 -->
    <!-- <input type="text" v-model="title" /> -->
    <hr />
    <!--
      v-model它是一個(gè)語(yǔ)法糖,它是 value和事件[input[默認(rèn)]]的集合體
     -->
     <!-- v-model語(yǔ)法糖的作用相當(dāng)于下面這一句 -->
    <!-- <child :value="title" @input="setTitle" /> -->
    <child v-model="title" />
  </div>
</template>
<script>
import child from './components/child.vue'
export default {
  components: {
    child
  },
  data() {
    return {
      title: '我是父組件的title'
    }
  },
  // v-model相當(dāng)于寫(xiě)有這個(gè)方法
  // methods: {
  //   setTitle(title) {
  //     this.title = title
  //   }
  // }
}
</script>

子組件:

<template>
  <div>
    <!-- 默認(rèn)的 -->
    <h3>child組件 -- {{ value }}</h3>
    <!-- 默認(rèn)的 -->
    <button @click="$emit('input', Date.now())">修改value數(shù)據(jù)</button>
  </div>
</template>
<script>
export default {
  // 默認(rèn)的
  props: ['value'],
  data() {
    return {};
  },
};
</script>

除了使用默認(rèn)的用法,還可以自定義屬性名稱和事件名稱:

只需要修改子組件:

<template>
  <div>
    <!-- 默認(rèn)的 -->
    <!-- <h3>child組件 -- {{ value }}</h3> -->
    <h3>child組件 -- {{ title }}</h3>
    <!-- 默認(rèn)的 -->
    <!-- <button @click="$emit('input', Date.now())">修改value數(shù)據(jù)</button> -->
    <button @click="$emit('change', Date.now())">修改value數(shù)據(jù)</button>
  </div>
</template>
<script>
export default {
  // 默認(rèn)的
  // props: ['value'],
  props: ["title"],
  model: {
    // 修改v-model中的綁定的屬性名稱,默認(rèn)為value
    prop: "title",
    // 修改v-model它的自定義事件的名稱,默認(rèn)為input
    event: "change",
  },
  data() {
    return {};
  },
};
</script>

10. sync同步動(dòng)態(tài)屬性數(shù)據(jù)

上文說(shuō)到 props 是單向數(shù)據(jù)流,子組件不能修改父組件的數(shù)據(jù),但是加上 sync 修飾符就可以實(shí)現(xiàn)修改 。

父組件:

<template>
  <div>
    <h3 class="title">App組件</h3>
    <hr />
    <!-- 
      sync修飾符,它是一語(yǔ)法糖 動(dòng)態(tài)屬性和 update:屬性名稱 事件
     -->
    <child :title.sync="title" />
  </div>
</template>
<script>
import child from './components/child.vue'
export default {
  components: {
    child
  },
  data() {
    return {
      title: '我是父組件的title'
    }
  },
  methods: {}
}
</script>

子組件:

<template>
  <div>
    <h3>child組件 -- {{ title }}</h3>
    <button @click="setTitle">修改Title</button>
  </div>
</template>
<script>
export default {
  props: ['title'],
  data() {
    return {}
  },
  methods: {
    setTitle() {
      // 這里的update事件是固定寫(xiě)法
      this.$emit('update:title', Date.now())
    }
  }
}
</script>

11. localStorage / sessionStorage

這種通信比較簡(jiǎn)單,缺點(diǎn)是數(shù)據(jù)和狀態(tài)比較混亂,不太容易維護(hù)。

通過(guò)window.localStorage.getItem(key)獲取數(shù)據(jù)

通過(guò)window.localStorage.setItem(key,value) 存儲(chǔ)數(shù)據(jù)

注意用JSON.parse() / JSON.stringify() 做數(shù)據(jù)格式轉(zhuǎn)換

localStorage / sessionStorage可以結(jié)合vuex,實(shí)現(xiàn)數(shù)據(jù)的持久保存,同時(shí)使用vuex解決數(shù)據(jù)和狀態(tài)混亂問(wèn)題。

到此這篇關(guān)于Vue組件間傳值的實(shí)現(xiàn)解析的文章就介紹到這了,更多相關(guān)Vue組件間傳值內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue中keep-alive組件的用法示例

    vue中keep-alive組件的用法示例

    眾所周知keep-alive是Vue提供的一個(gè)抽象組件,主要是用來(lái)對(duì)組件進(jìn)行緩存,從而做到節(jié)省性能,這篇文章主要給大家介紹了關(guān)于vue中keep-alive組件用法的相關(guān)資料,需要的朋友可以參考下
    2021-05-05
  • vue如何解決sass-loader的版本過(guò)高導(dǎo)致的編譯錯(cuò)誤

    vue如何解決sass-loader的版本過(guò)高導(dǎo)致的編譯錯(cuò)誤

    這篇文章主要介紹了vue如何解決sass-loader的版本過(guò)高導(dǎo)致的編譯錯(cuò)誤問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • ElementUI多個(gè)子組件表單的校驗(yàn)管理實(shí)現(xiàn)

    ElementUI多個(gè)子組件表單的校驗(yàn)管理實(shí)現(xiàn)

    這篇文章主要介紹了ElementUI多個(gè)子組件表單實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • vue實(shí)現(xiàn)動(dòng)態(tài)給data函數(shù)中的屬性賦值

    vue實(shí)現(xiàn)動(dòng)態(tài)給data函數(shù)中的屬性賦值

    這篇文章主要介紹了vue實(shí)現(xiàn)動(dòng)態(tài)給data函數(shù)中的屬性賦值,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • vue打包后修改配置后端IP地址、端口等信息兩種方法

    vue打包后修改配置后端IP地址、端口等信息兩種方法

    這篇文章主要給大家介紹了關(guān)于vue打包后修改配置后端IP地址、端口等信息的兩種方法,文中通過(guò)代碼示例以及圖文介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用vue打包具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-09-09
  • 如何監(jiān)聽(tīng)Vue項(xiàng)目報(bào)錯(cuò)的4種方式?

    如何監(jiān)聽(tīng)Vue項(xiàng)目報(bào)錯(cuò)的4種方式?

    本文主要介紹了如何監(jiān)聽(tīng)Vue項(xiàng)目報(bào)錯(cuò)的4種方式,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • vue實(shí)現(xiàn)微信分享功能

    vue實(shí)現(xiàn)微信分享功能

    這篇文章主要介為大家詳細(xì)紹了vue實(shí)現(xiàn)微信分享功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-11-11
  • Vue-resource攔截器判斷token失效跳轉(zhuǎn)的實(shí)例

    Vue-resource攔截器判斷token失效跳轉(zhuǎn)的實(shí)例

    下面小編就為大家?guī)?lái)一篇Vue-resource攔截器判斷token失效跳轉(zhuǎn)的實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-10-10
  • Vue引入部分element.ui組件的一些小坑記錄

    Vue引入部分element.ui組件的一些小坑記錄

    這篇文章主要介紹了Vue引入部分element.ui組件的一些小坑記錄,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • Vue3?Watch踩坑實(shí)戰(zhàn)之watch監(jiān)聽(tīng)無(wú)效

    Vue3?Watch踩坑實(shí)戰(zhàn)之watch監(jiān)聽(tīng)無(wú)效

    Vue.js中的watch選項(xiàng)用于監(jiān)聽(tīng)Vue實(shí)例上某個(gè)特定的數(shù)據(jù)變化,下面這篇文章主要給大家介紹了關(guān)于Vue3?Watch踩坑實(shí)戰(zhàn)之watch監(jiān)聽(tīng)無(wú)效的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-05-05

最新評(píng)論