Vue系列之『滿足多數(shù)需求的基本使用』

首先創(chuàng)建一個(gè)簡單的vue應(yīng)用

# 全局安裝 vue-cli
$ npm i -g vue-cli
# 創(chuàng)建一個(gè)簡單的vue倉庫
$ vue init webpack-simple learnvue
# 安裝依賴
$ cd learnvue
$ npm i
$ npm run dev

class綁定——?jiǎng)討B(tài)地切換class

  • 在:class上綁定一個(gè)對象
  • 在:class上綁定一個(gè)對象名
  • 在:class上綁定一個(gè)返回對象的計(jì)算屬性
  • 在:class上綁定一個(gè)數(shù)組填帽,數(shù)組語法中也可以使用對象語法
  • 三元表達(dá)式:根據(jù)條件切換列表中的class

注意:普通class和綁定class可以共存

<template>
  <div id="app">
    {{msg}}
    <!--  1.在在:class上綁定一個(gè)對象  -->
    <div :class="{active:isActive}" class="header">
      我是header溶耘,我有一個(gè)普通class和一個(gè)可能存在的class對象
    </div>
    <div :class="{bigger:isBigger,'text-danger':hasError}" class="main">
      我是main念颈,我有一個(gè)普通class和一個(gè)可能存在的class對象
    </div>

    <!--  在:class上綁定一個(gè)對象名  -->
    <div :class="classObj1">
      我是小字球散,我有背景色
    </div>

    <!-- 在:class上綁定一個(gè)返回對象的計(jì)算屬性 -->
    <div :class="classObj2">
      我是大字七芭,沒有背景色
    </div>

    <!--在:class上綁定一個(gè)數(shù)組拷沸,可使用三元表達(dá)式介衔,數(shù)組語法中也可以使用對象語法  -->
    <div :class="['text-danger',classObj1]">我始終是紅色字址貌,可能是大字也可能是小字删壮,有或者沒有綠色背景</div>
    <div :class="[classObj2,{'text-danger':hasError}]">我現(xiàn)在是大字且為紅色贪绘,沒有背景色</div>
    <div :class="[isActive? '' :'text-danger']">我是紅字</div>

  </div>
</template>

<script>
export default {
  name: 'app',
  data() {
    return {
      msg: 'Welcome to Your Vue.js App',
      isActive: 0,
      isBigger: '',
      hasError: true,
      classObj1: {
        active: !this.isActive,
        bigger: this.isBigger
      }
    }
  },
  computed: {
    classObj2() {
      return {
        active: this.isActive && this.hasError,
        bigger: !this.isBigger && this.hasError
      }
    }
  }
}
</script>

<style>
.active {
  background: green;
}

.header {
  font-size: 2em;
}

.bigger {
  font-size: 4em;
}

.text-danger {
  color: red;
}

.main {
  font-style: italic;
}
</style>

style綁定——綁定內(nèi)聯(lián)樣式

  • 看著很像css內(nèi)聯(lián)樣式,屬性名可用駝峰式或用短橫線分隔央碟,短橫線分隔要用單引號(hào)引起來
  • 直接綁定到一個(gè)樣式對象
  • 結(jié)合計(jì)算屬性使用
  • 數(shù)組語法

當(dāng) v-bind:style 使用需要添加瀏覽器引擎前綴的 CSS 屬性時(shí)税灌,如 transform,Vue.js 會(huì)自動(dòng)偵測并添加相應(yīng)的前綴亿虽。

<template>
  <div id="app">
    {{msg}}
    <div :style="{color:activeColor,fontSize:fontSize+'px'}">
      hello world
    </div>

    <div :style="styleObj1">
      hello dot
    </div>

    <div :style="styleObj2">
      hello dolby
    </div>

    <div :style="[styleObj1,styleObj2]">
      hello dolby
    </div>

  </div>
</template>

<script>
export default {
  name: 'app',
  data() {
    return {
      msg: 'Welcome to Your Vue.js App',
      activeColor: 'red',
      fontSize: 12,
      styleObj1: {
        background: 'yellow',
        color: 'pink'
      }
    }
  },
  computed: {
    styleObj2() {
      return {
        fontStyle: 'italic',
        fontWeight: 'bolder'
      }
    }
  }
}
</script>

vue不得不說的生命周期

當(dāng)一個(gè)vue實(shí)例被創(chuàng)建時(shí)菱涤,它向 Vue 的響應(yīng)式系統(tǒng)中加入了其 data 對象中能找到的所有的屬性。當(dāng)這些屬性的值發(fā)生改變時(shí)洛勉,視圖將會(huì)產(chǎn)生“響應(yīng)”粘秆,即匹配更新為新的值。

看下圖:

圖源Vue.js教程

一個(gè)實(shí)例的生命周期分為creat收毫、mount攻走、update殷勘、destroy四個(gè)階段,它們的分工各有不同:

  • create:創(chuàng)建
  • mount:掛載DOM
  • update:數(shù)據(jù)更新
  • destroy:銷毀(一般為手動(dòng)清理事件和定時(shí)器)

同時(shí)在這些過程中也會(huì)運(yùn)行一些叫做生命周期鉤子的函數(shù)昔搂,這給了用戶在不同階段添加自己的代碼的機(jī)會(huì)玲销。對應(yīng)生命周期來看,又有以下8個(gè)鉤子:

beforeCreate摘符、created痒玩、beforeMount、mounted议慰、beforeUpdate蠢古、updated、beforeDestroy别凹、destroyed草讶。

看一個(gè)例子:

<template>
  <div id="app">
    {{msg}}
  </div>
</template>

<script>
export default {
  name: 'app',
  data() {
    return {
      msg: 'Welcome to Your Vue.js App',
    }
  },
  beforeCreate() {
    console.log('beforeCreate')
  },
  created() {
    console.log('created')
    setTimeout(() => {
      this.msg = 'change msg'
    }, 1000);
  },
  beforeMount() {
    console.log('beforeMount')
  },
  mounted() {
    console.log('mounted')
  },
  beforeUpdate() {
    console.log('beforeUpdate')
  },
  updated() {
    console.log('updated')
  },
  beforeDestroy() {
    console.log('beforeDestroy')
  },
  destroyed() {
    console.log('destroyed')
  },
  methods: {
    clickBtn() {
      alert('hello')
    }
  },
  watch: {
    msg() {
      console.log('hello')
    }
  }
}
</script>

打開localhost:8080,頁面顯示初始msg內(nèi)容炉菲,控制臺(tái)打印beforeCreate堕战、created、beforeMount拍霜、mounted

大約1s之后文虏,頁面內(nèi)容發(fā)生變化,緊接著watch生效退敦,控制臺(tái)一次打印出hello,beforeUpdate,updated叽掘,這里沒有打印出beforeDestroy和destroyed是因?yàn)轫撁嫔蠜]有事件。

v-model

單行文本

v-model 指令用于在表單 <input><textarea> 元素上創(chuàng)建雙向數(shù)據(jù)綁定道偷。它會(huì)根據(jù)控件類型自動(dòng)選取正確的方法來更新元素缀旁,但 v-model 本質(zhì)上不過是語法糖。它負(fù)責(zé)監(jiān)聽用戶的輸入事件以更新數(shù)據(jù)勺鸦,并對一些極端場景進(jìn)行一些特殊處理并巍。

<template>
  <div id="app">
    <input type="text" placeholder="edit me" v-value="hello">
  </div>
</template>

以上代碼的效果是頁面上會(huì)出現(xiàn)一個(gè)input輸入框且有初始值value

當(dāng)我們在input中使用v-model用于綁定數(shù)據(jù)時(shí),value值不生效

<template>
  <div id="app">
    <input type="text" placeholder="edit me" v-model="message" value="hello">
  </div>
</template>

<script>
export default {
  name: 'app',
  data() {
    return {
      message: '',
    }
  },
}
</script>

v-model 會(huì)忽略所有表單元素的 value换途、checked懊渡、selected 特性的初始值而總是將 Vue 實(shí)例的數(shù)據(jù)作為數(shù)據(jù)來源。如果有需要军拟,我們應(yīng)在組件的 data 選項(xiàng)中聲明初始值剃执。

<template>
  <div id="app">
    <input type="text" placeholder="edit me" v-model="value">
  </div>
</template>

<script>
export default {
  name: 'app',
  data() {
    return {
      message: '',
      value: 'init',
    }
  },
}
</script>

現(xiàn)在結(jié)合前面學(xué)到的看一段代碼:

<template>
  <div id="app">
    <input type="text" placeholder="edit me" v-model="message">
    <button @click="clickBtn">Click me</button>
    <p :style="styleObj">Message is: {{message}}</p>
  </div>
</template>

<script>
export default {
  name: 'app',
  data() {
    return {
      message: '',
      isClick: ''
    }
  },
  computed: {
    styleObj() {
      return {
        color: this.isClick && this.message ? 'red' : '',
        background: this.isClick && this.message ? 'yellow' : ''
      }
    }
  },
  methods: {
    clickBtn() {
      if (this.message) {
        this.isClick = true
      }
    }
  },
}
</script>

我們?yōu)閕nput定義了一個(gè)placeholder值為'edit me'并綁定了一個(gè)message屬性

首先看input里綁定的message和p中message之間的關(guān)系,前面說v-model雙向綁定不過是語法糖吻谋,實(shí)際上還是單向綁定忠蝗。
當(dāng)input中的內(nèi)容發(fā)生變化,也就是input中綁定的message——來自于data中的message屬性值發(fā)生了變化漓拾,p中的message也會(huì)隨之改變阁最,所以數(shù)據(jù)改變是單向的從data中的message屬性到頁面上的message屬性變換的過程戒祠。所以p中的文本會(huì)隨著input中的內(nèi)容改變而改變。

我們再來看看data中的另一個(gè)屬性'isClick'速种,我們給它賦值為一個(gè)空的字符串姜盈,即布爾值false

繼續(xù)看代碼,在button按鈕上定義了一個(gè)單擊事件'clickBtn'配阵,在p元素上綁定了一個(gè)內(nèi)聯(lián)樣式'styleObj'馏颂,我們把樣式對象放在computed中,這樣就會(huì)返回計(jì)算后的屬性對象棋傍。當(dāng)用戶點(diǎn)擊按鈕時(shí)救拉,如果input中有輸入,我們將'isClick'值設(shè)為true瘫拣,反應(yīng)在頁面上就是輸入不為空的情況下點(diǎn)擊按鈕之后p元素有了黃色背景亿絮,字色變?yōu)榧t色。

多行文本
<template>
  <div id="app">
    <span>Multiline message is:</span>
    <p style="white-space: pre-line;">{{ message }}</p>
    <br>
    <textarea v-model="message" placeholder="add multiple lines"></textarea>
  </div>
</template>

<script>
export default {
  name: 'app',
  data() {
    return {
      message: '',
    }
  },
}
</script>

在文本區(qū)域插值 (<textarea></textarea>) 并不會(huì)生效麸拄,應(yīng)用 v-model 來代替派昧。

復(fù)選框
  • 單個(gè)復(fù)選框綁定到布爾值
<template>
  <div id="app">
    <input type="checkbox" v-model="checked">
    <label for="checkbox">{{checked}}</label>
  </div>
</template>

<script>
export default {
  name: 'app',
  data() {
    return {
      checked: false,
    }
  },
}
</script>
  • 多個(gè)復(fù)選框綁定到同一數(shù)組
<template>
  <div id="app">
    <input type="checkbox" value="Jack" v-model="checkedArr">
    <label for="jack">Jack</label>
    <input type="checkbox" value="John" v-model="checkedArr">
    <label for="john">John</label>
    <input type="checkbox" value="Mike" v-model="checkedArr">
    <label for="mike">Mike</label>
    <br>
    <span>Checked names: {{ checkedArr }}</span>
  </div>
</template>

<script>
export default {
  name: 'app',
  data() {
    return {
      checkedArr: [],
    }
  },
}
</script>

綁定到checkedArr中的值是input中的value

單選按鈕
<template>
  <div id="app">
    <input type="radio" value="Jack" v-model="picked">
    <label for="jack">Jack</label>
    <input type="radio" value="John" v-model="picked">
    <label for="john">John</label>
    <input type="radio" value="Mike" v-model="picked">
    <label for="mike">Mike</label>
    <br>
    <span>picked names: {{ picked }}</span>
  </div>
</template>

<script>
export default {
  name: 'app',
  data() {
    return {
      picked: '',
    }
  },
}
</script>
選擇框
  • 單選時(shí)
<template>
  <div id="app">
    <select v-model="selected">
      <option disabled value="">請選擇</option>
      <option>A</option>
      <option>B</option>
      <option>C</option>
    </select>
    <span>Selected: {{ selected }}</span>
  </div>
</template>

<script>
export default {
  name: 'app',
  data() {
    return {
      selected: '',
    }
  },
}
</script>

如果 v-model 表達(dá)式的初始值未能匹配任何選項(xiàng),<select> 元素將被渲染為“未選中”狀態(tài)拢切。這種情況下iOS 不會(huì)觸發(fā) change 事件蒂萎,這會(huì)使用戶無法選擇第一個(gè)選項(xiàng)。因此推薦像上面這樣提供一個(gè)值為空的禁用選項(xiàng)淮椰。

  • 多選時(shí)
<template>
  <div id="app">
    <select v-model="selectedArr" multiple >
      <option>A</option>
      <option>B</option>
      <option>C</option>
    </select>
    <span>SelectedArr: {{ selectedArr }}</span>
  </div>
</template>

<script>
export default {
  name: 'app',
  data() {
    return {
      selectedArr: [],
    }
  },
}
</script>

用v-for渲染的動(dòng)態(tài)項(xiàng)

<template>
  <div id="app">
    <select v-model="selected">
      <option v-for="option in options" :value="option.value">{{option.text}}</option>
    </select>
    <span>Selected: {{ selected }}</span>
  </div>
</template>

<script>
export default {
  name: 'app',
  data() {
    return {
      selected: 'A',
      options: [
        { value: 'A', text: 'One' },
        { value: 'B', text: 'Two' },
        { value: 'C', text: 'Three' },
      ]
    }
  }
}

computed

接下來我們來說一個(gè)前面反復(fù)提到的計(jì)算屬性對象computed五慈,計(jì)算屬性可以應(yīng)用于各種復(fù)雜的邏輯,使代碼更加輕便容易維護(hù)实苞。
語法:computed: {xxx: function () { return /* */}}

<template>
  <div id="app">
    <p>Original message: "{{ message }}"</p>
    <p>Computed reversed message: "{{ reversedMessage }}"</p>
  </div>
</template>

<script>
export default {
  name: 'app',
  data() {
    return {
      message: 'hello'
    }
  },
  computed: {
    reversedMessage() {
      return this.message.split('').reverse().join('')
    }
  },
}

可以像綁定普通屬性一樣在模板中綁定計(jì)算屬性豺撑。Vue 知道 reversedMessage 依賴于message,因此當(dāng) message 發(fā)生改變時(shí)黔牵,所有依賴 reversedMessage 的綁定也會(huì)更新。而且最妙的是用計(jì)算屬性沒有副作用爷肝,更易于測試和理解猾浦。

methods

看了上面computed的例子你會(huì)發(fā)現(xiàn),我們在methods中使用方法可達(dá)到同樣的效果:

<template>
  <div id="app">
    <p>Original message: "{{ message }}"</p>
    <p>Methods reversed message: "{{ reversedMessage() }}"</p>
  </div>
</template>

<script>
export default {
  name: 'app',
  data() {
    return {
      message: 'hello'
    }
  },
  methods: {
    reversedMessage() {
      return this.message.split('').reverse().join('')
    }
  },
}

我們可以將同一函數(shù)定義為一個(gè)方法而不是一個(gè)計(jì)算屬性灯抛。兩種方式的最終結(jié)果確實(shí)是完全相同的金赦。不同的是計(jì)算屬性是基于它們的依賴進(jìn)行緩存的,只有在它的相關(guān)依賴發(fā)生改變時(shí)才會(huì)重新求值对嚼。這就意味著只要 message 還沒有發(fā)生改變夹抗,多次訪問 reversedMessage 計(jì)算屬性會(huì)立即返回之前的計(jì)算結(jié)果,而不必再次執(zhí)行函數(shù)纵竖。

這也同樣意味著下面的計(jì)算屬性將不再更新漠烧,因?yàn)?Date.now() 不是響應(yīng)式依賴:

<template>
  <div id="app">
    <p>{{ now }}</p>
    <p>{{ now }}</p>
    <p>{{ now }}</p>
    <p>{{ now }}</p>
  </div>
</template>

<script>
export default {
  name: 'app',
  computed: {
    now() {
      return Date.now()
    }
  },
}

相比之下杏愤,每當(dāng)觸發(fā)重新渲染時(shí),調(diào)用方法總會(huì)再次執(zhí)行函數(shù)已脓。

<template>
  <div id="app">
    <p>{{ now() }}</p>
    <p>{{ now() }}</p>
    <p>{{ now() }}</p>
    <p>{{ now() }}</p>
  </div>
</template>

<script>
export default {
  name: 'app',
  methods: {
    now() {
      return Date.now()
    }
  },
}

我們?yōu)槭裁葱枰彺嫔郝ィ考僭O(shè)我們有一個(gè)性能開銷比較大的的計(jì)算屬性 A,它需要遍歷一個(gè)巨大的數(shù)組并做大量的計(jì)算度液。然后我們可能有其他的計(jì)算屬性依賴于 A 厕宗。如果沒有緩存,我們將不可避免的多次執(zhí)行 A 的 getter函數(shù)堕担,如果你不希望有緩存已慢,請用方法來替代。

前面說過了computed計(jì)算屬性與methods方法的比較霹购,現(xiàn)在說說計(jì)算屬性和偵聽屬性watch的比較佑惠。

<template>
  <div id="app">
    {{ fullName }}
  </div>
</template>

<script>
export default {
  name: 'app',
  data() {
    return {
      firstName: 'Foo',
      lastName: 'Bar',
      fullName: 'Foo Bar'
    }
  },
  watch: {
    firstName: function(val) {
      this.fullName = val + ' ' + this.lastName
    },
    lastName: function(val) {
      this.fullName = this.firstName + ' ' + val
    }
  },
}

以上做法是命令式的watch回調(diào),而且代碼重復(fù)厕鹃,也沒辦法做到響應(yīng)式兢仰,沒有任何意義〖敛辏看computed如何實(shí)現(xiàn)

<template>
  <div id="app">
    {{ fullName }}
  </div>
</template>

<script>
export default {
  name: 'app',
  data() {
    return {
      firstName: 'Foo',
      lastName: 'Bar',
    }
  },
  computed: {
    fullName() {
      return this.firstName + ' ' + this.lastName
    }
  },
}

代碼簡潔直觀把将,且當(dāng)firstName或lastName改變時(shí),fullName也會(huì)隨之改變并反映到頁面上忆矛。
雖然計(jì)算屬性在大多數(shù)情況下更合適察蹲,但有時(shí)也需要一個(gè)自定義的偵聽器,于是就有了watch催训。

watch

當(dāng)需要在數(shù)據(jù)變化時(shí)執(zhí)行異步或開銷較大的操作時(shí)洽议,watch是最有用響應(yīng)數(shù)據(jù)變化的方法,一般用于監(jiān)聽input等有輸入操作的場景。

<template>
  <div id="app">
    {{msg}}
    <input v-model="question">
    <div>{{answer}}</div>
  </div>
</template>

<script>
export default {
  name: 'app',
  created() {
    console.log('')
    setTimeout(() => {
      this.msg = '12121212'
    }, 1000);
  },
  data() {
    return {
      msg: 'Welcome to Your Vue.js App',
      question: '',
      answer: 'I cannot give you an answei until you ask a question'
    }
  },
  watch: {
    question() {
      this.answer = 'Waiting for you to stop typing...'
    },
    msg() {
      alert('hello')
    }
  }
}
</script>

以上代碼在http://localhost:8080/中打開后漫拭,頁面正常顯示數(shù)據(jù)亚兄,接著先彈出hello

點(diǎn)擊確定后msg值變?yōu)閟etTimeout中的12121212

在輸入框中輸入任意內(nèi)容,answer值變?yōu)槲覀冊O(shè)定的字符串

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末采驻,一起剝皮案震驚了整個(gè)濱河市审胚,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌礼旅,老刑警劉巖膳叨,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異痘系,居然都是意外死亡菲嘴,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來龄坪,“玉大人昭雌,你說我怎么就攤上這事∠つ” “怎么了城豁?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長抄课。 經(jīng)常有香客問我唱星,道長,這世上最難降的妖魔是什么跟磨? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任间聊,我火速辦了婚禮,結(jié)果婚禮上抵拘,老公的妹妹穿的比我還像新娘哎榴。我一直安慰自己,他們只是感情好僵蛛,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布尚蝌。 她就那樣靜靜地躺著,像睡著了一般充尉。 火紅的嫁衣襯著肌膚如雪飘言。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天驼侠,我揣著相機(jī)與錄音姿鸿,去河邊找鬼。 笑死倒源,一個(gè)胖子當(dāng)著我的面吹牛苛预,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播笋熬,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼热某,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了胳螟?” 一聲冷哼從身側(cè)響起苫拍,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎旺隙,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體骏令,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蔬捷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片周拐。...
    茶點(diǎn)故事閱讀 39,696評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡铡俐,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出妥粟,到底是詐尸還是另有隱情审丘,我是刑警寧澤,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布勾给,位于F島的核電站滩报,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏播急。R本人自食惡果不足惜脓钾,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望桩警。 院中可真熱鬧可训,春花似錦、人聲如沸捶枢。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽烂叔。三九已至谨胞,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間长已,已是汗流浹背畜眨。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留术瓮,地道東北人康聂。 一個(gè)月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像胞四,于是被迫代替她去往敵國和親恬汁。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評論 2 353