国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

「每日一瞥

qujian / 1153人閱讀

摘要:當(dāng)引擎開始執(zhí)行腳本是的時候,會先創(chuàng)建一個全局執(zhí)行上下文,并將其到當(dāng)前執(zhí)行棧,無論何時一個函數(shù)被調(diào)用,就會創(chuàng)建一個新的函數(shù)執(zhí)行上下文并壓入棧中。當(dāng)函數(shù)執(zhí)行完畢,執(zhí)行棧會將其彈出,并把控制權(quán)交給當(dāng)前棧的下一個上下文。

從過去直到 React.lazy

寫一個沒有 JSX 的 React

執(zhí)行上下文和執(zhí)行棧

公私有域和方法

數(shù)組在性能方面的一個注意點(diǎn)

從過去直到 React.lazy code-splitting

當(dāng)我們最最開始做前端開發(fā)的時候,JavaScript 文件自然就一個個羅列在一起,通過 script 標(biāo)簽引入到 html 里。當(dāng)然,即使在現(xiàn)在,我們也還是會在寫一些 Demo 時使用這樣的方式。

如今,我們有了如 Webpack、Parcel 等 Module bundler 來為我們更好的組織 JavaScript 文件。我們可以使用各種模塊系統(tǒng)如 CommonJS(requiremodule.exports)或者 ES Modules(importexport)來定義文件之間的依賴。

然而,隨著我們的應(yīng)用越來越大,我們就會得到一個巨大的 JS bundle,而這種慢慢等待加載的體驗(yàn)是絕不能忍受的。因此,code-splitting 就成了一種廣泛接受的做法。

下面的例子就是沒有拆分過的、只會打包成一份的應(yīng)用,在加載時會同步全部加載再渲染:

import Description from "./Description";

function App() {
  return (
    

My Movie

); }

現(xiàn)在我們來開始看看,如何讓我們的 Module bundler 來懶加載我們的模塊呢?

Dynamic import proposal

動態(tài) import 提案為 ES Modules 添加了新特性,使我們可以以異步的方式定義我們的依賴關(guān)系。import 語句可以作為一個函數(shù)來調(diào)用,并返回一個 Promise,這個 Promise 會 resolve 我們想要加載的模塊。使用方式只需要從上面的 ES Modules 的 import 方式略加調(diào)整:

- import Description from "./Description";

+ const Description = import("./Description");

上面的用法就會告訴 Webpack 或 Parcel 我們的 Description 模塊并不是立即就需要,而是可以等到加載好后再使用。并且,動態(tài) import 就可以使得 Module bundler 將該模塊打包成多帶帶的 js 文件,而這就是所謂的 code-split。

但是還不夠,這還只是開始。讓我們繼續(xù)往下走。

React 組件的懶加載

如果我們使用上述動態(tài) import,我們的 App 組件就要修改成如下的方式:

const LoadDescription = () => import("./Description");

class App extends React.Component {
  state = {
    Description: null,
  };

  componentDidMount() {
    LoadDescription.then(Description => {
      this.setState({ Description: Description.default });
    });
  }

  render() {
    const { Description } = this.state;
    return (
      

My Movie

{Description ? : "Loading..."}
); } }

這樣寫未免就有點(diǎn)蛋疼了,所幸的是我們有一個非常好用的庫,即 react-loadable:

react-loadable 會幫我們省掉很多模板代碼,改寫后的效果如下:

import Loadable from "react-loadable";

const LoadableDescription = Loadable({
  loader: () => import("./Description"),
  loading() {
    return 
Loading...
; }, }); function App() { return (

My Movie

); }

這樣看上去就好多了,我們就不需要再自己去管生命周期之類的事,只需要靠它來 load 我們需要的組件、指定相應(yīng)的 loading 即可使用。

既然 react-loadable 已經(jīng)這么好用了,我們還干嘛要用 React.lazy 呢?

Suspense

react-loadable 實(shí)際上還是有一些不足的,主要的一點(diǎn)就是它只作用于每一個多帶帶組件。什么意思呢?如果你有一堆想要懶加載的組件,你需要分別為他們指定 loading 狀態(tài)。當(dāng)然,你可以使用一個公用的組件,這樣你每個 loading 狀態(tài)都可以復(fù)用,但是你仍然會看到每一個懶加載的組件各自有一個 loading。如果你在一個頁面有很多懶加載的組件,那就牛逼了,你會看到一堆小菊花,這恐怕也不是什么好的體驗(yàn)。

說到這一缺點(diǎn),在我們團(tuán)隊(duì)的一些項(xiàng)目中,CLI 目前是在路由層面配合使用 react-router 和 react-loadable 的,一次只會 load 一個組件,因而就不存在一堆要懶加載的組件同時出現(xiàn)在頁面上;而 loading 狀態(tài),我們也可以設(shè)計(jì)一個全局的 Spin 來使用。總的來說,肯定是存在一些方法或替代方案來彌補(bǔ)或避免這些問題的。

但是,在我們目前的工程中,仍然有可以改善的點(diǎn):

一堆 loadable 文件;

react-loadable 有除懶加載以外功能的其他代碼,這些可能是我們不需要的;

如果我們想對更深層的子組件做懶加載,就還需要引入 loadable 文件,不優(yōu)雅。

好的,讓我們來看看 React.lazy 可以做到什么吧!

與 react-loadable 不同的是,我們不需要在每一個 React.lazy 處定義一個 loading 狀態(tài),我們要搭配使用 Suspense,在 Suspense 這里定義一個 loading 狀態(tài)。這就意味著,你可以有很多個 React.lazy 組件,但你只需要給對應(yīng)的 Suspense 指定一個 loading 狀態(tài)就可以了

此外,我們可以在任意深的地方放入一個 React.lazy 組件,Suspense 會統(tǒng)一的、干干凈凈的處理好懶加載的任務(wù)。

那么我們要怎樣使用 React.lazy 來改寫上面的代碼呢?如下所示:

import React, { Suspense } from "react";
const Description = React.lazy(() => import("./Description"));

function App() {
  return (
    

My Movie

); }

Suspense 就像是 try-catch 一樣,會「捕獲」到 React.lazy 實(shí)例,然后會進(jìn)入同一個 fallback 組件。也就是說,下面的例子中,我們只會渲染同一個 fallback:

import React, { Suspense } from "react";
const Description = React.lazy(() => import("./Description"));

function App() {
  return (
    

My Movie

Cast
); } // AnotherLazyComponent.js (imagine in another file) const AndYetAnotherLazyComponent = React.lazy(() => import("./AndYetAnotherLazyComponent") ); function AnotherLazyComponent() { return (
So...so..lazy..
); }

如果我們想更自由的指定不同的懶加載組件的不同 loading 狀態(tài),只需要像下面一樣嵌套 Suspense 即可:

function App() {
  return (
    

My Movie

Cast
); }

厲害的是,如果 AnotherLazyComponent 很久都沒有加載完,沒關(guān)系,他不會影響到其他組件的渲染。React.lazy 和 Suspense 會把 AnotherLazyComponent 和他的子組件們隔離開來,避免它加載的延遲影響到其他內(nèi)容的渲染。

這樣一來,與前面沒有另一個 Suspense 的寫法相比,后者就不會等待所有懶加載組件都加載好后才能呈現(xiàn),而是逐個呈現(xiàn)各個組件,這就有些像是 Promise.all 和各自異步的感覺。

最后

是不是可以準(zhǔn)備改造一下項(xiàng)目了呢?

源地址:https://hswolff.com/blog/reac...

參考:https://reactjs.org/docs/code...

寫一個沒有 JSX 的 React

習(xí)慣了 JSX 的寫法,今天來感受下沒有 JSX 的 React 的酸爽。

我們知道,通常我們在使用 React 時所寫的 JSX,都會被 Babel 編譯成一些方法,一個很有名的方法就是 React.createElement。

React.createElement 方法需要三個參數(shù):

type: HTML 元素或組件的類型(例如: h1、h2、p、button 等等);

props: 傳入的屬性對象;

children: 任何可以穿入的夾在元素中的東西。

簡單的例子

那么我們把最基本的 React 去掉 JSX 來寫,就有下面的代碼:

let welcome = React.createElement("h1",{style:{color:"red"}},`Welcome to react world`);

ReactDOM.render(welcome,document.querySelector("#root"));

上面的代碼就是純 React,當(dāng)然,ReactDOM.render 方法還是一樣的。

我們調(diào)整下上面的代碼,組織成一個組件:

class Welcome extends React.Component{
  render(){
    return React.createElement("h1",{style:{color:"red"}},
            `Welcome to ${this.props.name}`);
  }
}

ReactDOM.render(React.createElement(Welcome,
                {name:"Homepage"},null),document.querySelector("#root"));

我們在 React.createElement 方法傳入了第二個參數(shù) {name:"Homepage"},因此在 Welcome 類內(nèi)部,就可以通過 this.props.name 訪問到這個傳入的屬性。

counter 例子
const  el =  React.createElement;

function Button(props){
  return el("button", { onClick: props.handleClick }, props.name);
}

class Counter extends React.Component{
  state= {
       num: 0,
  }

  handleIncrement = () =>{
    this.setState({
      num: this.state.num + 1,
    });
  }

  handleDecrement = () =>{
    this.setState({
      num: this.state.num - 1,
    });
  }

  render(){
    return el("div",null,
             el(Button, { handleClick: this.handleIncrement, name:"Increment" }, null),
             el(Button,{ handleClick: this.handleDecrement, name:"Decrement" }, null),
             el("p", null, this.state.num),
    }
}

ReactDOM.render(el(Counter,null,null),document.querySelector("#root"))

可以看到,沒有 JSX,我們的 render 方法變得復(fù)雜了很多。上面代碼的效果如下圖所示:

我們再回來看看 JSX 的寫法:

function Button(props) {
  return 
}

class Counter extends React.Component {
  state = {
    num: 0
  }
  handleIncrement = () => {
    this.setState({
      num: this.state.num + 1
    })
  }
  handleDecrement = () => {
    this.setState({
      num: this.state.num - 1
    })
  }
  render() {
    return (
      

{this.state.num}

) } } ReactDOM.render(, document.querySelector("#root"))

JSX 的可讀性原來還算好的了。

源地址:https://codeburst.io/how-to-u...

執(zhí)行上下文和執(zhí)行棧 什么是執(zhí)行上下文

這可能是很多書本上都會講的基礎(chǔ)知識,這里我們也帶一遍。執(zhí)行上下文就是 JavaScript 代碼求值和執(zhí)行的環(huán)境。不管跑什么代碼,都是跑在一個執(zhí)行上下文里。

執(zhí)行上下文有 3 種:

全局上下文
程序里只會有一個。

函數(shù)上下文
函數(shù)上下文可以有人以多個,只要一個新的函數(shù)被調(diào)用,就會創(chuàng)建一個函數(shù)上下文,而且他們會按照一種定義好的順序逐個執(zhí)行。

Eval 上下文
這個咱們還是不多講了,危險。

執(zhí)行棧

其實(shí)也就是調(diào)用棧。當(dāng) JavaScript 引擎開始執(zhí)行腳本是的時候,會先創(chuàng)建一個全局執(zhí)行上下文,并將其 push 到當(dāng)前執(zhí)行棧,無論何時一個函數(shù)被調(diào)用,就會創(chuàng)建一個新的(函數(shù))執(zhí)行上下文并壓入棧中。

引擎會執(zhí)行那些在棧頂?shù)膱?zhí)行上下文。當(dāng)函數(shù)執(zhí)行完畢,執(zhí)行棧會將其彈出,并把控制權(quán)交給當(dāng)前棧的下一個上下文。

舉個例子:

let a = "Hello World!";
function first() {
  console.log("Inside first function");
  second();
  console.log("Again inside first function");
}
function second() {
  console.log("Inside second function");
}
first();
console.log("Inside Global Execution Context");

以一個圖來展示就是:

怎么個執(zhí)行真的不需要多說了。我們還是接著講點(diǎn)不知道的吧。

執(zhí)行上下文是怎么被創(chuàng)建的?

上面的內(nèi)容告訴我們 JavaScript 引擎是怎么管理執(zhí)行上下文的,現(xiàn)在我們來講下上下文是怎么被創(chuàng)建的。

執(zhí)行上下文的創(chuàng)建總共分兩步:

創(chuàng)建階段

執(zhí)行階段

創(chuàng)建階段

執(zhí)行上下文其實(shí)就是在創(chuàng)建階段被創(chuàng)建的。在創(chuàng)建階段,我們會有兩種環(huán)境被創(chuàng)建:

LexicalEnvironment,我們叫作詞匯環(huán)境

VariableEnvironment,我們叫作變量環(huán)境

所以,執(zhí)行上下文可以從概念上標(biāo)識如下:

ExecutionContext = {
  LexicalEnvironment = ,
  VariableEnvironment = ,
}
詞匯環(huán)境

官方 ES6 是這么定義詞匯環(huán)境的:

詞匯環(huán)境是一種規(guī)范類型,用于根據(jù) ECMAScript 代碼的詞法嵌套結(jié)構(gòu)定義標(biāo)識符與特定變量和函數(shù)的關(guān)聯(lián)。詞匯環(huán)境由環(huán)境記錄和的可能為 null 引用的外部詞匯環(huán)境組成。

簡單來說,詞匯環(huán)境就是一種維護(hù)標(biāo)識符到變量的映射,這里標(biāo)識符指變量或函數(shù)的名字,而變量指的是一個實(shí)際對象(包括函數(shù)對象、數(shù)組對象)或基本值的引用。

每個詞匯環(huán)境由三部分組成:

環(huán)境記錄

外部環(huán)境引用

this binding

我們還需要再繼續(xù)展開講:

環(huán)境記錄

環(huán)境記錄,就是變量和函數(shù)聲明存儲在詞法環(huán)境中的位置。有兩種環(huán)境記錄:

聲明式環(huán)境記錄

對象環(huán)境記錄

前者主要就是存放變量、函數(shù)這類聲明了的,后者則是對全局的代碼進(jìn)行記錄,例如全局綁定的 window。

注意,對于函數(shù),環(huán)境記錄還會包含 arguments 對象,用于映射傳入函數(shù)的參數(shù)和記錄傳入?yún)?shù)的個數(shù)。我們舉個例子就很明白了:

function foo(a, b) {
  var c = a + b;
}
foo(2, 3);
// argument object
Arguments: {0: 2, 1: 3, length: 2},

外部環(huán)境引用

對外部環(huán)境的引用意味著它可以訪問其外部詞匯環(huán)境。這意味著如果在當(dāng)前詞匯環(huán)境中找不到它們,JavaScript 引擎可以在外部環(huán)境中查找變量。

this binding

這一部分就是講 this 是怎么設(shè)置的。

在全局執(zhí)行上下文,this 指向全局對象,比如瀏覽器環(huán)境下就是 window。

【基礎(chǔ)知識】在函數(shù)執(zhí)行上下文里,this 就取決于函數(shù)調(diào)用的方式。如果是通過對象引用,那么 this 就是這個對象,不然的話,this 就會是全局對象或者 undefined (嚴(yán)格模式下)。舉個例子:

const person = {
  name: "peter",
  birthYear: 1994,
  calcAge: function() {
    console.log(2018 - this.birthYear);
  }
}
person.calcAge(); 
// "this" refers to "person", because "calcAge" was called with //"person" object reference
const calculateAge = person.calcAge;
calculateAge();
// "this" refers to the global window object, because no object reference was given

綜上:詞匯環(huán)境的偽代碼如下:

GlobalExectionContext = {
  LexicalEnvironment: {
    EnvironmentRecord: {
      Type: "Object",
      // Identifier bindings go here
    }
    outer: ,
    this: 
  }
}
FunctionExectionContext = {
  LexicalEnvironment: {
    EnvironmentRecord: {
      Type: "Declarative",
      // Identifier bindings go here
    }
    outer: ,
    this: 
  }
}
變量環(huán)境

它也是一個詞法環(huán)境,因此它具有上面定義的詞法環(huán)境的所有內(nèi)容。唯一的不同是,在 ES6 中,詞法環(huán)境和變量環(huán)境這兩個,前者用于存儲函數(shù)聲明和變量(let 和 const)綁定,而后者僅用于存儲變量(var)綁定。

執(zhí)行階段

在這個階段,變量賦值都結(jié)束了,代碼也最終被執(zhí)行掉。

舉個例子:

let a = 20;
const b = 30;
var c;
function multiply(e, f) {
 var g = 20;
 return e * f * g;
}
c = multiply(20, 30);

執(zhí)行上述代碼時,JavaScript 引擎會創(chuàng)建一個全局執(zhí)行上下文來執(zhí)行全局代碼。因此,在創(chuàng)建階段,全局執(zhí)行上下文將如下所示:

GlobalExectionContext = {
  LexicalEnvironment: {
    EnvironmentRecord: {
      Type: "Object",
      // Identifier bindings go here
      a: < uninitialized >,
      b: < uninitialized >,
      multiply: < func >
    }
    outer: ,
    ThisBinding: 
  },
  VariableEnvironment: {
    EnvironmentRecord: {
      Type: "Object",
      // Identifier bindings go here
      c: undefined,
    }
    outer: ,
    ThisBinding: 
  }
}

在執(zhí)行階段,完成變量賦值。因此,在執(zhí)行階段,全局執(zhí)行上下文將看起來像這樣:

GlobalExectionContext = {
  LexicalEnvironment: {
    EnvironmentRecord: {
      Type: "Object",
      // Identifier bindings go here
      a: 20,
      b: 30,
      multiply: < func >
    }
    outer: ,
    ThisBinding: 
  },
  VariableEnvironment: {
    EnvironmentRecord: {
      Type: "Object",
      // Identifier bindings go here
      c: undefined,
    }
    outer: ,
    ThisBinding: 
  }
}

當(dāng)遇到函數(shù) multiply(20,30) 被調(diào)用時,會創(chuàng)建一個新的函數(shù)執(zhí)行上下文來執(zhí)行函數(shù)代碼。因此,在創(chuàng)建階段函數(shù)執(zhí)行上下文將如下所示:

FunctionExectionContext = {
  LexicalEnvironment: {
    EnvironmentRecord: {
      Type: "Declarative",
      // Identifier bindings go here
      Arguments: {0: 20, 1: 30, length: 2},
    },
    outer: ,
    ThisBinding: ,
  },
  VariableEnvironment: {
    EnvironmentRecord: {
      Type: "Declarative",
      // Identifier bindings go here
      g: undefined
    },
    outer: ,
    ThisBinding: 
  }
}

在此之后,執(zhí)行上下文將走完執(zhí)行階段,這意味著完成了對函數(shù)內(nèi)部變量的賦值。因此,在執(zhí)行階段函數(shù)執(zhí)行上下文將如下所示:

FunctionExectionContext = {
  LexicalEnvironment: {
    EnvironmentRecord: {
      Type: "Declarative",
      // Identifier bindings go here
      Arguments: {0: 20, 1: 30, length: 2},
    },
    outer: ,
    ThisBinding: ,
  },
  VariableEnvironment: {
    EnvironmentRecord: {
      Type: "Declarative",
      // Identifier bindings go here
      g: 20
    },
    outer: ,
    ThisBinding: 
  }
}

函數(shù)完成后,返回的值存儲在 c 中。因此全局詞匯環(huán)境得到了更新。之后,全局代碼完成,程序結(jié)束。

注意!你可能發(fā)現(xiàn)一個有意思的東西,就是在創(chuàng)建階段,let 和 const 定義的變量是「未初始化」?fàn)顟B(tài),而 var 定義的則是 undefined。

這是因?yàn)椋诙x階段,代碼會掃描變量和函數(shù)聲明,函數(shù)聲明會在環(huán)境中被完整存著,對 var 定義的就會被初始化成 undefined,而 let 和 const 定義的就成了未初始化狀態(tài)。

這就是為什么,我們?nèi)绻?var 定義的變量定義之前使用它,會得到 undefined,但在 let 或 const 定義的變量定義之前使用會報 error。

這就是我們所說的提升

Javascript Hoisting:In javascript, every variable declaration is hoisted to the top of its declaration context.

另一個點(diǎn)則是,如果在執(zhí)行階段,JavaScript 引擎找不到 let 變量實(shí)際的值,他就會被賦值為 undefined。

源地址:https://blog.bitsrc.io/unders...

公私有域和方法

這篇文章主要介紹 V8 v7.2 和 Chrome 72 新的 class fields 語法,以及即將出現(xiàn)的 private class fields。

我們來創(chuàng)建一個 IncreasingCounter 實(shí)例:

const counter = new IncreasingCounter();
counter.value;
// logs "Getting the current value!"
// → 0
counter.increment();
counter.value;
// logs "Getting the current value!"
// → 1
ES2015 class

如果使用 ES2015 class 語法,我們應(yīng)該會這么實(shí)現(xiàn) IncreasingCounter:

class IncreasingCounter {
  constructor() {
    this._count = 0;
  }
  get value() {
    console.log("Getting the current value!");
    return this._count;
  }
  increment() {
    this._count++;
  }
}

該類在原型上添上了一個 value getter 和 increment 方法。類有一個構(gòu)造函數(shù),它創(chuàng)建一個實(shí)例屬性 _count,并將其默認(rèn)值設(shè)置為0。我們目前傾向于使用下劃線前綴來表示 _count 不應(yīng)該由該類的使用者直接使用,但這只是一個約定;它不是真正的「私有」屬性,只是有這個特殊語義而已。

const counter = new IncreasingCounter();
counter.value;
// logs "Getting the current value!"
// → 0

// Nothing stops people from reading or messing with the
// `_count` instance property.            
               
                                           
                       
                 

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/100756.html

相關(guān)文章

  • 每日一瞥

    摘要:目前前端主要有以下四種方法會觸發(fā)對應(yīng)的回調(diào)方法方法客戶端回調(diào)客戶端回調(diào)參考地址每日一瞥是團(tuán)隊(duì)內(nèi)部日常業(yè)界動態(tài)提煉,發(fā)布時效可能略有延后。 showImg(https://segmentfault.com/img/remote/1460000017975436?w=1200&h=630); 「ES2015 - ES2018」Rest / Spread Properties 梳理 Thr...

    xiangzhihong 評論0 收藏0
  • 每日一瞥

    摘要:另一部分就是類型的屬性,也就是返回的屬性。,一開始提案為,其作用就是遞歸的將數(shù)組展平到指定深度,默認(rèn)深度為。目前在使用時,我們唯一的選擇是命令行界面。 showImg(https://segmentfault.com/img/remote/1460000017516912?w=1200&h=630); TypeScript 3.3 更新梳理 Object.assign vs Obje...

    劉明 評論0 收藏0
  • 每日 30 秒 ? 大家一起被捕吧

    showImg(https://segmentfault.com/img/remote/1460000018793640?w=900&h=500); 簡介 安全、注入攻擊、XSS 13歲女學(xué)生被捕:因發(fā)布 JavaScript 無限循環(huán)代碼。 這條新聞是來自 2019年3月10日 很多同學(xué)匆匆一瞥便滑動屏幕去看下一條消息了,并沒有去了解這段代碼是什么,怎么辦才能防止這個問題。事情發(fā)生后為了抗議日本...

    lbool 評論0 收藏0
  • 每日一瞥

    摘要:首先,我們需要一個基本框架來處理表單域變化和表格提交。最起碼我們需要提供一個來告訴如果用戶還沒有對表單域進(jìn)行改動,就不必展示錯誤。我們需要一個來標(biāo)識用戶已嘗試提交表單,還需要來標(biāo)識表單是否正在提交以及每個表單域是否正在進(jìn)行異步校驗(yàn)。 showImg(https://segmentfault.com/img/remote/1460000017516912?w=1200&h=630); ...

    XboxYan 評論0 收藏0
  • Django靜態(tài)文件一瞥

    摘要:配置在設(shè)置項(xiàng)中確認(rèn)包含增加設(shè)置項(xiàng),值為一個字符串路徑,必須以結(jié)尾在模板中這樣引用在的目錄存放靜態(tài)文件開發(fā)期間使用極度低效時有別的做法注意默認(rèn)為,一個列表,表示獨(dú)立于的靜態(tài)文件存放位置。 配置 1.在INSTALLED_APPS設(shè)置項(xiàng)中確認(rèn)包含django.contrib.staticfiles 2.增加STATIC_URL設(shè)置項(xiàng),值為一個字符串(路徑),必須以‘/’結(jié)尾 3.在模板中...

    binta 評論0 收藏0

發(fā)表評論

0條評論

qujian

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<