久久伊人一区二区三区四区-久久伊人影视-久久伊人影院-久久伊人中文字幕-亚洲成在人色婷婷-亚洲大成色www永久网

千鋒教育-做有情懷、有良心、有品質(zhì)的職業(yè)教育機(jī)構(gòu)

手機(jī)站
千鋒教育

千鋒學(xué)習(xí)站 | 隨時(shí)隨地免費(fèi)學(xué)

千鋒教育

掃一掃進(jìn)入千鋒手機(jī)站

領(lǐng)取全套視頻
千鋒教育

關(guān)注千鋒學(xué)習(xí)站小程序
隨時(shí)隨地免費(fèi)學(xué)習(xí)課程

當(dāng)前位置:首頁  >  技術(shù)干貨  > React自動(dòng)化路由

React自動(dòng)化路由

來源:千鋒教育
發(fā)布人:wjy
時(shí)間: 2022-06-01 17:18:00 1654075080

在使用`react-router-dom`在編寫項(xiàng)目的時(shí)候有種感覺就是,使用起來非常的方便,但是若是維護(hù)起來,那便是比較麻煩了,因?yàn)楦鞔舐酚煞稚⒃诟鱾€(gè)組件中. 所以我們就會(huì)想到,使用`react-router-dom`中提供的`config`模式來編寫我們的路由,這樣寫的好處就是我們可以將邏輯集中在一處,配置路由比較方便

React自動(dòng)化路由

## **項(xiàng)目地址**

[https://gitee.com/d718781500/autoRouter](https://link.zhihu.com/?target=https%3A//gitee.com/d718781500/autoRouter)

## **1.路由集中式**

我們先將下列數(shù)據(jù)定義在`/src/router/index.js`中

在react的路由官方文檔中就提供了配置集中式路由的案例,大致是這樣的仿照`vue`的路由,生成一個(gè)配置文件,預(yù)期是這樣的

```js
//需要一個(gè)路由的配置,它是一個(gè)數(shù)組
import Discover from "../pages/Discover"
import Djradio from "../pages/Discover/Djradio"
import Playlist from "../pages/Discover/Playlist"
import Toplist from "../pages/Discover/Toplist"
import Friends from "../pages/Friends"
import Mine from "../pages/Mine"
import Page404 from "../pages/Page404"
const routes = [
    {
        path: "/friends",
        component: Friends
    },
    {
        path: "/mine",
        component: Mine
    },
   
    {
        path: "/discover",
        component: Discover,
        children: [
            {
                path: "/discover/djradio",
                component: Djradio
            },
            {
                path: "/discover/playlist",
                component: Playlist

            },
            {
                path: "/discover/toplist",
                component: Toplist
            }
        ]
    },
    {//Page404這個(gè)配置一定要在所有路由配置之后
        path: "*",
        component: Page404
    }
]

export default routes
```

我們可以通過上述配置,來生成一個(gè)路由.當(dāng)然上述的配置也只是做了簡單的處理,還有`redirect` `exact`等屬性沒有寫,我們還是從一個(gè)簡單的開始吧

## **2.文件目錄**

上述的配置中使用了類似于vue的集中式路由配置模式,那么下面就展示下我當(dāng)前這個(gè)demo的結(jié)構(gòu)目錄吧

### **項(xiàng)目目錄結(jié)構(gòu)**

### **src/pages目錄結(jié)構(gòu)**

```js
├─Discover
│  │  abc.js
│  │  index.js
│  │
│  ├─Djradio
│  │  │  index.js
│  │  │  lf.js
│  │  │
│  │  └─gv
│  │          index.js
│  │
│  ├─Playlist
│  │      index.js
│  │
│  └─Toplist
│          index.js

├─Entertaiment
│      index.js

├─Friends
│      index.js
│      xb.js

├─Mine
│      index.js

└─Page404
        index.js
```

有了這些結(jié)構(gòu)之后,那么在`1`中提到的引入文件結(jié)合起來看就不懵逼啦,接下來我們可以封裝一個(gè)組件,給他取個(gè)名字叫做`CompileRouter`這個(gè)組件專門用于編譯路由

## **3.創(chuàng)建CompileRouter**

這個(gè)組件我們把它創(chuàng)建在`src/utils`中,作用就是通過傳入的路由配置,然后計(jì)算出這個(gè)組件,那么問題來了,為什么要?jiǎng)?chuàng)建這個(gè)組件呢?

讓我們回顧一下react路由的編寫方式吧,react路由需要一個(gè)基礎(chǔ)組件`HashRouter`或者`BrowserRouter`這兩個(gè)相當(dāng)于一個(gè)基石組件

然后還需要一個(gè)路由配方這個(gè)組件可以接受一個(gè)`path`映射一個(gè)`component`

我們來寫段偽代碼來說明一下

```js
//引入路由基本組件(要在項(xiàng)目中安裝 npm i react-router-dom)
import {HashRouter as Router,Route} from "react-router-dom"
class Demo extends React.Component {
    render(){
        //基石路由
        <Router>
            //路由配方組件 通過path匹配component
            <Route path="/" component={Home}/>
             <Route path="/mine" component={Mine}/>
        </Router>
    }
}
```

這是基本用法,所以我們CompileRouter這個(gè)組件的工作就是,生成如上代碼中的Route一樣,生成Route然后展示在組件上

在了解到Compile的基本作用之后,下面我們就開始編碼吧

我個(gè)`CompileRouter`設(shè)計(jì)是接受一個(gè)數(shù)據(jù),這個(gè)數(shù)據(jù)必須是符合路由配置的一個(gè)數(shù)組,就像`1`里代碼中所示的數(shù)組一樣,接受的屬性為`routes`

```js
//這個(gè)文件通過routes配置來編譯出路由
import React from 'react'
import { Switch, Route } from "react-router-dom";
export default class CompileRouter extends React.Component {
    constructor() {
        super()
        this.state = {
            c: []
        }
    }
    renderRoute() {
        let { routes } = this.props;//獲取routes路由配置
        //1.通過routes生成Route組件
        //確保routes是一個(gè)數(shù)組
        // console.log(routes)
        //render 不會(huì)重復(fù)讓組件的componentDidMount和componentWillUnmount重復(fù)調(diào)用
        if (Array.isArray(routes) && routes.length > 0) {
            //確保傳入的routes是個(gè)數(shù)組
           // 循環(huán)迭代傳入的routes
            let finalRoutes = routes.map(route => {
                //每個(gè)route是這個(gè)樣子的 {path:"xxx",component:"xxx"}
                //如果route有子節(jié)點(diǎn) {path:"xxx",component:"xxx",children:[{path:"xxx"}]}
                return <Route path={route.path} key={route.path} render={
                       // 這么寫的作用就是,如果路由還有嵌套路由,那么我們可以把route中的children中的配置數(shù)據(jù)傳遞給這個(gè)組件,讓組件再次調(diào)用CompileRouter的時(shí)候就能編譯出嵌套路由了
                    () => <route.component routes={route.children} />
                } />
            })

            this.setState({
                c: finalRoutes
            })
        } else {
            throw new Error('routes必須是一個(gè)數(shù)組,并且長度要大于0')
        }
    }
    componentDidMount() {
        //確保首次調(diào)用renderRoute計(jì)算出Route組件
        this.renderRoute()
    }
    render() {
        let { c } = this.state;
        return (
            <Switch>
                {c}
            </Switch>
        )
    }
}
```

上述代碼就是用于去處理`routes`數(shù)據(jù)并且聲稱這樣的組件,每一步的作用我都已經(jīng)在上面用注釋標(biāo)明了

 

## **4.使用CompileRouter**

其實(shí)我們可以把封裝的這個(gè)組件當(dāng)成是`vue-router`中的視圖組件`<router-view/>`就暫且先這么認(rèn)為吧,接下來我們需要在頁面上渲染`1級(jí)路由了`

在`src/app.js`

```js
import React from 'react'
import { HashRouter as Router, Link } from 'react-router-dom'
//引入我們封裝的CompileRouter罪案
import CompileRouter from "./utils/compileRouter"
//引入在1中定義的路由配置數(shù)據(jù)
import routes from "./router"
console.log(routes)
class App extends React.Component {
    render() {
        return (
            <Router>
                <Link to="/friends">朋友</Link>
                |
                <Link to="/discover">發(fā)現(xiàn)</Link>
                |
                <Link to="/mine">我的</Link>
                {/*當(dāng)成是vue-router的視圖組件 我們需要將路由配置數(shù)據(jù)傳入*/}
                <CompileRouter routes={routes} />
            </Router>
        )
    }
}

export default App
```

寫完后,那么頁面上其實(shí)就可以完美的展示1級(jí)路由了

## **5.嵌套路由處理**

上面我們已經(jīng)對(duì)1級(jí)路由進(jìn)行了渲染,可以跳轉(zhuǎn),但是二級(jí)路由怎么處理呢?其實(shí)也很簡單,我們只需要找到二級(jí)路由的父路由,繼續(xù)使用`CompileRouter`就可以了

我們從配置中可以看到,`Discover`這個(gè)路由是具有嵌套路由的,所以我們就以`Discover`路由為例子,首先我們看下結(jié)構(gòu)圖

![img](https://pic4.zhimg.com/80/v2-99aebf28aca62fa66c48587f6897068b_720w.jpg)

圖上的`index.js`就是`Discover`這個(gè)視圖組件了,也是嵌套路由的`父級(jí)路由`,所以我們只需要在這個(gè)`index.js`中繼續(xù)使用`CompileRouter`就可以了

```js
import React from 'react'
import { Link } from "react-router-dom"

import CompileRouter from "../../utils/compileRouter"
function Discover(props) {

    let { routes } = props //這個(gè)數(shù)據(jù)是從ComileRouter組件編譯的時(shí)候傳遞過來的children
    // console.log(routes)
    let links = routes.map(route => {
        return (
            <li key={route.path}>
                <Link to={route.path}>{route.path}</Link>
            </li>
        )
    })
    return (
        <fieldset>
            <legend>發(fā)現(xiàn)</legend>
            <h1>我發(fā)現(xiàn),不能說多喝熱水</h1>
            <ul>
                {links}
            </ul>
            {/*核心代碼,再次使用即可 這里將通過children數(shù)據(jù)可以渲染出Route*/}
            <CompileRouter routes={routes} />
        </fieldset>
    )
}
Discover.meta = {
    title: "發(fā)現(xiàn)",
    icon: ""
}
export default Discover
```

所以我們以后記住,只要是有嵌套路由我們要做兩件事

1. 配置routes
2. 在嵌套路由的父級(jí)路由中再次使用`CompileRouter`,并且傳入`routes`即可

## **6.** **require.context**

上面我們實(shí)現(xiàn)了一個(gè)路由集中式的配置,但是我們會(huì)發(fā)現(xiàn)一個(gè)問題

![img](https://pic3.zhimg.com/80/v2-93403806cb935bd4dbeb50a6e770f66e_720w.jpg)

引入了很多的組件,實(shí)際上,在項(xiàng)目中引入的更多,如果一個(gè)一個(gè)引入,對(duì)我們來說是災(zāi)難性的,所以我們可以使用`webpack`提供的一個(gè)很好用的api,`require.context`我們先說說它是怎么使用的吧

自動(dòng)化導(dǎo)入`require.context`方法,使用這個(gè)方法可以減少繁瑣的組件引入,而且可以深度的遞歸目錄,做到import做不到的事情 下面我們來看一下這個(gè)方法是如何使用的

### **使用**

你可以通過 `require.context()` 函數(shù)來創(chuàng)建自己的 context。

可以給這個(gè)函數(shù)傳入4個(gè)參數(shù):

1. 一個(gè)要搜索的目錄,
2. 一個(gè)標(biāo)記表示是否還要搜索其子目錄,
3. 一個(gè)匹配文件的正則表達(dá)式。
4. mode 模塊加載模式,常用值為 sync、lazy、lazy-once、eager

- `sync` 直接打包到當(dāng)前文件,同步加載并執(zhí)行
  `lazy` 延遲加載會(huì)分離出單獨(dú)的 chunk 文件
  `lazy-once` 延遲加載會(huì)分離出單獨(dú)的 chunk 文件,加載過下次再加載直接讀取內(nèi)存里的代碼。
  `eager` 不會(huì)分離出單獨(dú)的 chunk 文件,但是會(huì)返回 promise,只有調(diào)用了 promise 才會(huì)執(zhí)行代碼,可以理解為先加載了代碼,但是我們可以控制延遲執(zhí)行這部分代碼。

webpack 會(huì)在構(gòu)建中解析代碼中的 `require.context()` 。

語法如下:

```js
require.context(
  directory,
  (useSubdirectories = true),
  (regExp = /^\.\/.*$/),
  (mode = 'sync')
);
```

示例:

```js
require.context('./test', false, /\.test\.js$/);
//(創(chuàng)建出)一個(gè) context,其中文件來自 test 目錄,request 以 `.test.js` 結(jié)尾。
require.context('../', true, /\.stories\.js$/);
// (創(chuàng)建出)一個(gè) context,其中所有文件都來自父文件夾及其所有子級(jí)文件夾,request 以 `.stories.js` 結(jié)尾。
```

### **api**

函數(shù)有三個(gè)屬性:`resolve`, `keys`, `id`。

- `resolve` 是一個(gè)函數(shù),它返回 request 被解析后得到的模塊 id。
- let p = require.context("...",true,"xxx")
  p.resolve("一個(gè)路徑")
- `keys` 也是一個(gè)函數(shù),它返回一個(gè)數(shù)組,由所有可能被此 context module 處理的請(qǐng)求(譯者注:參考下面第二段代碼中的 key)組成。

`require.context`的返回值是一個(gè)函數(shù),我們可以在函數(shù)中傳入文件的路徑,就可以得到模塊化的組件了

```js
let components = require.context('../pages', true, /\.js$/, 'sync')

let paths = components.keys()//獲得了所有引入文件的地址
// console.log(paths)
let routes = paths.map(path => {
    let component = components(path).default
    path = path.substr(1).replace(/\/\w+\.js$/,"")
    return {
        path,
        component
    }
})
console.log(routes)
```

### **總結(jié)**

雖然上面有很多api和返回的值,我們只拿兩個(gè)來做說明

1. keys方法,這個(gè)可以獲取所有模塊的路徑,返回的是一個(gè)數(shù)組
   let context = require.context("../pages", true, /\.js$/);

   let paths = context.keys()*//獲取了所有文件的路徑*

2. 獲取路徑下所有的模塊
   let context = require.context("../pages", true, /\.js$/);

   let paths = context.keys()*//獲取了所有文件的路徑*

   let routes = paths.map(path => {
   *//批量獲取引入的組件*
   let component = context(path).default;
   console.log(component)
   })

掌握這兩個(gè)就可以了,下面我們來繼續(xù)處理

## **7.扁平數(shù)據(jù)轉(zhuǎn)換為樹形結(jié)構(gòu)的(convertTree算法)**

這個(gè)算法的名字是我自己起的,首先我們要明白為甚么需要將數(shù)據(jù)轉(zhuǎn)換成tree

我們的預(yù)期的`routes`數(shù)據(jù)應(yīng)該是下面這樣的

```js
//目的是什么?
//生成一個(gè)路由配置
 const routes = [
     {
         path: "",
         component:xxx
          children:[
                 {
                     path:"xxx"
                     component:xxx
                 }
            ]
     }
 ]
```

但其實(shí)我們使用`require.context`處理之后的數(shù)據(jù)是這樣的

![img](https://pic1.zhimg.com/80/v2-7562f0762bc6f1e97c9c7b7e128ef618_720w.jpg)

可以看到這個(gè)數(shù)據(jù)是完全`扁平化`的,沒有任何的嵌套,所以我們第一步就是要實(shí)現(xiàn)將這種扁平化的數(shù)據(jù)轉(zhuǎn)換為符合我們預(yù)期的`樹形`結(jié)構(gòu),下面我們一步一步來

### **7.1使用require.context將數(shù)據(jù)處理成扁平化**

首先要處理成上圖那樣的結(jié)構(gòu),代碼都有注釋,難度也不高

```js
//require.context()

// 1. 一個(gè)要搜索的目錄,
// 2. 一個(gè)標(biāo)記表示是否還要搜索其子目錄,
// 3. 一個(gè)匹配文件的正則表達(dá)式。
let context = require.context("../pages", true, /\.js$/);

let paths = context.keys()//獲取了所有文件的路徑


let routes = paths.map(path => {
    //批量獲取引入的組件
    let component = context(path).default;
    //組件擴(kuò)展屬性方便渲染菜單
    let meta = component['meta'] || {}
    //console.log(path)
    //這個(gè)正則的目的
    //因?yàn)榈刂肥?/Discover/Djradio/index.js這種類型的并不能直接使用,所以要進(jìn)行處理
    //1.接去掉最前的"." 得到的結(jié)果是/Discover/Djradio/index.js
    //2.處理了還是不能直接用 因?yàn)槲覀兊念A(yù)期/Discover/Djradio,所以通過正則將index.js干掉了
    //3.有可能后面的路徑不是文件夾 得到的結(jié)果是/Discover/abc.js,后綴名并不能用到路由配置的path屬性中,所以.js后綴名又用正則替換掉
    path = path.substr(1).replace(/(\/index\.js|\.js)$/, "")
    // console.log(path)
    return {
        path,
        component,
        meta
    }
})
```

### **7.2** **實(shí)現(xiàn)convertTree算法**

上面處理好了數(shù)據(jù)后,我們封裝一個(gè)方法,專門用于處理扁平化數(shù)據(jù)變成樹形數(shù)據(jù),算法`時(shí)間復(fù)雜度為O(n^2)`

```js
function convertTree(routes) {
    let treeArr = [];
    //1.處理數(shù)據(jù) 將每條數(shù)據(jù)的id和parent處理好 (俗稱 爸爸去哪兒了)
    routes.forEach(route => {
        let comparePaths = route.path.substr(1).split("/")
        // console.log(comparePaths)
        if (comparePaths.length === 1) {
            //說明是根節(jié)點(diǎn),根節(jié)點(diǎn)不需要添加parent_id
            route.id = comparePaths.join("")
        } else {
            //說明具有父節(jié)點(diǎn)
            //先處理自己的id
            route.id = comparePaths.join("");
            //comparePaths除去最后一項(xiàng)就是parent_id
            comparePaths.pop()
            route.parent_id = comparePaths.join("")
        }
    })
    //2.所有的數(shù)據(jù)都已經(jīng)找到了父節(jié)點(diǎn)的id,下面才是真正的找父節(jié)點(diǎn)了
    routes.forEach(route => {
        //判斷當(dāng)前的route有沒有parent_id
        if (route.parent_id) {
            //有父節(jié)點(diǎn)
            //id===parent_id的那個(gè)route就是當(dāng)前route的父節(jié)點(diǎn)
            let target = routes.find(v => v.id === route.parent_id);
            //判斷父節(jié)點(diǎn)有沒有children這個(gè)屬性
            if (!target.children) {
                target.children = []
            }
            target.children.push(route)
        } else {
            treeArr.push(route)
        }
    })

    return treeArr
}
```

通過上述處理之后就可以得到樹形結(jié)構(gòu)啦

![img](https://pic3.zhimg.com/80/v2-74337231c1b570e8532025dd75a56aaa_720w.jpg)

接下來我們只需要把數(shù)據(jù)導(dǎo)出去,在app上引入傳遞給`CompileRouter`組件就可以了

### **7.3** **以后要注意的**

以后只需要在pages中創(chuàng)建文件即可自動(dòng)實(shí)現(xiàn)路由的處理以及編譯了,不過對(duì)于嵌套級(jí)別的路由咱們別忘了要在路由組件加上CompileRouter組件,總結(jié)為亮點(diǎn)

1. 創(chuàng)建路由頁面
2. 嵌套路由的父級(jí)路由組件中加入

## **8.擴(kuò)展靜態(tài)屬性**

我們當(dāng)前創(chuàng)建出來的效果是有了,但是如果我們用于渲染`菜單`的時(shí)候就會(huì)有問題,沒有內(nèi)容可以用于渲染菜單,所以我們可以給組件上擴(kuò)展`靜態(tài)屬性meta(也可以是別的)`,然后對(duì)我們的自動(dòng)化編譯代碼做一些小小的改動(dòng)就行了

### **組件**

### **自動(dòng)化處理邏輯完整代碼**

```js
//require.context()

// 1. 一個(gè)要搜索的目錄,
// 2. 一個(gè)標(biāo)記表示是否還要搜索其子目錄,
// 3. 一個(gè)匹配文件的正則表達(dá)式。
let context = require.context("../pages", true, /\.js$/);

let paths = context.keys()//獲取了所有文件的路徑


let routes = paths.map(path => {
    //批量獲取引入的組件
    let component = context(path).default;
    //組件擴(kuò)展屬性方便渲染菜單
    let meta = component['meta'] || {}
    //console.log(path)
    //這個(gè)正則的目的
    //因?yàn)榈刂肥?/Discover/Djradio/index.js這種類型的并不能直接使用,所以要進(jìn)行處理
    //1.接去掉最前的"." 得到的結(jié)果是/Discover/Djradio/index.js
    //2.處理了還是不能直接用 因?yàn)槲覀兊念A(yù)期/Discover/Djradio,所以通過正則將index.js干掉了
    //3.有可能后面的路徑不是文件夾 得到的結(jié)果是/Discover/abc.js,后綴名并不能用到路由配置的path屬性中,所以.js后綴名又用正則替換掉
    path = path.substr(1).replace(/(\/index\.js|\.js)$/, "")
    // console.log(path)
    return {
        path,
        component,
        meta
    }
})
//這種數(shù)據(jù)是扁平化的數(shù)據(jù),并不符合我們的路由規(guī)則
//需要做算法 盡可能將時(shí)間復(fù)雜度降低o(n)最好
//封裝一個(gè)convertTree算法 時(shí)間復(fù)雜度o(n^2)
// console.log(routes)

//id
//parent_id

function convertTree(routes) {
    let treeArr = [];
    //1.處理數(shù)據(jù) 將每條數(shù)據(jù)的id和parent處理好 (俗稱 爸爸去哪兒了)
    routes.forEach(route => {
        let comparePaths = route.path.substr(1).split("/")
        // console.log(comparePaths)
        if (comparePaths.length === 1) {
            //說明是根節(jié)點(diǎn),根節(jié)點(diǎn)不需要添加parent_id
            route.id = comparePaths.join("")
        } else {
            //說明具有父節(jié)點(diǎn)
            //先處理自己的id
            route.id = comparePaths.join("");
            //comparePaths除去最后一項(xiàng)就是parent_id
            comparePaths.pop()
            route.parent_id = comparePaths.join("")
        }
    })
    //2.所有的數(shù)據(jù)都已經(jīng)找到了父節(jié)點(diǎn)的id,下面才是真正的找父節(jié)點(diǎn)了
    routes.forEach(route => {
        //判斷當(dāng)前的route有沒有parent_id
        if (route.parent_id) {
            //有父節(jié)點(diǎn)
            //id===parent_id的那個(gè)route就是當(dāng)前route的父節(jié)點(diǎn)
            let target = routes.find(v => v.id === route.parent_id);
            //判斷父節(jié)點(diǎn)有沒有children這個(gè)屬性
            if (!target.children) {
                target.children = []
            }
            target.children.push(route)
        } else {
            treeArr.push(route)
        }
    })

    return treeArr
}

export default convertTree(routes)


//獲取一個(gè)模塊
// console.log(p("./Discover/index.js").default)

//目的是什么?
//生成一個(gè)路由配置
// const routes = [
//     {
//         path: "",
//         component,
//          children:[
//                 {path component}
//             ]
//     }
// ]
```

## **寫在最后**

其實(shí)上述的處理并不能作為`應(yīng)用級(jí)別`用于項(xiàng)目中,主要在于`CompileRouter`處理的不夠細(xì)致,下一期我將專門寫一篇如何處理`CompileRouter`用于`鑒權(quán)`等應(yīng)用在項(xiàng)目中

**-** **End** **-**

更多關(guān)于“html5培訓(xùn)”的問題,歡迎咨詢千鋒教育在線名師。千鋒已有十余年的培訓(xùn)經(jīng)驗(yàn),課程大綱更科學(xué)更專業(yè),有針對(duì)零基礎(chǔ)的就業(yè)班,有針對(duì)想提升技術(shù)的提升班,高品質(zhì)課程助理你實(shí)現(xiàn)夢想。

tags:
聲明:本站稿件版權(quán)均屬千鋒教育所有,未經(jīng)許可不得擅自轉(zhuǎn)載。
10年以上業(yè)內(nèi)強(qiáng)師集結(jié),手把手帶你蛻變精英
請(qǐng)您保持通訊暢通,專屬學(xué)習(xí)老師24小時(shí)內(nèi)將與您1V1溝通
免費(fèi)領(lǐng)取
今日已有369人領(lǐng)取成功
劉同學(xué) 138****2860 剛剛成功領(lǐng)取
王同學(xué) 131****2015 剛剛成功領(lǐng)取
張同學(xué) 133****4652 剛剛成功領(lǐng)取
李同學(xué) 135****8607 剛剛成功領(lǐng)取
楊同學(xué) 132****5667 剛剛成功領(lǐng)取
岳同學(xué) 134****6652 剛剛成功領(lǐng)取
梁同學(xué) 157****2950 剛剛成功領(lǐng)取
劉同學(xué) 189****1015 剛剛成功領(lǐng)取
張同學(xué) 155****4678 剛剛成功領(lǐng)取
鄒同學(xué) 139****2907 剛剛成功領(lǐng)取
董同學(xué) 138****2867 剛剛成功領(lǐng)取
周同學(xué) 136****3602 剛剛成功領(lǐng)取
相關(guān)推薦HOT
抖音小店運(yùn)營做什么的

在當(dāng)前的電商市場中,抖音小店已經(jīng)逐漸成為一種新的電商模式,它集成了社交化、音視頻分享、直播銷售等多種功能,使得消費(fèi)者更加便捷地進(jìn)行商品...詳情>>

2023-10-08 16:36:41
抖音小店照片要求尺寸多大

在抖音平臺(tái)開設(shè)小店已經(jīng)成為了越來越多人的選擇,相信大家已經(jīng)在各大社交平臺(tái)上看到有不少小店的推廣。在抖音上,照片是展示產(chǎn)品的重要手段,因...詳情>>

2023-10-08 16:14:25
抖音招商團(tuán)長托管服務(wù)費(fèi)怎么退回來

抖音招商團(tuán)長托管服務(wù)是抖音為有意愿創(chuàng)作內(nèi)容并帶動(dòng)其他創(chuàng)作者成為團(tuán)隊(duì)成員的用戶提供的一種服務(wù)。通過該服務(wù),招商團(tuán)長可以自主組建團(tuán)隊(duì)并得到...詳情>>

2023-10-08 16:08:53
抖音小店怎么做代銷

抖音已經(jīng)成為了一個(gè)非常受歡迎的短視頻應(yīng)用程序,在其中許多用戶都精心打造了自己的小店,用于銷售各種各樣的商品,獲取額外的收入。然而,要想...詳情>>

2023-10-08 15:28:41
怎樣開抖音小店帶貨賺錢

隨著直播帶貨的火熱,越來越多的人開始嘗試通過抖音小店來開展帶貨業(yè)務(wù)。抖音小店是抖音直播帶貨的配套,可以讓用戶在購買直播中產(chǎn)品時(shí)就實(shí)現(xiàn)購...詳情>>

2023-10-08 15:06:36
主站蜘蛛池模板: 无码人妻av一区二区三区毛片 | 男人一边吃奶一边弄下边好爽| 暗交小拗女一区二区| 国产精品亚洲精品日韩动图| 公车上玩弄白嫩少妇| 差差差不多视频30分钟轮滑| 色婷婷粉嫩AV精品综合在线 | 日韩AV高清无码| 全部免费A级毛片| 国产成人久久AV免费高潮| 成人做受120视频试看| 午马视频影院1区2区3区4区| 久久精品第一国产久精国产宅男6| 亚洲无人区码一码二码三码的含义| 亚洲AV无码一区二区高潮| 欧美黑人一区二区| 亚洲AV人无码激艳猛片服务器| 久久精品日日躁夜夜躁欧美| 免费下载破解看片APP的软件| 纯爱无遮挡H肉动漫| 国产成人精品午夜福利| 人人爽人人模人人人爽人人爱| 丰满少妇人妻HD高清大乳| 后入内射国产一区二区| 老阿姨哔哩哔哩B站肉片茄子芒果| 无码熟妇人妻AV在线影片免费| 成年黄网站18禁免费观看一区| 国产精品久久一区二区三区| 国产精品VA无码免费| 嗯~啊哈好深好骚啊哼| 亚洲乱妇老熟女爽到高潮的片| А√天堂资源地址在线下载| 小SB是不是想被C了| 日本丰满熟妇BBXBBXHD| 欧美精品色婷婷五月综合| 久久成人无码专区| 亚洲精品无码专区| 精品人妻无码专区中文字幕| 丰满妇女强高潮18ⅩXXX在线| 成熟丰满熟妇高潮XXXXX| 亚洲日本一本DVD高清| 蜜臀AV无码一区二区三区| 国产精品JIZZ在线观看无码| 亚洲无AV码一区二区三区| 女厕脱裤撒尿大全视频| 亚洲综合国产一区二区三区| 第九理论午夜电影院| 天天综合网网欲色| 在线 | 一区二区三区| 久久AⅤ人妻少妇嫩草影院| 亚洲AV永久无码精品古装片| 草草最新发地布地址①· | 无码专区人妻系列日韩| 国产精品久久久久久无遮挡| 欧美性猛交内射兽交老熟妇| 午夜夫妻试看120国产| 无码人妻AⅤ一区二区三区夏目| 公车上玩弄白嫩少妇| 国产精品亚洲А∨无码播放麻豆| 人妻 中文无码 中出| 久久久久国色AV免费观看性色| 无码AV在线一区二区| 色婷婷综合中文久久一本| 人人妻人人澡人人爽不卡视频| 无套内谢的新婚少妇国语播放| 亚洲AV无码国产在丝袜线观看| 亚洲国产精品嫩草影院久久| 欧妇女乱妇女乱视频| 欧美极品在线观看| 一区二区AV在线| 嫩小BBB揉BBB揉BBBB| 色婷婷五月综合亚洲影院| 精品人妻一区二区三区四区九九| 拔萝卜日本视频在线观看免费| 日韩无码2021| 岳丰满多毛的大隂户| 好男人好资源电影在线播放| 亚洲AV无码一区二区二三区我| 国产一区二区三区久久精品| 三上悠亚被弄到痉挛惨叫AV| 涨乳催乳改造调教公主| 久久精品囯产精品亚洲| 哦┅┅快┅┅用力啊┅警花少妇 | 丰满人妻一区二区三区视频53 | 亚洲AV午夜福利精品一区二区| 男友把舌头都伸进我的嘴巴里了| 天美传媒在线观看果冻传媒视频| 波多野结衣AV高清一区二区三区| 精品亚洲国产成人AV制服| 人曾交互MOUSE农场| 人喾交性专区免费看| 女人无遮挡无内衣内裤网站| 欧美人与性囗牲恔配| 国产在线无码精品电影网| 久久久久久精品免费免费R | 国产成人一区二区三区APP| 欧美亚洲一区二区三区 | 强被迫伦姧在线观看中文版| 日本熟少妇裸交ⅩXX视频| 女人扒开的小泬高潮喷水小说| 日本熟妇人妻XXXXX野外呻| 久久久久久人妻精品一区| 纯肉无遮挡H肉动漫在线观看3D | 欧美男生射精高潮视频网站| 欧美精品亚洲精品日韩传电影| 欧洲精品99毛片免费高清观看| 国产妇女馒头高清泬20P多| 丰满大屁股BWWBWWBWW| 亚洲AV无码乱码国产精品| 久久高清内射无套| 亚洲AV永久无码精品古装片 | 日本高清WWW色视频| 女人爽到高潮的免费视频| 国产精品成人VA在线观看| 欧美激情视频一区| 永久免费精品精品永久-夜色| 欧洲熟妇色XXXXⅩ欧美老妇天| 亚洲AV无码专区国产乱码4| 国产精品无码久久AV不卡| 女的把腿张开男的往里面插| 色综合AV综合无码综合网站| 又粗又黄又爽视频免费看| 成 人 A V免费视频在线观看| 成人爽A毛片免费| 亚洲无AV码一区二区三区| 亚洲综合国产一区二区三区| 无码口爆内射颜射后入| 婷婷五月综合色视频| 国产男男GAY做受XXX| 亚洲AV无码一区二区三区网站 | 国产又色又爽又黄的网站在线| 一本色道久久HEZYO无码| 天堂SV在线最新版在线| 在线精品国产一区二区三区| 少妇WWB搡BBBB搡BBBB| 在线看AV的网站| 啊哈~给我~啊(H)| 绯色AV一区二区三区在线高清| 陈冠希实干阿娇13分钟| 婷婷伊人久久大香线蕉AV| 国产精品亚洲专区无码破解版 | 亚洲AV永久无码精品无码影片 | 极品少妇的粉嫩小泬看片| 成在线人免费无码高潮喷水| 天美传媒剧国产MV在线看| 国产成人三级在线视频网站观看| 无码G0G0大胆啪啪艺术| 无码专区人妻系列日韩| 丰满爆乳在线播放| 超清无码熟妇人妻AV在线电影| 少妇特黄Av一区二区三区| 粉嫩AV一二三区免费| 高清拍拍拍无挡国产精品| 国产女人喷潮视频在线观看| 国产成人牲交在线观看视频 | 一受多攻同做H嗯啊巨肉| 成年动作片AV免费网站| 中国东北熟女老太婆内谢| 亚洲人女屁股眼HD| 人人爽人人模人人人爽人人爱| 一面膜上边一面膜下边视频| 久拍国产在线观看| 高清FREESEXMOVIES性TV出水| 成人无号精品一区二区三区| 无码人妻AⅤ一区二区三区夏目 | 亚洲AV无码专区国产乱码不卡| 亚洲 欧美 激情 小说 另类 | 少妇厨房愉情理伦片BD在线观看| 窝窝人体色WWW聚色窝| 国产性夜夜春夜夜爽| 有人有在线观看的片资源| 无码人妻精品一区二区在线视频 | 欧美私人家庭影院| 男男暴菊GAY无套网站| 成人无码H在线观看网站| 脱色摇床THERMO网站| 丰满妇女强高潮18ⅩXXX在线| 天干夜天干天天爽自慰| 抖抈短视频APP下载| 粉嫩AV一二三区免费| 国产熟女一区二区| 国产成人亚洲综合网站| 国产成人精品无码片区在线观看| 少妇特殊按摩高潮爽翻天| 小SB是不是想被C了| 日本毛多水多做受视频| 女人扒下裤让男人桶到爽| 老阿姨哔哩哔哩B站肉片茄子芒果| 亚洲国产精品久久久久爰色欲| 国产寡妇XXXX猛交| 在线观看韩国电影| 久久久久久人妻精品一区二区三区 | 上面一边亲下一边面膜使用方法| 丰满人妻被公侵犯日本| 少妇午夜AV一区| 少妇厨房愉情理伦片BD在线观看| 漂亮人妻被中出中文字幕| 国产精品亚洲片夜色在线| 亚洲综合成人婷婷五月网址| 精品国产一区二区AV片| 日韩AV影院在线观看| YELLOW在线观看| 精品国产AⅤ一区二区三区V视界 | 我是你可爱的小猫| 国产交换配乱婬视频| 特大黑人巨交吊性XXXX| 丰满大屁股熟女偷拍内射| 亲孑伦视频一区二区三区一| 在线成人A毛片免费播放| 欧美人与性口牲恔配视频| 中文字幕人妻互换AV久久| 国产午夜精品免费一区二区三区| 色综合精品无码一区二区三区 | 欧美变态另类ZOZO| 熟妇人妻AV无码一区二区三区| 国产成人亚洲精品无码H| 国产乱人伦偷精品视频免| 哦┅┅快┅┅用力啊┅┅村妇| 日韩精品一区二区三区影院| 日本一区二区在线播放| 欧美大屁股XXXX高跟欧美黑人| 欧美XXXXX高潮喷水麻豆| 女人扒开屁股桶爽6O分钟| 国产成人涩涩涩视频在线观看| 黑人巨大JEEP日本人| 国产成人亚洲精品青草天美| 专干日本熟妇人妻| 日韩A级成人免费无码视频| 啪啪男女爱高潮GIF| 黑人上司粗大拔不出来电影| 丰满少妇人妻XXXXX| 欧美性色黄大片WWW喷水| 高清一区二区三区日本久| 无码熟妇人妻AⅤ在线影片| 久久久久久精品国产亚洲AV麻豆 | 国产成人午夜在线视频A站| 亚洲一线产区和二线产区的区别| 久久久久久人妻精品一区二区三区 | 特大黑人巨交吊性XXXX| 国产精品亚洲片在线| 久久夜色撩人精品国产小说| 小SB是不是想被C了| 亚洲伊人成无码综合影院| 国产极品粉嫩馒头一线天AV| 内射后入在线观看一区| 亚欧洲精品在线视频免费观看 | 久久精品国产亚洲AV高清色欲 | 高潮喷吹一区二区在线观看| 人妻少妇久久中文字幕| 全球AV集中精品导航福利| 无码毛片内射白浆视频| 奇米影视7777久久精品| 琪琪777午夜理论片在线观看播| 无码AV在线一区二区| 久久国产精品无码网站| 老阿姨哔哩哔哩B站肉片茄子芒果| 女人被狂躁高潮啊的视频在线看 | 外国操逼全黄视频| 嫩BBB槡BBBB搡BBBB| 国产精品午夜福利不卡| 西西人体444WWW高清大胆| 久久久久久久99精品国产片| 成 人 免费 黄 色 网站视频| 亚洲AV之男人的天堂| 久久夜色精品国产噜噜麻豆| 成年女人午夜毛片免费视频| 日本高清在线视频WWW色| 国产精品白浆无码流出视频| 视频视频APP在线看| 国产精品无码久久综合网| 色婷婷日日躁夜夜躁| 丰满妇女强高潮18ⅩXXX在线| 外国操逼全黄视频| 亚洲大尺度无码专区尤物| 解开人妻的裙子猛烈进入| 忘忧草影视WWW在线播放网| 妇女AV中文精品字幕XXX| 教官在我腿间疯狂驰聘视频| 人人妻人人澡人人爽超污| 亚洲AV无码专区国产乱码4| 国产精品美女久久久| 极品少妇的粉嫩小泬看片| 久久国产精品无码网站| 嗯…啊 摸 湿 奶头免费视频| 国产激情无码一区二区APP| 久久成人国产精品| 精品日本一区二区三区免费| 精二和精三的区别| 亚洲最大AV网站在线观看| 真人作爱试看90分钟免费影视| 触及真心在线观看| 亚洲AV无码专区亚洲猫咪| 人善交VIDEOS欧美3D| 久久久久久精品免费免费自慰| 国内精品久久影院综合日日| 性少妇VIDEOXXX欧美69| 蜜芽AV在线新地址| WWW国产无套内射COM| 欧美黑人一区二区| 色狠狠一区二区三区香蕉| 丰满少妇AAAAAA爰片毛片| 色欲网久久久久久久久久久久久久 | 亚洲精品无码专区在线播放| 青草青草视频2免费观看 | 国产精品亚洲片在线| 日韩精品无码区免费专区| 国产精品国产三级国产AⅤ| 无码丰满人妻熟妇区| 中文无码一区二区不卡ΑV| 久久久久久久99精品国产片| 欧美性猛交乱大交3| 清纯校花自慰呻吟流白浆| 亚洲精品成人A在线观看 | 在线成本人国语视频动漫| 国产精品久久久久国产A级| 男人的天堂在线视频| 欧美大胆A级视频免费| 欧洲精品不卡1卡2卡三卡| 欧美黑人一级爽快片婬片高清| 日韩中文无码有码免费视频| 日本免费人成视频在线观看| 女人被男人爽到呻吟的视频| 久久99精品久久久久久HB无码| 久久精品无码一区二区日韩AV | 天天做天天忝天天噜| 无码人妻精一区二区三区老牛| 我半夜摸妺妺的奶摸到高潮| 女的把腿张开男的往里面插| 丰满的少妇愉情HD高清免费| 无码人妻精品一区二区三区不卡| 无套内谢的新婚少妇国语播放 | 色婷婷久久综合中文久久蜜桃AV| 女人扒开屁股桶爽30分钟| 国产精品日本亚洲欧美| 亚洲AV无码无在线观看红杏| 韩国19禁床震无遮掩免费| 他将头埋进双腿间吮小核故事| 牛牛本精品99久久精品66| 香蕉免费一区二区三区在| 国语第一次处破女| 久久久久久精品免费免费WEⅠ| 岳潮湿的大肥梅开二度第三部最新| 日本高清视频色WWWWWW色| 夜色毛片永久免费| А√天堂BT中文在线| 放在里面边顶边吃饭H| 国产成人三级在线视频网站观看 | 一面亲上边一面膜的免费| 嫩草在线视频WWW免费看| 欧美乱码卡1卡2卡三卡四卡| 人妻无码熟妇乱又视频| 人妻少妇精品无码专区APP | 久久国产精品无码HDAV| 欧美性猛交一区二区| 久久亚洲SM情趣捆绑调教| 国产精品成人永久在线四虎| 国产丰满老熟女重口对白| 亚洲精品成人AV在线| 久久国产欧美日韩精品| 国产成人欧美精品视频| 性饥渴少妇AV无码毛片| 免费A级毛片在线播放不收费| 国产精品秘入口18禁麻豆免会员| 丰满的少妇XXXXX人妻| 屠户家的小娇花哒哒啦爱你| 极品少妇被猛得白浆直流草莓| 成人免费A级毛片久久| 日本55丰满熟妇厨房伦| 房东天天吃我奶躁我| 久久精品国产一区二区三区肥胖| 久久精品熟女亚州AV麻豆| 婷婷成人丁香五月综合激情 | 国产精品99久久久久| 色哟哟精品网站在线观看| 草草最新发地布地址①· | 成人精品视频一区二区| 日本最新免费二区三区| 亚洲AV无码一区二区高潮| 宝贝对着镜子CAO好不好| 国产亚洲午夜高清国产拍精品| 四川丰满少妇被弄到高潮| 亚洲人女屁股眼HD| 侵犯美人妻中出中文字幕| 无码YY4800亚洲私人影院| 人人爽人人操人人精品| 色综合精品无码一区二区三区 | 小SAO货都湿掉奶头好硬男女| 国产精品99久久久久久WWW| 国产蜜臀AV无码一区二区三区| 国内精品九九久久精品| 国产成人欧美精品视频| 无码一区在线视频| 国精一二二产品无人区免费应用| 肉大捧一进一出免费视频| 蜜臀98精品国产免费观看| 久久精品无码一区二区日韩AV | 日本护士毛茸茸XX| 国精产品砖一区二区三区糖心| 成人精品一区二区久久久| 亚洲国产精品久久久久秋霞影院| 亲情会王芳高敏大团圆| 又大又粗又爽A级毛片免费看| 色视频WWW在线播放国产人成| 国产福利一区二区久久| 无码毛片内射白浆视频| 成人精品动漫一区二区| 国产精品99久久久久久WWW| 久久九九精品国产AV片国产| 秋霞免费理论片在线观看| 无套内谢的新婚少妇国语播放|