91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

redux以及react-redux的示例分析

發布時間:2021-08-02 10:22:19 來源:億速云 閱讀:135 作者:小新 欄目:web開發

這篇文章給大家分享的是有關redux以及react-redux的示例分析的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

redux 簡介

隨著 JavaScript 單頁應用開發日趨復雜,JavaScript 需要管理比任何時候都要多的 state (狀態)。 這些 state 可能包括服務器響應、緩存數據、本地生成尚未持久化到服務器的數據,也包括 UI 狀態,如激活的路由,被選中的標簽,是否顯示加載動效或者分頁器等等。

管理不斷變化的 state 非常困難。如果一個 model 的變化會引起另一個 model 變化,那么當 view 變化時,就可能引起對應 model 以及另一個 model 的變化,依次地,可能會引起另一個 view 的變化。直至你搞不清楚到底發生了什么。state 在什么時候,由于什么原因,如何變化已然不受控制。 當系統變得錯綜復雜的時候,想重現問題或者添加新功能就會變得舉步維艱。

如果這還不夠糟糕,考慮一些來自前端開發領域的新需求,如更新調優、服務端渲染、路由跳轉前請求數據等等。前端開發者正在經受前所未有的復雜性,難道就這么放棄了嗎?當然不是。

這里的復雜性很大程度上來自于:我們總是將兩個難以理清的概念混淆在一起:變化和異步。 如果把二者分開,能做的很好,但混到一起,就變得一團糟。一些庫如 React 試圖在視圖層禁止異步和直接操作 DOM 來解決這個問題。美中不足的是,React 依舊把處理 state 中數據的問題留給了我們自己。而 redux 就可以來幫我管理這些狀態;

redux以及react-redux的示例分析

demo 結構樹
├── config-overrides.js
├── .gitignore
├── package.json
├── package-lock.json
├── public
│ ├── favicon.ico
│ ├── index.html
│ └── manifest.json
├── README.md
└── src
 ├── App.js
 ├── Demo
 │ ├── actionCreate.js
 │ ├── Demo.jsx
 │ ├── react-redux.js
 │ ├── reducer.js
 │ ├── redux.js
 │ ├── style.css
 │ └── thunk.js
 └── index.js

一、 redux API createStore 的實現

  首先我們先結合 reducer 以及 action 的知識簡單實現開頭展示的 demo, 并逐步揭曉 createStore 的神秘面紗;

1.1 準備工作:

創建 reducer 并導出 reducer
// reducer.js
const initState = { user: 'qianyin', age: 18, sex: '男' };
export const reducer = (state=initState, action) => {
 switch(action.type){
 case 'USER_UPDATE':
  return {...state, ...action.payload};
 case 'AGE_GROW':
  return {...state, age: state.age + 1};
 case 'SEX_UPDATE':
  return {...state, ...action.payload};
 default:
  return state;
 }
}
創建 action 創建函數
// actionCreate.js
export const changeUser = (user) => {
 return {
 payload:{user},
 type: 'USER_UPDATE',
 };
}

export const changeAge = () => {
 return { type: 'AGE_GROW' };
}
通過 react 在頁面上預先繪制出基本的元素
/* style.css */
.btn{
 height: 31px;

}
.input{
 height: 25px;
}
// Demo.jsx
import React from 'react';
import './style.css';

export default class Demo extends React.Component{
 onChange = () => {}
 onClick = () => {}
 render(){
 return (
  <div>
  <p>user: xxx, age: xxx</p>
  user: 
  <input type="text" className="input" onChange={this.onChange}/>
  &nbsp;
  <button className="btn" onClick={this.onClick}>年齡增長</button>
  </div>
 );
 }
}
最終頁面將渲染如下:

redux以及react-redux的示例分析

1.2 demo 的初次實現代碼

  • 創建全局狀態 state;

  • 創建監聽隊列;

  • 針對監聽隊列,新增函數用于將指定監聽對象添加到隊列中;

  • 在函數 dispatch 中執行 reducer 將返回值作為新的 state, 同時依次執行監聽對象;

  • 默認執行一次 dispatch 給定一個 type 相對唯一的 action, 目的是為了匹配 reducer 的默認狀態值,從而實現對 redux state 的初始化;

  • 在組件 Demo 通過在函數 update 使用 this.setState 將全局 state 保存到 react state 中,并將函數 update 添加到監聽隊列中;從而使得當我們一旦試圖通過 dispatch 修改全局狀態時,能夠及時更新 react state 最終觸發 react 生命周期 render;

  • 在 react 生命周期 componentDidMount 中我們除了將 update 添加到監聽隊列以外,還需手動執行一次 update 其主要目的就是為了首次初始化 react state;

// Demo.jsx
import React from 'react';
import { changeAge, changeUser } from './actionCreate';
import { reducer } from './reducer';
import './style.css';

let state;
const listeners = [];
const subscribe = (listener) => {
 listeners.push(listener);
}
const dispatch = (action) => {
 state = reducer(state, action);
 console.log(state);
 listeners.forEach(v => v());
}
dispatch({type: '%$&HJKAJJHDJHJ'});

export default class Demo extends React.Component{
 state = {user: 'xxx', age: 'xxx'};
 componentDidMount(){
 subscribe(this.update);
 this.update();
 }

 update = () => {
 this.setState(state);
 }

 onChange = (e) => {
 dispatch(changeUser(e.target.value));
 }

 onClick = () => {
 dispatch(changeAge());
 }

 render(){
 return (
  <div>
  <p>user: {this.state.user}, age: {this.state.age}</p>
  user: 
  <input type="text" className="input" onChange={this.onChange}/>
  &nbsp;
  <button className="btn" onClick={this.onClick}>年齡增長</button>
  </div>
 );
 }
}

1.3 API createStore 的實現

其實上文的代碼中對于 createStore 的實現原理已經基本描述清除,下面我們只是單純的對代碼進行了簡單的封裝;當然為了能夠獲取到 state 我們專門增加了一個函數 getState 來實現它;

createStore 函數實現
// redux.js

export const createStore = (reducer) => {
 // 聲明常量
 let state;
 const listeners = [];

 // 獲取狀態
 const getState = () => {
 return state;
 }

 // 添加監聽對象
 const subscribe = (listener) => {
 listeners.push(listener);
 }

 // [1]執行reducer修改狀態 [2]遍歷執行監聽對象
 const dispatch = (action) => {
 state = reducer(state, action);
 listeners.forEach(v => v());
 }

 // 初始化 state
 dispatch({type: '%$&HJKAJJHDJHJ'});
 
 // 暴露接口
 return {getState, subscribe, dispatch};
}
調用 createStore 并對 demo 進行修改
// Demo.jsx
import React from 'react';
import './style.css';
import { changeAge, changeUser } from './actionCreate';
import { reducer } from './reducer';
import { createStore } from './redux';

const store = createStore(reducer);

export default class Demo extends React.Component{
 state = {user: 'xxx', age: 'xxx'};
 componentDidMount(){
 store.subscribe(this.update);
 this.update();
 }

 update = () => {
 this.setState(store.getState());
 }

 onChange = (e) => {
 store.dispatch(changeUser(e.target.value));
 }

 onClick = () => {
 store.dispatch(changeAge());
 }

 render(){
 return (
  <div>
  <p>user: {this.state.user}, age: {this.state.age}</p>
  user: 
  <input type="text" className="input" onChange={this.onChange}/>
  &nbsp;
  <button className="btn" onClick={this.onClick}>年齡增長</button>
  </div>
 );
 }
}

二、 react-redux API Provider 的實現

在 react 中大多數情況下我們需要將狀態傳遞給后代組件進行使用的,當然通過 props 是可以實現狀態從父級到子級的傳遞,但是當狀態需要傳遞的層級比較深的情況下再使用 props 就顯得無力了,那么在 react-redux 中它是如何實現對 store 的傳遞的呢?

2.1 react context 的引入

在 App.js 中創建 store 并通過 context 傳遞 store
// App.js
import React, { Component } from 'react';
import propTypes from 'prop-types';
import { createStore } from './Demo/redux';
import { reducer } from './Demo/reducer';
import Demo from './Demo/Demo';

// 創建 store
const store = createStore(reducer);

class App extends Component {
 // 聲明 childContextTypes 狀態屬性類型
 static childContextTypes = {
 store: propTypes.object
 };
 // 設置 childContext
 getChildContext(){
 return {store}
 }
 render() {
 return <Demo />;
 }
}
export default App;
在子組件 Demo 中通過 context 獲取 store 并對代碼進行簡單修改
// Demo.jsx
import React from 'react';
import propTypes from 'prop-types';
import './style.css';
import { changeAge, changeUser } from './actionCreate';

export default class Demo extends React.Component{
 // 設置 context 狀態值類型
 static contextTypes = {
 store: propTypes.object
 };

 constructor(props, context){
 super(props, context);
 // 獲取store
 this.store = context.store;
 this.state = {user: 'xxx', age: 'xxx'};
 }
 
 componentDidMount(){
 this.store.subscribe(this.update);
 this.update();
 }

 update = () => {
 this.setState(this.store.getState());
 }

 onChange = (e) => {
 this.store.dispatch(changeUser(e.target.value));
 }

 onClick = () => {
 this.store.dispatch(changeAge());
 }

 render(){
 return (
  <div>
  <p>user: {this.state.user}, age: {this.state.age}</p>
  user: 
  <input type="text" className="input" onChange={this.onChange}/>
  &nbsp;
  <button className="btn" onClick={this.onClick}>年齡增長</button>
  </div>
 );
 }
}

2.2 封裝代碼實現 Provider

通過 react context 我們實現了對 store 的傳遞,到這里 Provider 的功能以及實現原理基本上應該算是清晰了,無非就是對組件進行包裹同時通過 react context 來傳遞共享 store;那么接下來我們通過對代碼的封裝來實現 Provider 組件;

Provider 組件:實現對 store 的傳遞
// react-redux.js
import React from 'react';
import propTypes from 'prop-types';

export class Provider extends React.Component{
 // 設置 childContext 狀態值類型
 static childContextTypes = {
 store: propTypes.object
 };

 // 設置 childContext
 getChildContext(){
 return {store: this.props.store}
 }
 
 render(){
 return this.props.children;
 }
}
重寫 App.js: 對 Provider 組件的調用
// App.js
import React, { Component } from 'react';
import { createStore } from './Demo/redux';
import { Provider } from './Demo/react-redux';
import { reducer } from './Demo/reducer';
import Demo from './Demo/Demo';

// 創建 store
const store = createStore(reducer);

class App extends Component {
 render() {
 // 調用接口 Provider
 return <Provider store={store}><Demo /></Provider>;
 }
}
export default App;

三、 react-redux API connect 高階組件的實現

上文中在后代組件如果需要獲取 store 則需要手動通過獲取 react context 來調用 store 并且需要顯性的調用 store 內部的方法來進行一些操作;接下來我們來實現這么一個高階組件 connect,我們只需要提供所需的 redux state 以及 action 創建函數,即可通過 props 獲取到相應的 redux state , 并且允許直接通過 props 調用action 創建函數來試圖修改 redux state ;

創建高階組件 connect
// react-redux.js
export const connect = (mapStateToProps, mapDispatchToProps) => (Component) => {
 return class NewComponent extends React.Component{
 render(){
  return <Component />
 }
 }
}
獲取store
// react-redux.js
export const connect = (mapStateToProps, mapDispatchToProps) => (Component) => {
 return class NewComponent extends React.Component{
 // 設置 context 狀態值類型
 static contextType = {
  store: propTypes.object
 };
  // [1]獲取 store [2]設置空 react state
 constructor(props, context){
  super(props, context);
  this.store = context.store;
  this.state = {};
 }
 render(){
  return <Component />
 }
 }
}
添加監聽對象,并嘗試通過 props 將狀態傳遞給子組件
export const connect = (mapStateToProps, mapDispatchToProps) => (Component) => {
 return class NewComponent extends React.Component{
 static contextType = {
  store: propTypes.object
 };
 constructor(props, context){
  super(props, context);
  this.store = context.store;
  this.state = {};
 }
  // [1]添加監聽對象 [2]手動執行監聽對象,初始化 react state
 componentDidMount(){
  this.store.subscribe(this.update);
  this.update();
 }
 
 update = () => {
  // 獲取全部redux state 并添加到 react state
  const state = this.store.getState();
  this.setState(state);
 }
 render(){
  // 通過 props 將 react state 全部傳給子組件
  return <Component {...this.state} />
 }
 }
}
通過 mapStateToProps 獲取指定 redux state
// react-redux.js
export const connect = (mapStateToProps, mapDispatchToProps) => (Component) => {
 return class NewComponent extends React.Component{
 static contextType = {
  store: propTypes.object
 };
 constructor(props, context){
  super(props, context);
  this.store = context.store;
  this.state = {};
 }
 componentDidMount(){
  this.store.subscribe(this.update);
  this.update();
 }
 
 update = () => {
  // 執行 mapStateToProps 只獲取用戶指定需求的 state
  const state = this.store.getState();
  const filterState = mapStateToProps(state);
  this.setState(filterState);
 }
 render(){
  return <Component {...this.state} />
 }
 }
}
通過 mapDispatchToProps 獲取 action 創建函數: 使用 dispatch 包裹后返回
// react-redux.js
// react-redux.js
export const connect = (mapStateToProps, mapDispatchToProps) => (Component) => {
 return class NewComponent extends React.Component{
 static contextTypes = {
  store: propTypes.object
 };
 constructor(props, context){
  super(props, context);
  this.store = context.store;
  this.state = {};
 }
 componentDidMount(){
  this.store.subscribe(this.update);
  this.update();
 }
 
 update = () => {
  // 處理 state ===> 獲取用戶指定的 state
  const state = this.store.getState();
  const filterState = mapStateToProps(state);

  // 使用 dispatch 對 mapDispatchToProps 中的 action 創建函數進行包裹后返回
  const actionFun = {};
  for(let key in mapDispatchToProps){
  actionFun[key] = (...args) => {
   this.store.dispatch(mapDispatchToProps[key](...args));
  }
  }
 // 一種簡寫方式: 騷操作
 // const actionFun = Object.keys(mapDispatchToProps)
 // .reduce((total, item) => {
 // return { ...total, [item]: (...args) => {dispatch(mapDispatchToProps[item](...args));}
 // } } ,{});

  this.setState({...filterState, ...actionFun});
 }
 render(){
  return <Component {...this.state} />
 }
 }
}
調用高階組件:修改 Demo.jsx
// Demo.jsx
import React from 'react';
import { changeAge, changeUser } from './actionCreate';
import { connect } from './react-redux';
import './style.css';

// 編寫 mapStateToProps 參數 redux state 返回所需的 redux state
const mapStateToProps = (state) => {
 return {user: state.user, age: state.age};
}

// 調用高階組件
@connect(mapStateToProps, {changeAge, changeUser})
export default class Demo extends React.Component{
 onChange = (e) => {
 this.props.changeUser(e.target.value);
 }
 onClick = () => {
 this.props.changeAge();
 }
 render(){
 return (
  <div>
  <p>user: {this.props.user}, age: {this.props.age}</p>
  user: 
  <input type="text" className="input" onChange={this.onChange}/>
  &nbsp;
  <button className="btn" onClick={this.onClick}>年齡增長</button>
  </div>
 );
 }
}

四、redux API bindactioncreators 的實現

在上文我們對 mapDispatchToProps 的處理過程就是 API bindactioncreators 的功能: 將給定 action 創建函數使用 dispatch 進行包裹后返回;

封裝 bindactioncreators
// redux.js
export const bindactioncreators = (mapDispatchToProps, dispatch) => {
 const actionFun = {};
 // 遍歷 mapDispatchToProps 中每個 action 創建函數 并使用 dispatch 包裹后返回
 for(let key in mapDispatchToProps){
 actionFun[key] = (...args) => {
  dispatch(mapDispatchToProps[key](...args));
 }
 }

 return actionFun;
 // 一種簡寫方式: 騷操作
 // return actionFun = Object.keys(mapDispatchToProps)
 // .reduce((total, item) => {
 // return { ...total, [item]: (...args) => {dispatch(mapDispatchToProps[item](...args));}
 // } } ,{});
}
修改 connect :
// react-redux.js
import { bindactioncreators } from './redux';
....
export const connect = (mapStateToProps, mapDispatchToProps) => (Component) => {
 return class NewComponent extends React.Component{
 static contextTypes = {
  store: propTypes.object
 };
 constructor(props, context){
  super(props, context);
  this.store = context.store;
  this.state = {};
 }
 componentDidMount(){
  this.store.subscribe(this.update);
  this.update();
 }
 
 update = () => {
  const state = this.store.getState();
  const filterState = mapStateToProps(state);
  
  // 調用 API bindactioncreators 
  // 對 mapDispatchToProps 內每個 action 創建函數使用 dispatch 進行包裹后返回
  const actionFun = bindactioncreators(mapDispatchToProps, this.store.dispatch);
  this.setState({...filterState, ...actionFun});
 }
 render(){
  return <Component {...this.state} />
 }
 }
}

五、redux API applyMiddleware 的實現

到此簡化版的 react-redux 算是已經初步完成,但是假如我們想要我們的 age 值的增長是一個異步操作,比如:通過按鈕點擊后經過兩秒再修改 age ,而不是一點擊按鈕就立即修改值;這樣我們又該怎么實現呢?

當然我們可以通過 setTimeout 兩秒后再執行 action 創建函數,比如這樣:

onClick = () => {
 setTimeout(()=>{
  // 兩秒后執行 action 創建函數
  this.props.changeAge();
 }, 2000);
}

但是呢事實上我們并不愿意像上面那么整,我們想要這么一種效果:我們只需要簡單的調用 action 創建函數即可實現異步操作,而不是需要進行額外的操作;這時我們就需要為我們的 react-redux 編寫一個中間件來實現這么一個效果;

5.1 準備工作

新增action 創建函數

  在這之前我們所有的 acton 創建函數都是直接返回一個 action 對象,下面我們寫一個不一樣的 action 創建函數, 它返回的不再是一個 action 對象而是一個函數,并且該函數接收兩個參數 dispatch 以及 getState, 在該函數內部我們進行相應的異步操作,比如:修改 age 值;

// actionCreate.js
export const asyncChangeAge = () => {
 // 返回函數
 return (dispatch, getState) => {
 setTimeout(v=>{
  console.log('==>', getState());
  dispatch({type: 'AGE_GROW'});
 }, 1000);
 }
}
修改頁面:新增按鈕并綁定點擊事件,并且調用 asyncChangeAge 函數;
// Demo.jsx
// Demo.jsx
import React from 'react';
import './style.css';
// 導入 asyncChangeAge
import { changeAge, changeUser, asyncChangeAge } from './actionCreate';
import { connect } from './react-redux';

const mapStateToProps = (state) => {
 return {user: state.user, age: state.age};
}

// 添加 asyncChangeAge
@connect(mapStateToProps, {changeAge, changeUser, asyncChangeAge})
export default class Demo extends React.Component{
 onChange = (e) => {
 this.props.changeUser(e.target.value);
 }
 onClick = () => {
  this.props.changeAge();
 }
 // 點擊事件
 onClickAsync = () => {
 this.props.asyncChangeAge();
 }
 render(){
 return (
  <div>
  <p>user: {this.props.user}, age: {this.props.age}</p>
  user: 
  <input type="text" className="input" onChange={this.onChange}/>
  &nbsp;
  <button className="btn" onClick={this.onClick}>年齡增長</button>
  {/* 新增按鈕 */}
  <button className="btn" onClick={this.onClickAsync}>
   異步增長
  </button>
  </div>
 );
 }
}
頁面的變化其實很簡單就是新增了一個按鈕:

redux以及react-redux的示例分析

5.2 需求實現

接下來我們先什么都不考慮先來實現我們的需求,現在 action 創建函數 asyncChangeAge 因為返回的是一個對象,其 type 值為 undefined 所以當我們點擊按鈕時 reducer 將會一直匹配到默認情況,返回的將是當前的狀態,接下來我們先讓我們的 action 創建函數 asyncChangeAge 生效,達到異步修改狀態的作用;

擴展 createStore

既然 asyncChangeAge 返回的不再是一個 action 對象,而是一個函數;那么其實我們要做的事情是很簡單的,我們只需要針對 createStore 中的返回值 dispatch 進行一個簡單的擴展即可;通過判斷 dispatch 中的 action 參數是否是函數而進行不同的操作:

// redux.js
export const createStore = (reducer) => {
 ......
 // 在createStore 我們對返回值 dispatch 進行了封裝
 const dispatchExtend = (action) => {
 if(typeof action === 'function'){
  // action 為函數,執行函數
  action(dispatch, getState);
 } else {
  // action 為非函數(對象)調用dispatch
  dispatch(action);
 }
 }
 return {getState, dispatch: dispatchExtend, subscribe};
}

5.3 抽離封裝

上文我們通過對 createStore 的返回值 dispatch 進行了擴展,實現了 redux-react 的異步操作,但問題是我們將代碼寫死在 createStore 中了,redux-react 的異步操作應該是一個可選項而不應該是必選項;

重新擴展 createStore :

新增參數 middleware (函數), 在函數 createStore 開始位置判斷 middleware 是否存在,存在則執行;

// redux.js
export const createStore = (reducer, middleware) => {
 // 判斷 middleware 是否存在,存在則執行
 if(middleware){
 return middleware(createStore)(reducer);
 }

 let state;
 const listeners = [];

 const getState = () => {
 return state;
 }

 const dispatch = (action) => {
 state = reducer(state, action);
 listeners.forEach(v => v());
 }

 const subscribe = (listener) => {
 listeners.push(listener);
 }

 dispatch({type: '%$&HJKAJJHDJHJ'});

 return {getState, dispatch, subscribe};
}
編寫函數 applyMiddleware ,在創建 store 時 作為 createStore 第二參數
// App.js
const applyMiddleware = (createStore) => (redux)=> {
 // 在這里進行創建 store
 const store = createStore(redux);
 // 返回store
 return {...store}
}

const store = createStore(reducer, applyMiddleware);
在 applyMiddleware 函數內擴展 dispatch

上文 applyMiddleware 函數并其實沒做任何事情, 只是在 createStore 函數外面套了一層函數,那么接下來我們做點正事,來擴展一下我們的 dispatch

// App.js
const applyMiddleware = (createStore) => (redux)=> {
 const store = createStore(redux);

 const midApi = {
 getState: store.getState,
 dispatch: (...args) => {dispatch(...args);}
 };

 const dispatch = (action) => {
 if( typeof action === 'function' ){
  action(midApi.dispatch, midApi.getState);
 } else {
  store.dispatch(action);
 }
 }

 return {
 ...store,
 dispatch
 };
}

5.4 擴展分離

上文已經實現了我們想要的效果了,我們在 applyMiddleware 對 dispatch 進行了擴展;然而我們是那么容易滿足的嘛,當然不是的!! applyMiddleware 中對 dispatch 的擴展我們還可以將其單獨提出來封裝成一個函數;

重寫 applyMiddleware ,再給 applyMiddleware 包裹一層函數: 將對 dispatch 的擴展抽離,封裝成方法;
// App.js
const applyMiddleware = (middleware) => (createStore) => (redux)=> {
 const store = createStore(redux);

 const midApi = {
 getState: store.getState,
 dispatch: (...args) => {dispatch(...args);}
 };

 const dispatch = middleware(midApi)(store.dispatch);

 return {
 ...store,
 dispatch
 };
}
thunk 中間件: 其實 thunk 才是真正的中間件;applyMiddleware 只是用來綁定中間件的
// App.js 
const thunk = ({dispatch, getState}) => next => (action) => {
 if(typeof action === 'function'){
 action(dispatch, getState);
 } else {
 next(action);
 }
};
在調用 createStore 時綁定中間件 thunk
// App.jsx
const store = createStore(reducer, applyMiddleware(thunk));

5.5 代碼整理

這一步只是將 applyMiddleware 函數移到 redux.js 文件中;同時將 thunk 函數寫到文件 thunk.jsx 中,然后在 App.js 中引用 applyMiddleware 以及 thunk 而已;

看下最終效果(效果和上一個錄屏是一樣樣的)

redux以及react-redux的示例分析

感謝各位的閱讀!關于“redux以及react-redux的示例分析”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

仁怀市| 滕州市| 宜阳县| 天长市| 松桃| 茶陵县| 株洲市| 松阳县| 和政县| 拉孜县| 鸡东县| 会理县| 明溪县| 光山县| 长寿区| 哈巴河县| 辽源市| 涟源市| 白玉县| 织金县| 南木林县| 怀柔区| 怀仁县| 博野县| 黑山县| 阿合奇县| 三原县| 康定县| 汝南县| 嫩江县| 左云县| 离岛区| 唐河县| 吉林市| 谢通门县| 灵宝市| 恭城| 安仁县| 维西| 长丰县| 岑溪市|