完整版的Vue基礎學習

Vue 基礎學習

MVC、MVP、MVVM

MVC

img

  • View 傳送指令到 Controller
  • Controller 完成業務邏輯後,要求 Model 改變狀態
  • Model 將新的數據發送到 View,用戶得到反饋

不足之處:依賴太多

  • View 依賴Controller和Model
  • Controller依賴View和Model
  • Model 和View的關係雖然很弱, 但是也需要某種方式來通知View進行數據更新。

m層和v層直接打交道,導致這兩層還存在耦合的

因爲所有邏輯都寫在c層,導致c層特別臃腫

MVP

img

  • 各部分之間的通信,都是雙向的。
  • View 與 Model 不發生聯繫,都通過 Presenter 傳遞。即View只知道Presenter, 不知道Model 。
  • View 非常薄,不部署任何業務邏輯,稱爲"被動視圖"(Passive View),即沒有任何主動性,而 Presenter非常厚,所有邏輯都部署在那裏。

不足之處:

  • Presenter還是需要調用View的方法,也就是說Presenter對View有依賴,這樣Presenter就沒辦法單獨做單元測試,非得等到界面做好以後纔行。
  • 可以讓View層提取出接口,Presenter只依賴這個接口

p層代替了了c層,v層和m層的交互被p層隔斷,從理論上去除了v和m層的耦合

但是造成p層比原來的c層更加臃腫,爲了緩解這種臃腫,MVVM出現了

MVVM

img

  • 唯一的區別是,它採用雙向綁定(data-binding):View的變動,自動反映在 ViewModel,反之亦然。Angular 和 Ember 都採用這種模式。
  • 在MVP模式中:讓Presenter調用View的方法去設置界面,仍然需要大量的、煩人的代碼。所以ViewModel就誕生了,他是一個數據結構,而view可以根據這個數據結構的變化自動隨之變化

基礎指令

  • v-cloak{{value}}能夠解決 插值表達式的閃爍問題 不過需要在style裏設置樣式
    [v-cloak]{ display: none !important; }
  • v-text 沒有閃爍問題 v-text會覆蓋標籤裏的內容
  • v-html 會將元素當做HTML解析,上面兩個只會當做文本
  • v-bind 綁定屬性 縮寫 :
  • v-on 綁定事件 縮寫 @ 綁定的方法可以加括號方便傳參數
  • v-model實現數據的雙向綁定
  • .stop 阻止事件冒泡
  • .capture 使用捕獲機制
  • .self 只有點擊當前元素時才觸發事件
  • .prevent 去阻止默認行爲
  • .once 只觸發一次事件處理函數
  • v-for 遍歷對象 注意:除了有item key 之外還有索引i 如v-for="(item,key,i) in user 使用:key="item"指定綁定的key key需要具有唯一性(最好爲後臺數據庫傳過來json數據的id)(只能使用number 或者String
  • v-if 的特點是每次都會重新刪除或者創建元素 有較高的切換性能消耗 (頻繁的切換最好不用)
  • v-show 不會每次都操作DOM的創建和刪除,只是切換了元素的display:none;的樣式 有較高的初始渲染消耗

Vue實例中的屬性

  • el 表示要控制頁面的區域
  • data 表示data中存放的是el中用到的數據
  • methods 存放所需方法,主要處理業務邏輯
  • computed 計算屬性 主要當做屬性來使用,可在其中進行算數邏輯運算,存在緩存機制性能更高 以減輕模板重量 使程序便於維護
  • watch 監視 監視對象在data中 接收一個回調函數 函數參數ewValueoldValue,可以看做computedmethods的結合體

組件

1、組件化的特性:

高內聚性,組建功能必須是完整的,如我要實現下拉菜單功能,那在下拉菜單這個組件中,就把下拉菜單所需要的所有功能全部實現。
低耦合度,通俗點說,代碼獨立不會和項目中的其他代碼發生衝突。在實際工程中,我們經常會涉及到團隊協作,傳統按照業務線去編寫代碼的方式,就很容易相互衝突,所以運用組件化方式就可大大避免這種衝突的存在、每一個組件都有子集清晰的職責,完整的功能,較低的耦合便於單元測試和重複利用。

2、組件化的優點:

提高開發效率
方便重複使用
簡化調試步驟
提升整個項目的可維護性
便於協同開


Vue生命週期

Vue 实例生命周期

  • beforeCreate(創建前) 在數據觀測和初始化事件還未開始

  • created(創建後) 完成數據觀測,屬性和方法的運算,初始化事件,$el屬性還沒有顯示出來

  • beforeMount(載入前) 在掛載開始之前被調用,相關的render函數首次被調用。實例已完成以下的配置:編譯模板,把data裏面的數據和模板生成html。注意此時還沒有掛載html到頁面上。

  • mounted(載入後) 在el 被新創建的 vm.$el 替換,並掛載到實例上去之後調用。實例已完成以下的配置:用上面編譯好的html內容替換el屬性指向的DOM對象。完成模板中的html渲染到html頁面中。此過程中進行ajax交互。

  • beforeUpdate(更新前) 在數據更新之前調用,發生在虛擬DOM重新渲染和打補丁之前。可以在該鉤子中進一步地更改狀態,不會觸發附加的重渲染過程。

  • updated(更新後) 在由於數據更改導致的虛擬DOM重新渲染和打補丁之後調用。調用時,組件DOM已經更新,所以可以執行依賴於DOM的操作。然而在大多數情況下,應該避免在此期間更改狀態,因爲這可能會導致更新無限循環。該鉤子在服務器端渲染期間不被調用。

  • beforeDestroy(銷燬前) 在實例銷燬之前調用。實例仍然完全可用。

  • destroyed(銷燬後) 在實例銷燬之後調用。調用後,所有的事件監聽器會被移除,所有的子實例也會被銷燬。該鉤子在服務器端渲染期間不被調用。


Vue中的樣式綁定

1、class的對象綁定

 <style>
        .activated{
            color: red;
        }
 </style>
 <div id='app'>
        <div @click="handleDivClick" :class="{activated:isActivated}">
            Hello World
        </div>
 </div>
<script>
        var vm=new Vue({
            el:'#app',
            data:{
                isActivated:false
            },
            methods:{
                handleDivClick:function(){
                    this.isActivated=!this.isActivated;
                }
            }
        });
</script>

2、class的數組綁定

<style>
        .activated {
            color: red;
        }
        .activated-one{
            font-size: 25px;
        }
</style>
 <div id='app'>
        <div @click="handleDivClick" :class="[activated,activatedOne]">
            Hello World
        </div>
</div>
<script>
        var vm = new Vue({
            el: '#app',
            data: {
                activated: "",
                activatedOne:"activated-one"
            },
            methods: {
                handleDivClick: function () {
                    this.activated = this.activated === "activated" ? "" : "activated";
                }
            }
        });
</script>

3、style對象綁定

 <div id='app'>
        <div :style="styleObj" @click="handleDivClick">
            Hello World
        </div>
 </div>
<script>
        var vm = new Vue({
            el: '#app',
            data: { 
                styleObj:{
                    color:"black"
                }
            },
            methods: {
                handleDivClick:function(){
                    this.styleObj.color=this.styleObj.color==="black"?"red":"black";
                }
            }
        });
</script>

4、style數組綁定

<div id='app'>
        <!-- <div @click="handleDivClick" :class="[activated,activatedOne]">
            Hello World
        </div> -->
        <div :style="[styleObj,{fontSize:'25px'}]" @click="handleDivClick">
            Hello World
        </div>
 </div>
<script>
        var vm = new Vue({
            el: '#app',
            data: { 
                styleObj:{
                    color:"black"
                }
            },
            methods: {
                handleDivClick:function(){
                    this.styleObj.color=this.styleObj.color==="black"?"red":"black";
                }
            }
        });
</script>

深入理解Vue組件

組件細節

1、tbody、ul、select下只能存放特定的標籤
<body>
    <div id='app'>
        <table>
            <tbody>
                <row></row>
                <row></row>
                <row></row>
            </tbody>
        </table>
    </div>

    <script>
        Vue.component('row',{
            template:'<tr><td>this is row</td></tr>'
        })

        var vm=new Vue({
            el:'#app',
            data:{

            },
            methods:{

            }
        });
    </script>
</body>

上述代碼出現問題,tr出現在了在<table><tbody></tbody></table>外,因爲<tbody>裏只能放tr

在這裏插入圖片描述

改:

 <div id='app'>
        <table>
            <tbody>
                <tr is="row"></tr>
                <tr is="row"></tr>
                <tr is="row"></tr>
            </tbody>
        </table>
    </div>
2、子組件data爲function

因爲根組件一樣只會被調用一次,子組件會被多次調用,而子組件每個需要自己的數據,所以不能是一個對象,必須是一個方法返回一個對象

 Vue.component('row',{
            data:function(){
                return {
                    content:'this is content'
                }
            },
            template:'<tr><td>this is row</td></tr>'
        })
3、vue 操作DOM方式

vue不推薦操作DOM但有時候不得不去操作(複雜動畫)

標籤中

使用this.$refs.hello獲得DOM

<body>
    <div id='app'>
        <div ref='hello' @click="handleClick">
            Hello World
        </div>
    </div>

    <script>
        var vm=new Vue({
            el:'#app',
            data:{},
            methods:{
                handleClick:function(){
                    console.log(this.$refs.hello.innerHTML);
                }
            }
        });
    </script>
</body>
組件中

使用this.$refs.hello獲得組件的引用

<body>
    <div id='app'>
        <!-- <div ref='hello' @click="handleClick">
            Hello World
        </div> -->
        <counter @change="handleChange" ref="one"></counter>
        <counter @change="handleChange" ref="two"></counter>
        <div>{{total}}</div>
    </div>

    <script>
        Vue.component('counter',{
            data:function(){
                return{
                    number:0
                }
            },
            methods:{
                handleClick:function(){
                    this.number ++;
                    this.$emit("change")
                }
            },
            template:'<div @click="handleClick">{{number}}</div>'
        })
        var vm=new Vue({
            el:'#app',
            data:{
                total:0
            },
            methods:{
                // handleClick:function(){
                //     console.log(this.$refs.hello.innerHTML);
                // }
                    handleChange:function(){
                        this.total=this.$refs.one.number+this.$refs.two.number
                    }
            }
        });
    </script>
</body>

父子組件間的傳值

注意單向數據流,不推薦改變父組件傳遞過來的數據

1、父組件向子組件傳值

在父組件中使用屬性定義需要傳的值,子組件用props接收

:count="0"傳遞的是一個數字(js表達式),若爲count="0"傳遞的是字符

2、子組件向父組件傳值

子組件通過事件觸發的形式向父組件傳值

示例:

<div id='app'>
        <counter :count="2" @inc="handleIncrease"></counter>
        <counter :count="3" @inc="handleIncrease"></counter>
        <div>{{total}}</div>
    </div>

    <script>
        var counter={
            props:[
                'count'
            ],
            data:function () {  
                return{
                    number:this.count
                }
            },
            template:"<div @click='handleClick'>{{number}}</div>",
            methods:{
                handleClick:function(){
                    this.number=this.number+2;
                    this.$emit("inc",2)
                }
            }
        }

        var vm=new Vue({
            el:'#app',
            data:{
                total:5
            },
            methods:{
                handleIncrease:function(step){
                    this.total+=step;
                }
            },
            components:{
                counter:counter
            }
        });
    </script>

組件參數校驗

props: {
                // content:[Number,String]
                content: {
                    type: [Number, String],
                    required: false, //是否必傳
                    default: "default value",
                    validator:function(value){
                        return(value.length>5)
                    }
                }
            }

組件綁定原生事件

1、子組件直接綁定

 Vue.component('child', {
            template: "<div @click='handleChildClick'>Child</div>",
            props: {},
            methods:{
                handleChildClick:function(){
                    alert('child click')
                }
            }
        })

2、給click加上.native

<body>
    <div id='app'>
        <child @click.native="handleClick"></child>
    </div>
    <script>
        Vue.component('child', {
            template: "<div>Child</div>",
        })
        var vm = new Vue({
            el: '#app',
            data: {},
            methods: {
                handleClick:function(){
                    alert('click')
                }
            }
        });
    </script>
</body>

非父子組件間的傳值

使用 Bus/總線/發佈訂閱模式 實現

<script>
        Vue.prototype.bus=new Vue()//讓以後創建的每個Vue示例都有一個共享的屬性bus,且bus是你一個Vue實例
        Vue.component('child', {
            template: "<div @click='handleClick'>{{selfContent}}</div>",
            data:function(){
                return {
                    selfContent:this.content
                }
            },
            props:{
                content:String
            },
            methods:{
                handleClick:function(){
                    this.bus.$emit('change',this.selfContent)//bus是個Vue實例所以有$emit()方法
                }
            },
            mounted:function () {
                var this_=this
                this.bus.$on('change',function (msg) {//$on監聽bus觸發的事件
                    this_.selfContent=msg
                  })
              }
        })

        var vm = new Vue({
            el: '#app',
        });
    </script>

Vue中的插槽

原來:太low

<div id='app'>
        <child content="<p>Gu</p>"></child>
    </div>

    <script>
        Vue.component('child',{
            props:['content'],
            template:'<div><p>hello</p><div v-html="this.content"></div></div>'
        })

        var vm=new Vue({
            el:'#app',
            data:{},
        });
    </script>

1、普通插槽、具名插槽

<div id='app'>
        <child>
            <!-- <p>Gu</p> -->
            <div class="header" slot="header">header</div>
            <div class="footer" slot="footer">footer</div>
        </child>
    </div>

    <script>
        Vue.component('child',{
            props:['content'],
            template:'<div><slot name="header">默認內容</slot><p>hello</p><slot name=footer>默認內容</slot></div>'
        })

        var vm=new Vue({
            el:'#app',
            data:{},
        });
    </script>

2、作用域插槽

原來:

<div id='app'>
        <child></child>
    </div>

    <script>
        Vue.component('child',{
            data:function(){
                return{
                    list:[1,2,3,4]
                }
            },
            template:'<div><ul><li v-for="item of list">{{item}}</li></ul></div>'
        })

        var vm=new Vue({
            el:'#app',
            data:{

            },
        });
    </script>

但我們渲染什麼需要外部告訴我們而不是child子組件控制

作用域插槽應該由template包裹 slot-scope傳過來的接收數據

<div id='app'>
        <child>
            <template slot-scope="props">
                <li>{{props.item}}---hello</li>
            </template>
        </child>
    </div>

    <script>
        Vue.component('child',{
            data:function(){
                return{
                    list:[1,2,3,4]
                }
            },
            template:'<div><ul><slot v-for="item of list" :item=item></slot></ul></div>'//傳入item數據
        })

        var vm=new Vue({
            el:'#app',
            data:{

            },
        });
    </script>

動態組件與v-once

在組件里加上v-once那麼組件第一次加載時會被放到內存裏,下次切換時會這從內存中取出,提高性能

  <div id='app'>
        <component :is="type"></component>
        <!-- <child-one v-if="type==='child-one'"></child-one>
        <child-two v-if="type==='child-two'"></child-two> -->
        <button @click='handleBtnClick'>change</button>
    </div>

    <script>
        Vue.component('child-one', {
            template: '<div v-once>child-one</div>'
        })
        Vue.component('child-two', {
            template: '<div v-once>child-two</div>'
        })
        var vm = new Vue({
            el: '#app',
            data: {
                type:"child-one"
            },
            methods: {
                handleBtnClick:function () {
                    this.type=this.type==='child-one' ? "child-two" : "child-one";
                  }
            }
        });
    </script>

Vue中的動畫

Vue中css動畫的原理(過度動畫)

<transition name="fade">
            <div v-if="show">hello world</div>
        </transition>

當一個元素被transition包裹以後,vue會自動分析元素的css樣式然後構建一個動畫流程

在進入/離開的過渡中,會有 6 個 class 切換。

  1. v-enter:定義進入過渡的開始狀態。在元素被插入之前生效,在元素被插入之後的下一幀移除。
  2. v-enter-active:定義進入過渡生效時的狀態。在整個進入過渡的階段中應用,在元素被插入之前生效,在過渡/動畫完成之後移除。這個類可以被用來定義進入過渡的過程時間,延遲和曲線函數。
  3. v-enter-to: 2.1.8版及以上 定義進入過渡的結束狀態。在元素被插入之後下一幀生效 (與此同時 v-enter 被移除),在過渡/動畫完成之後移除。
  4. v-leave: 定義離開過渡的開始狀態。在離開過渡被觸發時立刻生效,下一幀被移除。
  5. v-leave-active:定義離開過渡生效時的狀態。在整個離開過渡的階段中應用,在離開過渡被觸發時立刻生效,在過渡/動畫完成之後移除。這個類可以被用來定義離開過渡的過程時間,延遲和曲線函數。
  6. v-leave-to: 2.1.8版及以上 定義離開過渡的結束狀態。在離開過渡被觸發之後下一幀生效 (與此同時 v-leave 被刪除),在過渡/動畫完成之後移除。

Transition Diagram

<style>
        .fade-enter,
        .fade-leave-to{
            opacity: 0;
        }
        .fade-leave-active,
        .fade-enter-active{
            transition: opacity 4s;
        }
    </style>
<div id='app'>
        <transition name="fade">
            <div v-if="show">hello world</div>
        </transition>
        <button @click="handleBtnClick">Button</button>
    </div>

    <script>
        var vm=new Vue({
            el:'#app',
            data:{
                show:true
            },
            methods:{
                handleBtnClick:function(){
                    this.show=!this.show
                }
            }
        });
    </script>

使用animate

1、自己寫:
@keyframes bounce-in {
            0% {
                transform: scale(0);
            }

            50% {
                transform: scale(1.5);
            }

            100% {
                transform: scale(1);
            }
        }

        .enter {
            transform-origin: left center;
            animation: bounce-in 1s;
        }
        .leave {
            transform-origin: left center;
            animation: bounce-in 1s reverse;
        }
<div id='app'>
        <transition enter-active-class="enter" leave-active-class="leave">
            <div v-if="show">hello world</div>
        </transition>
        <button @click="handleBtnClick">Button</button>
    </div>

    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                show: true
            },
            methods: {
                handleBtnClick: function () {
                    this.show = !this.show
                }
            }
        });
    </script>
2、使用animate.css庫
 <link rel="stylesheet" type="text/css" href="../../lib/animate/animate.css">
 <div id='app'>
        <!-- <transition enter-active-class="enter" leave-active-class="leave"> -->
        <transition enter-active-class="animated swing" leave-active-class="animated shake">
            <div v-if="show">hello world</div>
        </transition>
        <button @click="handleBtnClick">Button</button>
    </div>

    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                show: true
            },
            methods: {
                handleBtnClick: function () {
                    this.show = !this.show
                }
            }
        });
    </script>

同時使用過度和動畫

 .fade-enter,
        .fade-leave-to{
            opacity: 0;
        }
        .fade-enter-active,
        .fade-leave-active{
            transition: opacity 1s;
        }
<div id='app'>
            <!--  type="transition"選擇時長爲過度動畫時長  :duration="{enter:5000,leave:10000}"自定義動畫時長-->
        <transition  
                :duration="{enter:5000,leave:10000}"
                name="fade"
                appear
                enter-active-class="animated swing fade-enter-active"
                leave-active-class="animated shake fade-leave-active"
                appear-active-class="animated swing">
            <div v-if="show">hello world</div>
        </transition>
        <button @click="handleBtnClick">Button</button>
    </div>

    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                show: true
            },
            methods: {
                handleBtnClick: function () {
                    this.show = !this.show
                }
            }
        });
    </script>

Vue中js動畫與Velocity結合

1、自己寫:

<div id='app'>
        <transition name="fade" 
        @before-enter="handleBeforeEnter"
        @enter="handleEnter"
        @after-enter="handleAfterEnter">
            <div v-if="show">hello world</div>
        </transition>
        <button @click="handleBtnClick">Button</button>
    </div>

    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                show: true
            },
            methods: {
                handleBtnClick: function () {
                    this.show = !this.show
                },
                handleBeforeEnter:function (el) {
                    el.style.color="red";
                },
                handleEnter:function(el,done){
                    setTimeout(() => {
                        el.style.color="green";  
                    }, 2000);
                    setTimeout(() => {
                        done();
                    }, 4000);
                },
                handleAfterEnter:function(el){
                    el.style.color="#000"
                }
            }
        });
    </script>

2、使用velocity.js庫

<script src="../../lib/velocity/velocity.min.js"></script>
<div id='app'>
        <transition name="fade" @before-enter="handleBeforeEnter" @enter="handleEnter" @after-enter="handleAfterEnter">
            <div v-if="show">hello world</div>
        </transition>
        <button @click="handleBtnClick">Button</button>
    </div>

    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                show: true
            },
            methods: {
                handleBtnClick: function () {
                    this.show = !this.show
                },
                handleBeforeEnter: function (el) {
                    el.style.opacity=0;
                },
                handleEnter: function (el, done) {
                    Velocity(el,{opacity:1},{duration:1000,complete:done})
                },
                handleAfterEnter: function (el) {
                    console.log("動畫結束")
                }
            }
        });
    </script>

多個元素的過渡動畫

.fade-enter,
        .fade-leave-to {
            opacity: 0;
        }

        .fade-leave-active,
        .fade-enter-active {
            transition: opacity 1s;
        }
<div id='app'>
        <!-- mode="in-out"元素先進入在隱藏 -->
        <transition name="fade" mode="out-in">
            <!-- 動態組件 -->
            <component :is="type"></component>
            <!-- <child-one v-if="show" key="one"></child-one>
            <child-two v-else key="two"></child-two> -->
            <!-- <div v-if="show" key="hello">hello world</div>
            <div v-else key="bye">bey world</div> -->
        </transition>
        <button @click="handleBtnClick">Button</button>
    </div>

    <script>
        Vue.component('child-one', {
            template: '<div v-once>child-one</div>'
        })
        Vue.component('child-two', {
            template: '<div v-once>child-two</div>'
        })

        var vm = new Vue({
            el: '#app',
            data: {
                // show: true
                type:"child-one"
            },
            methods: {
                handleBtnClick: function () {
                    // this.show = !this.show
                    this.type=this.type==="child-one" ?"child-two":"child-one";
                }
            }
        });
    </script>

列表過渡動畫

<style>
        .fade-enter,
        .fade-leave-to {
            opacity: 0;
        }

        .fade-leave-active,
        .fade-enter-active {
            transition: opacity 1s;
        }
    </style>
<div id='app'>
        <transition-group name="fade">
            <div v-for="item of list" :key="item.id">{{item.title}}</div>
        </transition-group>
        <button @click="handleBtnClick">Add</button>
    </div>

    <script>
        var count = 0;

        var vm = new Vue({
            el: '#app',
            data: {
                list: []
            },
            methods: {
                handleBtnClick: function () {
                    this.list.push({
                        id: count++,
                        title: "hello world " + (count - 1)
                    })
                }
            }
        });
    </script>

動畫封裝

1、css封裝

.v-enter,
        .v-leave-to {
            opacity: 0;
        }

        .v-leave-active,
        .v-enter-active {
            transition: opacity 2s;
        }
<div id='app'>
       <fade :show="show">
            <div>Hello World</div>
       </fade>
        <button @click="handleBtnClick">Button</button>
    </div>

    <script>
        Vue.component("fade",{
            props:['show'],
            template:'<transition><slot v-if="show"></slot></transition>'
        })

        var vm = new Vue({
            el: '#app',
            data: {
                show: true
            },
            methods: {
                handleBtnClick: function () {
                    this.show = !this.show
                }
            }
        });
    </script>

2、js封裝

<div id='app'>
       <fade :show="show">
            <div>Hello World</div>
       </fade>
       <fade :show="show">
           <h1>Hello World</h1>
       </fade>
        <button @click="handleBtnClick">Button</button>
    </div>

    <script>
        Vue.component("fade",{
        props:['show'],
        template:'<transition @before-enter="handleBeforeEnter" @enter="handleEnter"><slot v-if="show"></slot></transition>',
        methods:{
            handleBeforeEnter:function(el){
                el.style.color="red";
            },
            handleEnter:function(el,done){
                setTimeout(() => {
                    el.style.color="green";
                    done();
                }, 2000);
            }
        }
        })

        var vm = new Vue({
            el: '#app',
            data: {
                show: true
            },
            methods: {
                handleBtnClick: function () {
                    this.show = !this.show
                }
            }
        });
    </script>

學習到這路你的基礎基本已經掌握,可以看下一張實戰
https://blog.csdn.net/Gueyue/article/details/102453943

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章