最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue組件間的通信方式詳析

 更新時(shí)間:2022年09月29日 08:45:51   作者:BestAns???????  
本文介紹Vue組件間通信方式,Vue組件間通信一直是個(gè)重要的話題,雖然官方推出的Vuex狀態(tài)管理方案可以很好的解決組件之間的通信問(wèn)題,但是在組件庫(kù)內(nèi)部使用Vuex往往會(huì)比較重,本文將系統(tǒng)的羅列出幾種不使用Vuex,比較實(shí)用的組件間的通信方式,希望能幫助到大家

前言

在Vue組件庫(kù)開(kāi)發(fā)過(guò)程中,Vue組件之間的通信一直是一個(gè)重要的話題,雖然官方推出的 Vuex 狀態(tài)管理方案可以很好的解決組件之間的通信問(wèn)題,但是在組件庫(kù)內(nèi)部使用 Vuex 往往會(huì)比較重,本文將系統(tǒng)的羅列出幾種不使用 Vuex,比較實(shí)用的組件間的通信方式,供大家參考。

組件之間通信的場(chǎng)景

在進(jìn)入我們今天的主題之前,我們先來(lái)總結(jié)下Vue組件之間通信的幾種場(chǎng)景,一般可以分為如下幾種場(chǎng)景:

  • 父子組件之間的通信
  • 兄弟組件之間的通信
  • 隔代組件之間的通信

父子組件之間的通信

父子組件之間的通信應(yīng)該是 Vue 組件通信中最簡(jiǎn)單也最常見(jiàn)的一種了,概括為兩個(gè)部分:父組件通過(guò)prop向子組件傳遞數(shù)據(jù),子組件通過(guò)自定義事件向父組件傳遞數(shù)據(jù)。

父組件通過(guò) prop 向子組件傳遞數(shù)據(jù)

Vue組件的數(shù)據(jù)流向都遵循單向數(shù)據(jù)流的原則,所有的 prop 都使得其父子 prop 之間形成了一個(gè)單向下行綁定:父級(jí) prop 的更新會(huì)向下流動(dòng)到子組件中,但是反過(guò)來(lái)則不行。這樣會(huì)防止從子組件意外變更父級(jí)組件的狀態(tài),從而導(dǎo)致你的應(yīng)用的數(shù)據(jù)流向難以理解。

額外的,每次父級(jí)組件發(fā)生變更時(shí),子組件中所有的 prop 都將會(huì)刷新為最新的值。這意味著你不應(yīng)該在一個(gè)子組件內(nèi)部改變 prop。如果你這樣做了,Vue 會(huì)在瀏覽器的控制臺(tái)中發(fā)出警告。

父組件 ComponentA:

<template>
  <div>
    <component-b title="welcome"></component-b>
  </div>
</template>
<script>
import ComponentB from './ComponentB'

export default {
  name: 'ComponentA',
  components: {
    ComponentB
  }
}
</script>

子組件 ComponentB:

<template>
  <div>
    <div>{{title}}</div>
  </div>
</template>
<script>
export default {
  name: 'ComponentB',
  props: {
    title: {
      type: String,
    }
  }
} 
</script>

子組件通過(guò)自定義事件向父組件傳遞數(shù)據(jù)

在子組件中可以通過(guò) $emit 向父組件發(fā)生一個(gè)事件,在父組件中通過(guò) v-on/@ 進(jìn)行監(jiān)聽(tīng)。

子組件 ComponentA:

<template>
  <div>
    <component-b :title="title" @title-change="titleChange"></component-b>
  </div>
</template>
<script>
import ComponentB from './ComponentB'

export default {
  name: 'ComponentA',
  components: {
    ComponentB
  },
  data: {
    title: 'Click me'
  },
  methods: {
    titleChange(newTitle) {
      this.title = newTitle
    } 
  }
}
</script>

子組件 ComponentB:

<template>
  <div>
    <div @click="handleClick">{{title}}</div>
  </div>
</template>
<script>
export default {
  name: 'ComponentB',
  props: {
    title: {
      type: String,
    }
  },
  methods: {
    handleClick() {
      this.$emit('title-change', 'New title !')
    }  
  }
} 
</script>

這個(gè)例子非常簡(jiǎn)單,在子組件 ComponentB 里面通過(guò) $emit 派發(fā)一個(gè)事件 title-change,在父組件 ComponentA 通過(guò) @title-change 綁定的 titleChange 事件進(jìn)行監(jiān)聽(tīng),ComponentB 向 ComponentA 傳遞的數(shù)據(jù)在 titleChange 函數(shù)的傳參中可以獲取到。

兄弟組件之間的通信

狀態(tài)提升

寫(xiě)過(guò) React 的同學(xué)應(yīng)該對(duì)組件的 狀態(tài)提升 概念并不陌生,React 里面將組件按照職責(zé)的不同劃分為兩類(lèi):展示型組件(Presentational Component) 和 容器型組件(Container Component)。

展示型組件不關(guān)心組件使用的數(shù)據(jù)是如何獲取的,以及組件數(shù)據(jù)應(yīng)該如何修改,它只需要知道有了這些數(shù)據(jù)后,組件UI是什么樣子的即可。外部組件通過(guò) props 傳遞給展示型組件所需的數(shù)據(jù)和修改這些數(shù)據(jù)的回調(diào)函數(shù),展示型組件只是它們的使用者。

容器型組件的職責(zé)是獲取數(shù)據(jù)以及這些數(shù)據(jù)的處理邏輯,并把數(shù)據(jù)和邏輯通過(guò) props 提供給子組件使用。

因此,參考 React 組件中的 狀態(tài)提升 的概念,我們?cè)趦蓚€(gè)兄弟組件之上提供一個(gè)父組件,相當(dāng)于容器組件,負(fù)責(zé)處理數(shù)據(jù),兄弟組件通過(guò) props 接收參數(shù)以及回調(diào)函數(shù),相當(dāng)于展示組件,來(lái)解決兄弟組件之間的通信問(wèn)題。

ComponentA(兄弟組件A):

<template>
  <div>
    <div>{{title}}</div>
    <div @click="changeTitle">click me</div>
  </div>
</template>
<script>
export default {
  name: 'ComponentA',
  props: {
    title: {
      type: String
    },
    changeTitle: Function
  }
}
</script>

ComponentB(兄弟組件B):

<template>
  <div>
    <div>{{title}}</div>
    <div @click="changeTitle">click me</div>
  </div>
</template>
<script>
export default {
  name: 'ComponentB',
  props: {
    title: {
      type: String
    },
    changeTitle: Function
  }
}
</script>

ComponentC(容器組件C):

<template>
  <div>
    <component-a :title="titleA" :change-title="titleAChange"></component-a>
    <component-b :title="titleB" :change-title="titleBChange"></component-b>
  </div>
</template>
<script>
import ComponentA from './ComponentA'
import ComponentB from './ComponentB'

export default {
  name: 'ComponentC',
  components: {
    ComponentA,
    ComponentB
  },
  data: {
    titleA: 'this is title A',
    titleB: 'this is title B'
  },
  methods: {
    titleAChange() {
      this.titleA = 'change title A'
    },
    titleBChange() {
      this.titleB = 'change title B'
    }
  }
}
</script>

可以看到,上述這種 "狀態(tài)提升" 的方式是比較繁瑣的,特別是兄弟組件的通信還要借助于父組件,組件復(fù)雜之后處理起來(lái)是相當(dāng)麻煩的。

隔代組件之間的通信

隔代組件之間的通信可以通過(guò)如下幾種方式實(shí)現(xiàn):

  • $attrs/$listeners
  • rovide/inject
  • 基于 $parent/$children 實(shí)現(xiàn)的 dispatch 和 broadcast

attrs/attrs/listeners

Vue 2.4.0 版本新增了 $attrs 和 $listeners 兩個(gè)方法。先看下官方對(duì) $attrs 的介紹:

包含了父作用域中不作為 prop 被識(shí)別 (且獲取) 的 attribute 綁定(class 和 style 除外)。當(dāng)一個(gè)組件沒(méi)有聲明任何 prop 時(shí),這里會(huì)包含所有父作用域的綁定 (class 和 style 除外),并且可以通過(guò) v-bind="$attrs" 傳入內(nèi)部組件——在創(chuàng)建高級(jí)別的組件時(shí)非常有用。

看個(gè)例子:

組件A(ComponentA):

<template>
  <component-a name="Lin" age="24" sex="male"></component-a>
</template>
<script>
import ComponentB from '@/components/ComponentB.vue'

export default {
  name: 'App',
  components: {
    ComponentA
  }
}
</script>

組件B(ComponetB):

<template>
  <div>
    I am component B
    <component-c v-bind="$attrs"></component-c>
  </div>
</template>
<script>
import ComponentC from '@/components/ComponentC.vue'

export default {
  name: 'ComponentB',
  inheritAttrs: false,
  components: {
    ComponentC
  }
}
</script>

組件C(ComponetC):

<template>
  <div>
    I am component C
  </div>
</template>
<script>

export default {
  name: 'ComponentC',
  props: {
    name: {
      type: String
    }
  },
  mounted: function() {
    console.log('$attrs', this.$attrs)
  }
}
</script>

這里有三個(gè)組件,祖先組件(ComponentA)、父組件(ComponentB)和子組件(ComponentC)。這三個(gè)組件構(gòu)成了一個(gè)典型的子孫組件之間的關(guān)系。

ComponetA 給 ComponetB 傳遞了三個(gè)屬性 name、age 和 sex,ComponentB 通過(guò) v-bind="$attrs" 將這三個(gè)屬性再透?jìng)?/strong>給 ComponentC, 最后在 ComponentC 中打印 $attrs 的值為:

{age: '24', sex: 'male'}

為什么我們一開(kāi)始傳遞了三個(gè)屬性,最后只打印了兩個(gè)屬性 age 和 sex 呢?因?yàn)樵?ComponentC 的props 中聲明了 name 屬性,$attrs 會(huì)自動(dòng)排除掉在 props 中聲明的屬性,并將其他屬性以對(duì)象的形式輸出。

說(shuō)白了就是一句話,$attrs 可以獲取父組件中綁定的非 Props 屬性。

一般在使用的時(shí)候會(huì)同時(shí)和 inheritAttrs 屬性配合使用。

如果你不希望組件的根元素繼承 attribute,你可以在組件的選項(xiàng)中設(shè)置 inheritAttrs: false

在 ComponentB 添加了 inheritAttrs=false 屬性后,ComponentB 的dom結(jié)構(gòu)中可以看到是不會(huì)繼承父組件傳遞過(guò)來(lái)的屬性:

如果不加上 inheritAttrs=false 屬性,就會(huì)自動(dòng)繼承父組件傳遞過(guò)來(lái)的屬性:

再看下 $listeners 的定義:

包含了父作用域中的 (不含 .native 修飾器的) v-on 事件監(jiān)聽(tīng)器。它可以通過(guò) v-on="$listeners" 傳入內(nèi)部組件——在創(chuàng)建更高層次的組件時(shí)非常有用。

$listeners也能把父組件中對(duì)子組件的事件監(jiān)聽(tīng)全部拿到,這樣我們就能用一個(gè)v-on把這些來(lái)自于父組件的事件監(jiān)聽(tīng)傳遞到下一級(jí)組件。

繼續(xù)改造 ComponentB 組件:

<template>
  <div>
    I am component B
    <component-c v-bind="$attrs" v-on="$listeners"></component-c>
  </div>
</template>
<script>
import ComponentC from '@/components/ComponentC.vue'

export default {
  name: 'ComponentB',
  inheritAttrs: false,
  components: {
    ComponentC
  }
}
</script>

這里利用 $attrs 和 $listeners 方法,可以將祖先組件(ComponentA) 中的屬性和事件透?jìng)鹘o孫組件(ComponentC),這樣就可以實(shí)現(xiàn)隔代組件之間的通信。

provide/inject

provide/inject 是 Vue 2.2.0 版本后新增的方法。

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

先看下簡(jiǎn)單的用法:

父級(jí)組件:

export default {
  provide: {
    name: 'Lin'
  }
}

子組件:

export default {
  inject: ['name'],
  mounted () {
    console.log(this.name);  // Lin
  }
}

上面的例子可以看到,父組件通過(guò) privide 返回的對(duì)象里面的值,在子組件中通過(guò) inject 注入之后可以直接訪問(wèn)到。

但是需要注意的是,provide 和 inject 綁定并不是可響應(yīng)的,按照官方的說(shuō)法,這是刻意為之的。

也就是說(shuō)父組件 provide 里面的name屬性值變化了,子組件中 this.name 獲取到的值不變。

如果想讓 provide 和 inject 變成可響應(yīng)的,有以下兩種方式:

  • provide 祖先組件的實(shí)例,然后在子孫組件中注入依賴(lài),這樣就可以在子孫組件中直接修改祖先組件的實(shí)例的屬性,不過(guò)這種方法有個(gè)缺點(diǎn)就是這個(gè)實(shí)例上掛載很多沒(méi)有必要的東西比如props,methods
  • 使用 Vue 2.6 提供的 Vue.observable 方法優(yōu)化響應(yīng)式 provide

看一下第一種場(chǎng)景:

祖先組件組件(ComponentA):

export default {
  name: 'ComponentA',
  provide() {
    return {
      app: this
    }
  },
  data() {
    return {
       appInfo: {
         title: ''
       }
    }
  },
  methods: {
    fetchAppInfo() {
      this.appInfo = { title: 'Welcome to Vue world'}
    }
  }
}

我們把整個(gè) ComponentA.vue 的實(shí)例 this 對(duì)外提供,命名為 app。接下來(lái),任何組件只要通過(guò) inject 注入 app 的話,都可以直接通過(guò) this.app.xxx 來(lái)訪問(wèn) ComponentA.vue 的 data、computed、methods 等內(nèi)容。

子組件(ComponentB):

<template>
  <div>
    {{ title }}
    <button @click="fetchInfo">獲取App信息</button>
  </div>
</template>
<script>
export default {
  name: 'ComponentB',
  inject: ['app'],
  computed: {
    title() {
      return this.app.appInfo.title
    }
  },
  methods: {
    fetchInfo() {
      this.app.fetchAppInfo()
    } 
  }
}
</script>

這樣,任何子組件,只要通過(guò) inject 注入 app 后,就可以直接訪問(wèn)祖先組件中的數(shù)據(jù)了,同時(shí)也可以調(diào)用祖先組件提供的方法修改祖先組件的數(shù)據(jù)并反應(yīng)到子組件上。

當(dāng)點(diǎn)擊子組件(ComponentB)的獲取App信息按鈕,會(huì)調(diào)用 this.app.fetchAppInfo 方法,也就是訪問(wèn)祖先組件(ComponentA)實(shí)例上的 fetchAppInfo 方法,fetchAppInfo 會(huì)修改fetchAppInfo的值。同時(shí)子組件(ComponentB)中會(huì)監(jiān)聽(tīng) this.app.appInfo 的變化,并將變化后的title值顯示在組件上。

再看一下第二種場(chǎng)景,通過(guò) Vue.observable 方法來(lái)實(shí)現(xiàn) provide 和 inject 綁定并可響應(yīng)。

基于上面的示例,改造祖先組件(ComponentA):

import Vue from 'vue'

const state = Vue.observable({ title: '' });
export default {
  name: 'ComponentA',
  provide() {
    return {
      state
    }
  }
}

使用 Vue.observable 定義一個(gè)可響應(yīng)的對(duì)象 state,并在 provide 中返回這個(gè)對(duì)象。

改造子組件(ComponentB):

<template>
  <div>
    {{ title }}
    <button @click="fetchInfo">獲取App信息</button>
  </div>
</template>
<script>
export default {
  name: 'ComponentInject',
  inject: ['state'],
  computed: {
    title() {
      return this.state.title
    }
  },
  methods: {
    fetchInfo() {
      this.state.title = 'Welcome to Vue world22'
    } 
  }
}
</script>

與之前的例子不同的是,這里我們直接修改了 this.state.title 的值,因?yàn)?state 被定義成了一個(gè)可響應(yīng)的數(shù)據(jù),所以 state.title 的值被修改后,視圖上的 title 也會(huì)立即響應(yīng)并更新,從這里看,其實(shí)很像 Vuex 的處理方式。

以上兩種方式對(duì)比可以發(fā)現(xiàn),第二種借助于 Vue.observable 方法實(shí)現(xiàn) provide 和 inject 的可響應(yīng)更加簡(jiǎn)單高效,推薦大家使用這種方式。

基于 $parent/$children 實(shí)現(xiàn)的 dispatch 和 broadcast

先了解下 dispatch 和 broadcast 兩個(gè)概念:

  • dispatch: 派發(fā),指的是從一個(gè)組件內(nèi)部向上傳遞一個(gè)事件,并在組件內(nèi)部通過(guò) $on 進(jìn)行監(jiān)聽(tīng)
  • broadcast: 廣播,指的是從一個(gè)組件內(nèi)部向下傳遞一個(gè)事件,并在組件內(nèi)部通過(guò) $on 進(jìn)行監(jiān)聽(tīng)

在實(shí)現(xiàn) dispatch 和 broadcast 方法之前,先來(lái)看一下具體的使用方法。有 ComponentA.vue 和 ComponentB.vue 兩個(gè)組件,其中 ComponentB 是 ComponentA 的子組件,中間可能跨多級(jí),在 ComponentA 中向 ComponentB 通信:

組件ComponentA:

<template>
  <button @click="handleClick">派發(fā)事件</button>
</template>
<script>
import Emitter from '../mixins/emitter.js';
export default {
  name: 'ComponentA',
  mixins: [Emitter],
  methods: {
    handleClick () {
      this.dispatch('ComponentB', 'on-message', 'Hello Vue.js')
    }
  }
}
</script>

組件ComponentB:

export default {
  name: 'ComponentB',
  created () {
    this.$on('on-message', this.showMessage)
  },
  methods: {
    showMessage (text) {
      console.log(text)
    }
  }
}

dispatch 的邏輯寫(xiě)在 emitter.js 中,使用的時(shí)候通過(guò) mixins 混入到組件中,這樣可以很好的將事件通信邏輯和組件進(jìn)行解耦。

dispatch 的方法有三個(gè)傳參,分別是:需要接受事件的組件的名字(全局唯一,用來(lái)精確查找組件)、事件名和事件傳遞的參數(shù)。

dispatch 的實(shí)現(xiàn)思路非常簡(jiǎn)單,通過(guò) $parent 獲取當(dāng)前父組件對(duì)象,如果組件的name和接受事件的name一致(dispatch方法的第一個(gè)參數(shù)),在父組件上調(diào)用 $emit 發(fā)射一個(gè)事件,這樣就會(huì)觸發(fā)目標(biāo)組件上 $on 定義的回調(diào)函數(shù),如果當(dāng)前組件的name和接受事件的name不一致,就遞歸地向上調(diào)用此邏輯。

dispath:

export default {
  methods: {
    dispatch(componentName, eventName, params) {
      let parent = this.$parent || this.$root;
      let name = parent.$options.name;
      while (parent && (!name || name !== componentName)) {
        parent = parent.$parent;
        if (parent) {
          name = parent.$options.name
        }
      }
      if (parent) {
        parent.$emit.apply(parent, [eventName].concat(params));
      }
    }
  }
}

broadcast邏輯和dispatch的邏輯差不多,只是一個(gè)是通過(guò) $parent 向上查找,一個(gè)是通過(guò) $children 向下查找,

export default {
  methods: {
    broadcast(componentName, eventName, params) {
      this.$children.forEach(child => {
        const name = child.$options.name
        if (name === componentName) {
          child.$emit.apply(child, [eventName].concat(params))
        } else {
          broadcast.apply(child, [componentName, eventName].concat([params]))
        }
      })
    }
  }
}

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

相關(guān)文章

  • Vue2.0+ElementUI+PageHelper實(shí)現(xiàn)的表格分頁(yè)功能

    Vue2.0+ElementUI+PageHelper實(shí)現(xiàn)的表格分頁(yè)功能

    ElementUI也是一套很不錯(cuò)的組件庫(kù),對(duì)于我們經(jīng)常用到的表格、表單、時(shí)間日期選擇器等常用組件都有著很好的封裝和接口。這篇文章主要介紹了Vue2.0+ElementUI+PageHelper實(shí)現(xiàn)的表格分頁(yè),需要的朋友可以參考下
    2021-10-10
  • vue通過(guò)接口直接下載java生成好的Excel表格案例

    vue通過(guò)接口直接下載java生成好的Excel表格案例

    這篇文章主要介紹了vue通過(guò)接口直接下載java生成好的Excel表格案例
    2020-10-10
  • Vue雙向綁定原理及實(shí)現(xiàn)方法

    Vue雙向綁定原理及實(shí)現(xiàn)方法

    Vue雙向綁定是指數(shù)據(jù)模型和視圖之間的數(shù)據(jù)同步,通過(guò)Object.defineProperty()方法實(shí)現(xiàn)數(shù)據(jù)劫持,利用觀察者模式實(shí)現(xiàn)數(shù)據(jù)更新和視圖更新的自動(dòng)同步,實(shí)現(xiàn)方式包括指令、計(jì)算屬性、v-model等,優(yōu)化方法包括使用虛擬DOM、合理使用computed和watch等
    2023-04-04
  • vuex中的state、getters、mutations、actions之間的關(guān)系解讀

    vuex中的state、getters、mutations、actions之間的關(guān)系解讀

    這篇文章主要介紹了vuex中的state、getters、mutations、actions之間的關(guān)系,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • Console高級(jí)用法總結(jié)

    Console高級(jí)用法總結(jié)

    Console 對(duì)象提供了瀏覽器控制臺(tái)調(diào)試的接口。在不同宿主環(huán)境上它的工作方式可能不一樣,但通常都會(huì)提供一套共性的功能,本文主要總結(jié)了Console的一些高級(jí)用法,感興趣的小伙伴可以參考一下
    2023-04-04
  • Vue el-table表頭上引入組件不能實(shí)時(shí)傳參解決方法分析

    Vue el-table表頭上引入組件不能實(shí)時(shí)傳參解決方法分析

    這篇文章主要介紹了Vue el-table表頭上引入組件不能實(shí)時(shí)傳參解決方法,總的來(lái)說(shuō)這并不是一道難題,那為什么要拿出這道題介紹?拿出這道題真正想要傳達(dá)的是解題的思路,以及不斷優(yōu)化探尋最優(yōu)解的過(guò)程。希望通過(guò)這道題能給你帶來(lái)一種解題優(yōu)化的思路
    2022-11-11
  • 詳解webpack+vue-cli項(xiàng)目打包技巧

    詳解webpack+vue-cli項(xiàng)目打包技巧

    本篇文章主要介紹了詳解webpack+vue-cli項(xiàng)目打包技巧 ,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-06-06
  • 在Vue中使用Immutable.js的步驟

    在Vue中使用Immutable.js的步驟

    這篇文章主要介紹了在Vue中使用Immutable.js的步驟,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-09-09
  • Vue element-UI el-select循環(huán)選中的問(wèn)題

    Vue element-UI el-select循環(huán)選中的問(wèn)題

    這篇文章主要介紹了Vue element-UI el-select循環(huán)選中的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • vue條件渲染列表渲染原理示例詳解

    vue條件渲染列表渲染原理示例詳解

    這篇文章主要為大家介紹了vue條件渲染列表渲染原理示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07

最新評(píng)論

星座| 卢湾区| 余江县| 龙胜| 柯坪县| 长沙市| 巴青县| 常宁市| 剑川县| 双城市| 舟曲县| 玛纳斯县| 旅游| 寿光市| 吉首市| 沙雅县| 饶平县| 靖宇县| 屯昌县| 繁峙县| 太湖县| 西平县| 额尔古纳市| 胶州市| 巴中市| 新营市| 和平区| 淮安市| 易门县| 凤台县| 锦州市| 河北省| 新郑市| 海伦市| 陇西县| 区。| 玉林市| 肃南| 宜丰县| 乳山市| 绥德县|