Vue組件通信總結(jié)

能工摹形,巧匠竊意岂昭。必三省吾身,萬不可怠惰因循羡榴。

foreword

  • 這篇容納了我個人所知道的一些Vue 2.x組件通信的總結(jié),之后3.x官網(wǎng)公布后會增加3.x的部分。(篇幅長,細(xì)節(jié)有那么一些些,熟知部分可以一眼略過).

start

一. props $emit $attrs $listeners $props

  • 之所以把$attrs/$listeners/$props 和props $emit 放在一起 是因為個人感覺坑资,更加方便記憶耗帕。老項目使用$attrs $listeners $props這幾個API需要看當(dāng)時的vue版本是不是已經(jīng)支持;
1.props 父組件向子組件傳值

_ parent.vue

<template>
  <div>
    PARENT
    <children :stars="stars"></children>
  </div>
</template>

<script>
import children from './children/children';
export default {
  components:{children},
  data(){
    return {
      stars:[
        {name:"周杰倫",id:1},
        {name:"劉亦菲",id:2},
        {name:"胡歌",id:3},
        {name:"古天樂",id:4},
      ]
    }
  },
}
</script>

_ children.vue

<template>
   <div>
     CHILDREN
     <ul>
       <li v-for="star in stars" :key="star.id">{{star.name}}</li>
     </ul>
   </div>
</template>

<script>
export default {
  name:"children", 
  props:{
    stars:{
      type:Array,
      default(){
        return []
      },
      // required:true // 是否必須屬性
      // type:Symbol, // 傳入類型 type String Number Boolean Function Object Array Symbol 
      // type:CustormFn,// 可以是自定義構(gòu)造函數(shù),用instanceof 檢測
      validator(V){  // 自定義驗證函數(shù)
        return V.length > 2
      }
    }
  },
  created(){
    console.log(this.stars) //[{…}, {…}, {…}, {…}, __ob__: Observer]
  }
}
</script>
summarize: 父組件通過props傳入到子組件. 子組件可以設(shè)定傳入值的校驗,等屬性.組件中的數(shù)據(jù)方式共有 data,computed,props以及provide和inject(這個待商榷).
2. 子組件通過事件的形式向父組件傳值

_ parent

<template>
  <div>
    <p>{{bestHandsome}}</p>
    <children @handleBs='handleBs'></children>
  </div>
</template>
<script>
import children from './children';
export default {
  name:'parent2',
  components:{children},
  data(){
    return {
      bestHandsome:'劉德華'
    }
  },
  methods:{
    handleBs(name){
      this.bestHandsome = name;
    }
  }
}
</script>

_ children

<template>
  <button @click="setBestHandsome('吳彥祖')">BUTTON</button>
</template>

<script>
export default {
  name:'children2',
  methods:{
    setBestHandsome(name){
      this.$emit('handleBs',name);
    }
  }
}
</script>
summarize:子組件通過events的形式改變父組件的值,實際上是調(diào)用傳入?yún)?shù)父組件的方法,來改變父組件的值. 有部分程序員喜歡將 .sync 和v-model這兩個語法糖也歸為組件通信方式,這里不做歸納.詳細(xì)請看官方文檔.sync,v-model.
3. $attrs/$listeners/$props

官方解釋

  • $props:當(dāng)前組件接收到的 props 對象。Vue 實例代理了對其 props 對象屬性的訪問袱贮。類型(Object)
  • $attrs:包含了父作用域中不作為 prop 被識別 (且獲取) 的特性綁定 (class 和 style 除外)仿便。類型:{ [key: string]: string }(只讀)
  • $listeners: 包含了父作用域中的 (不含 .native 修飾器的) v-on 事件監(jiān)聽器。它可以通過 v-on="$listeners" 傳入內(nèi)部組件——在創(chuàng)建更高層次的組件時非常有用攒巍。類型: { [key: string]: Function | Array<Function> }(只讀)
$props

_ code

// parent.vue
<template>
  <div>
    <children
      name='input'
      type='nmber'
      disabled
      autofocus
      placeholder='這是一個輸入框'
    ></children>
  </div>
</template>
// children.vue
<template>
   <div>
     <input v-bind="$props">
   </div>
</template>

<script>
export default {
  name:"children", 
  props:['name','type','disabled','autofocus','placeholder'],
  mounted(){
    console.log(this.$props.name)// input
  }
}
</script>

_ view


view

html.png
  • 注意這里使用v-bind="$props"就會使得子組件中的input標(biāo)簽綁定上父組件中定義的props屬性.
$attrs

_ code

// parent.vue
<template>
  <div>
    <children
      name='input'
      type='nmber'
      disabled
      autofocus
      placeholder='這是一個輸入框'
    ></children>
  </div>
</template>
// children.vue
<template>
   <div>
     <input v-bind="$attrs">
   </div>
</template>

<script>
export default {
  inheritAttrs:false, // 將默認(rèn)綁定根元素屬性去掉
  name:"children", 
  props:['handsome'],
  mounted(){
    console.log(this.$attrs.name)// input
    console.log(this.$attrs.handsome)// undefined
    console.log(this.$props.handsome)// 1
  }
}
</script>
  • inheritAttrs

默認(rèn)情況下父作用域的不被認(rèn)作 props 的特性綁定 (attribute bindings) 將會“回退”且作為普通的 HTML 特性應(yīng)用在子組件的根元素上嗽仪。當(dāng)撰寫包裹一個目標(biāo)元素或另一個組件的組件時,這可能不會總是符合預(yù)期行為柒莉。通過設(shè)置 inheritAttrs 到 false绒疗,這些默認(rèn)行為將會被去掉城榛。而通過 (同樣是 2.4 新增的) 實例屬性 $attrs 可以讓這些特性生效,且可以通過 v-bind 顯性的綁定到非根元素上顽耳。

不設(shè)置inheritAttrs:false效果

設(shè)置inheritAttrs效果
$listeners

_ code

// parent.vue
<template>
  <div>
    <p>{{ handsome }}</p>
    <children
      @changeHandsome="changeHandsome"
      @clearHandsome="clearHandsome"
      @resetHandsome="resetHandsome"
    ></children>
  </div>
</template>

<script>
import children from './children/children';
export default {
  components:{children},
  data(){
    return {
      handsome:'lin'
    }
  },
  methods:{
    changeHandsome(name){
      this.handsome = name;
    },
    clearHandsome(){
      this.handsome = '';
    },
    resetHandsome(){
      this.handsome = 'lin';
    },
  }
}
</script>
// children.vue
<template>
   <div>
     <g-children v-on="$listeners"></g-children>
   </div>
</template>
<script>
import gChildren from './grandchildren'
export default {
  name:"children", 
  components:{gChildren},
  mounted(){
    console.log(this.$listeners)
  }
}
</script>
// grandchildren.vue
<template>
  <div>
    <button @click="$emit('changeHandsome','zhou')">set Zhou</button>
    <button @click="$emit('clearHandsome')">clear</button>
    <button @click="$emit('resetHandsome')">reset</button>
  </div>
</template>
以上這些實際上是父子組件直接直接或者間接通過vue提供的通信方式通信.

二. $refs $parent $children $root

  • 官方解釋

$refs:一個對象伟叛,持有注冊過 [ref 特性] 的所有 DOM 元素和組件實例屯仗。
$parent:父實例容握,如果當(dāng)前實例有的話侧戴。(類型:Vue instance)
$children:當(dāng)前實例的直接子組件。需要注意 $children 并不保證順序喷市,也不是響應(yīng)式的。如果你發(fā)現(xiàn)自己正在嘗試使用 $children 來進(jìn)行數(shù)據(jù)綁定威恼,考慮使用一個數(shù)組配合 v-for 來生成子組件品姓,并且使用 Array 作為真正的來源。(類型:Array)
$root:當(dāng)前組件樹的根 Vue 實例箫措。如果當(dāng)前實例沒有父實例腹备,此實例將會是其自己。

$refs

_ code

//children.vue
<script>
export default {
  name: "children",
  data() {
    return {
      name: "xiaoerlang",
      age: 18
    };
  }
};
</script>
// parent.vue
<template>
  <div>
    <children ref="children"></children>
    <button @click="setChildrenData">button</button>
  </div>
</template>
<script>
import children from "./children/children";
export default {
  components: { children },
  methods: {
    setChildrenData() {
      console.log(this.$refs.children.name); //第一次點擊按鈕的時候打印 xiaolang
      this.$refs.children.name = "xiaoming";
      console.log(this.$refs.children.name); //第一次點擊按鈕的時候打印 xiaoming
    }
  }
};
</script>
$parent
// parent.vue
<template>
  <div>
    {{name}}
    <children></children>
  </div>
</template>
<script>
import children from "./children/children";
export default {
  components: { children },
  data(){
    return {
      name:'liu'
    }
  },
};
</script>
// children.vue
<template>
  <div>
    <button @click="setParentName('fei')">button</button>
  </div>
</template>
<script>
export default {
  name: "children",
  methods:{
    setParentName(name){
      this.$parent.name = name;
    }
  }
};
</script>
$children
// parent.vue
<template>
  <div>
    <children></children>
    <button @click="setChildrenName('yi')">button</button>
  </div>
</template>
<script>
import children from "./children/children";
export default {
  components: { children },
  methods:{
    setChildrenName(name){
      this.$children[0].name = name;
    }
  }
};
</script>
// children.vue
<template>
  <div>
    {{name}}
  </div>
</template>
<script>
export default {
  name: "children",
  data() {
    return {
      name: "xiaoerlang",
    };
  },
};
</script>
$root:這里與$parent類似,是當(dāng)前組件樹的根實例.

附加:使用$parent或者$root配合$on和$emit可以 進(jìn)行兄弟組件之間通信

// parent.vue
<template>
  <div>
    <bother1></bother1>
    <bother2></bother2>
  </div>
</template>
<script>
import bother1 from './children/brother1';
import bother2 from './children/brother2';
export default {
  components: { bother1,bother2 },
};
</script>
// bother2.vue
<template>
  <div>{{name}}</div>
</template>
<script>
export default {
  name:'brother2',
  data(){
    return{
      name:'zhouxiaolun'
    }
  },
  created(){
    this.$parent.$on('setB2',this.setName)
  },
  methods:{
    setName(name){
      this.name = name;
    }
  }
}
</script>

// bother1.vue
<template>
  <button @click="setB2Name('zhoujielun')">button</button>
</template>

<script>
export default {
  name:'brother1',
  methods:{
    setB2Name(name){
      this.$parent.$emit('setB2',name)
    }
  }
}
</script>
summarize
  • 注意這里$children 格式為數(shù)組,如果沒有就是空數(shù)組,但是這里的數(shù)組順序與頁面順序是不對應(yīng)的,這里涉及到了虛擬dom掛載.
  • 上面的部分情況其實是拿到對應(yīng)的組件的實例,相當(dāng)于在對應(yīng)vue組件中調(diào)用this.xx = 'xxxx';
  • 實際開發(fā)中,非自定義組件,或者真實需要,不建議使用$parent和$children $root進(jìn)行組件之間的通信.

三. provide/inject

  • provide 和 inject 主要為高階插件/組件庫提供用例斤蔓。并不推薦直接用于應(yīng)用程序代碼中植酥。provide/inject能夠?qū)崿F(xiàn)祖先和后代之間傳值.
// 祖先組件
export default {
  provide() {
    const that = this;
    return {
      foo: "foo",
      forefathersThis: that
    };
  },
  name: "parent",
  components: { children }
};
// 后代組件
export default {
  name: "children",
  inject: ["foo", "forefathersThis"],
  created() {
    console.log(this.foo);
    console.log(this.forefathersThis); // 祖先組件的實例
  }
};
  • 提示:provide 和 inject 綁定并不是可響應(yīng)的。這是刻意為之的。然而友驮,如果你傳入了一個可監(jiān)聽的對象漂羊,那么其對象的屬性還是可響應(yīng)的。這里也可以傳入this到后代組件中,但實際開發(fā)中不推薦使用,可以用于開發(fā)高階組件或者組件庫.

四.事件總線eventBus方式(自定義Bus類,或者使用Vue代替);

// Bus 類
class Bus {
  constructor() {
    this.CB = {};
  }
  // 監(jiān)聽
  $on(name, fn) {
    this.CB[name] = this.CB[name] || [];
    this.CB[name].push(fn)
  }
  // 派發(fā)
  $emit(name, args) {
    this.CB[name] && this.CB[name].forEach(cb => cb(args))
  }
}
export default Bus;
// main.js
import Bus from './eventBus';
Vue.prototype.$bus = new Bus();
// 組件1
 methods: {
    setBH2Name() {
      this.$bus.$emit("setB2", "zhoujielun");
    }
  }
// 組件2 
  created() {
    this.$bus.$on("setB2", this.setName);
  },
  methods: {
    setName(name) {
      this.name = name;
    }
  }
summarize:
  • 如果不使用自定義方式,也可以Vue.prototype.$bus = new Vue(); vue內(nèi)部已經(jīng)做了具體處理.并且提供$once只監(jiān)聽一次這個事件,$off(name)移除name事件監(jiān)聽,$off() 移除所有事件監(jiān)聽.
  • 這里主要說Vue通信方式,所以關(guān)于上部分需要在destroy生命周期需要注銷監(jiān)聽等操作都未列出,實際開發(fā)實際需求.

五.Vuex

  • Vuex 是一個專為 Vue.js 應(yīng)用程序開發(fā)的狀態(tài)管理模式,實際上是把一些需要多處用到的狀態(tài)放在同一個對象中.
  • 小demo
// store
  state: {
    infoName: "handsome"
  },
  mutations: {
    setInfoName(state, payload) {
      state.infoName = payload;
    }
  }
// 組件1
<script>
import { mapMutations } from "vuex";
import bother2 from "./children/brother2";
export default {
  name: "parent",
  components: { bother2 },
  methods: {
    ...mapMutations(["setInfoName"]),
    setInfo() {
      const name = "ugly";
      this.setInfoName(name);
    }
  }
};
</script>
// 組件2
<script>
import { mapState } from "vuex";
export default {
  name: "brother2",
  computed: {
    ...mapState({
      infoName: s => s.infoName
    })
  }
};
</script>

summarize: Vuex相對來說比redux簡單一些,詳細(xì)可以參考中文官網(wǎng)Vuex中文官網(wǎng)

六. 自定義broadcast/dispatch

  • vue 1.x 版本中有兩個API $dipatch,$broadcast,$broadcast和$dispatch 這兩個API在2.x版本中去除. 實際上我們經(jīng)常寫一些自定義組件庫,或者高階組件的時候可能會用到.
    vue 1.x解釋

$dispatch:向上級派發(fā)事件,祖輩組件中$on監(jiān)聽到
$broadcast:與$dispatch相反,向下級廣播事件.

  • 自定義代碼實現(xiàn)功能.
/**
 * @param {*} componentName  // 組件名
 * @param {*} eName  // 自定義事件名稱
 * @param {*} params // 傳遞參數(shù)數(shù)據(jù)
 */
export function broadcast(componentName, eName, params) {
  this.$children.forEach(child => {
    const name = child.$options.name;
    if (name === componentName) {
      // 調(diào)用子組件emit
      child.$emit.bind(child)(eName, params)
    } else {
      // 遞歸調(diào)用
      broadcast.bind(child)(componentName, eName, params)
    }
  })
};
/**
 * @param {*} componentName  // 組件名
 * @param {*} eName  // 自定義事件名稱
 * @param {*} params // 傳遞參數(shù)數(shù)據(jù)
 */
export function dispatch(componentName, eName, params) {
  let parent = this.$parent || this.$root;
  let name = parent.$options.name;
  // 往上尋找 直到找到
  while (parent && (!name || name !== componentName)) {
    parent = parent.$parent;
    if (parent) name = parent.$options.name;
  }
  if (parent) parent.$emit.bind(parent)(eName, params)
}
解析
  1. this.$options.xx 可以取到vue組件中export default暴露的對象的對應(yīng)xx屬性值.我們一幫用來取一些靜態(tài)屬性.例如 組件的name值,判斷是哪個組件.
  2. 我們找到對應(yīng)的子組件或者父組件,然后用$emit調(diào)用,實際上就相當(dāng)于我們在對應(yīng)的組件A中用this.$emit(xxx)調(diào)用其在當(dāng)前組件A中created生命周期中$on監(jiān)聽的事件.
  3. 實際的邏輯就是找到對應(yīng)組件實例, 組件實例$emit 自己本身$on監(jiān)聽的事件.
  • 引入 main.js
import { broadcast, dispatch } from './dispatch-broadcast';
Vue.prototype.$dispatch = dispatch;
Vue.prototype.$broadcast = broadcast;
  • 實例引用.
  1. $dispatch 派發(fā)
//  后代
<template>
  <div><button @click="setParentDay('Sat')">button</button></div>
</template>
<script>
export default {
  name: "children",
  methods: {
    setParentDay(day) {
      this.$dispatch("parent", "setDay", day);
    }
  }
};
</script>
//  祖先
<div>
    <children></children>
    <p>{{ day }}</p>
  </div>
</template>
<script>
import children from "./children/children";
export default {
  name: "parent",
  components: { children },
  data() {
    return { day: "Fir" };
  },
  created() {
    this.$on("setDay", this.setDay);
  },
  methods: {
    setDay(day) {
      this.day = day;
    }
  }
};
</script>
  1. $broadcast 廣播
// 祖先
<template>
  <div>
    <children></children>
    <button @click="setChildrenDay('Fir')">button</button>
  </div>
</template>
<script>
import children from "./children/children";
export default {
  name: "parent",
  components: { children },
  methods: {
    setChildrenDay(day) {
      this.$broadcast("children", "setDay", day);
    }
  },
};
</script>
// --------- 后代 --------------
<template>
  <div>{{ day }}</div>
</template>
<script>
export default {
  name: "children",
  data() {
    return {
      day: "Sat"
    };
  },
  created() {
    this.$on("setDay", this.setDay);
  },
  methods: {
    setDay(day) {
      this.day = day;
    }
  }
};
</script>

七. 自定義findComponents多個方法

  • 就像上面說的,其實我們尋找到了對應(yīng)組件的實例,就可以用這個實例進(jìn)行操作,就可以說進(jìn)行了組件的通信.那么這里就存在幾個問題. (注意這里的前提是組件中name的屬性設(shè)置嚴(yán)格按照規(guī)范),這些方法一般在我們自定義組件庫,或者定義一些高階組件用來使用.
提出問題.
  1. 如何由一個組件向上找到第一個最近的指定組件?
  2. 如何由一個組件向上找到所有的指定組件?
  3. 如何由一個組件向下找到最近的指定組件?
  4. 如何由一個組件向下找到所有的指定組件?
  5. 如何由一個組件找到指定的兄弟組件?
分析:
  • 利用$options.name $children $parent , 參數(shù)包含當(dāng)前組件的this,要找到的組件名name. 通過$options.name確定尋找的組件.
1. 由一個組件向上找到第一個最近的指定組件.
/**
 * @param {*} context  執(zhí)行上下文卸留,這里一般傳 this
 * @param {*} componentName 要找到的組件名 name
 * @returns
 */
function findComponentUpwrad(context, componentName) {
  let parent = context.$parent;
  let { name } = parent.$options;

  while (parent && (!name || [componentName].indexOf(name) < 0)) {
    parent = parent.$parent;
    if (parent) name = parent.$options.name;
  }
  return parent;
}
2. 由一個組件向上找到所有的指定組件
/**
 * @param {*} context  執(zhí)行上下文走越,這里一般傳 this
 * @param {*} componentName 要找到的組件名 name
 */
function findComponentsUpward(context, componentName) {
  const parents = [];
  const parent = context.$parent;
  if (parent) {
    if (parent.$options.name === componentName) parents.push(parent);
    return parents.concat(findComponentUpwrad(parent, componentName));
  }
  return [];
}
3. 由一個組件向下找到最近的指定組件
/**
 *@description 向下找到最近的指定組件
 *
 * @context {*} context 執(zhí)行上下文,這里一般傳 this
 * @componentName {*} componentName 要找到的組件名 name
 */
function findComponentDownward(context, componentName) {
  const childrens = context.$children;
  let children = null;
  if (childrens.length) {
    for (const child of childrens) {
      const { name } = child.$options;
      if (name === componentName) {
        children = child;
        break;
      } else {
        children = findComponentDownward(child, componentName);
        if (children) break;
      }
    }
  }
  return children;
}
4. 由一個組件向下找到所有的指定組件
/**
 * @context {*} context 執(zhí)行上下文耻瑟,這里一般傳 this
 * @componentName {*} componentName 要找到的組件名 name
 */
function findComponentsDownward(context, componentName) {
  return context.$children.reduce((components, child) => {
    if (child.$options.name === componentName) components.push(child);
    const foundChilds = findComponentsDownward(child, componentName);
    return components.concat(foundChilds);
  }, []);
}
5. 由一個組件找到指定的兄弟組件
/**
 * @context {*} context 執(zhí)行上下文旨指,這里一般傳 this
 * @componentName {*} componentName 要找到的組件名 name
 * @exceptMe  {Boolean}  是否包含本身
 * @description2 Vue.js 在渲染組件時,都會給每個組件加一個內(nèi)置的屬性 _uid喳整,這個 * * *_uid 是不會重復(fù)的谆构,
 */
function findBrothersComponents(context, componentName, exceptMe) {
  const res = context.$parent.$children.filter(item => item.$options.name === componentName);
  const index = res.findIndex(item => item._uid === context._uid);
  if (exceptMe) res.splice(index, 1);
  return res;
}
找到組件后就等于找到組件中的this,之后通信的方式就可以很隨意了,當(dāng)然這里使用方式一般是存在特殊情況下,正常我們組件之間的通信使用Vuex 或者 props $emit 就可以了.
代碼參考 iview源碼 具體位置在 iview assets.js,有興趣的朋友可以查看源碼.

總結(jié)

  • Vue組件之間的通信,當(dāng)然可能還有更多,這里容納了大部分,當(dāng)然可能還有其他一些.

好學(xué)而不勤問非真好學(xué)者. 如果有幫助請點上一個贊,如果由疑問,請評論留言.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市框都,隨后出現(xiàn)的幾起案子搬素,更是在濱河造成了極大的恐慌,老刑警劉巖瞬项,帶你破解...
    沈念sama閱讀 218,640評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蔗蹋,死亡現(xiàn)場離奇詭異,居然都是意外死亡囱淋,警方通過查閱死者的電腦和手機(jī)猪杭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,254評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來妥衣,“玉大人皂吮,你說我怎么就攤上這事∷笆郑” “怎么了蜂筹?”我有些...
    開封第一講書人閱讀 165,011評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長芦倒。 經(jīng)常有香客問我艺挪,道長,這世上最難降的妖魔是什么兵扬? 我笑而不...
    開封第一講書人閱讀 58,755評論 1 294
  • 正文 為了忘掉前任麻裳,我火速辦了婚禮,結(jié)果婚禮上器钟,老公的妹妹穿的比我還像新娘津坑。我一直安慰自己,他們只是感情好傲霸,可當(dāng)我...
    茶點故事閱讀 67,774評論 6 392
  • 文/花漫 我一把揭開白布疆瑰。 她就那樣靜靜地躺著眉反,像睡著了一般。 火紅的嫁衣襯著肌膚如雪穆役。 梳的紋絲不亂的頭發(fā)上寸五,一...
    開封第一講書人閱讀 51,610評論 1 305
  • 那天,我揣著相機(jī)與錄音孵睬,去河邊找鬼播歼。 笑死,一個胖子當(dāng)著我的面吹牛掰读,可吹牛的內(nèi)容都是我干的秘狞。 我是一名探鬼主播,決...
    沈念sama閱讀 40,352評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼蹈集,長吁一口氣:“原來是場噩夢啊……” “哼烁试!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起拢肆,我...
    開封第一講書人閱讀 39,257評論 0 276
  • 序言:老撾萬榮一對情侶失蹤减响,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后郭怪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體支示,經(jīng)...
    沈念sama閱讀 45,717評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,894評論 3 336
  • 正文 我和宋清朗相戀三年鄙才,在試婚紗的時候發(fā)現(xiàn)自己被綠了颂鸿。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,021評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡攒庵,死狀恐怖嘴纺,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情浓冒,我是刑警寧澤栽渴,帶...
    沈念sama閱讀 35,735評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站稳懒,受9級特大地震影響闲擦,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜场梆,卻給世界環(huán)境...
    茶點故事閱讀 41,354評論 3 330
  • 文/蒙蒙 一佛致、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧辙谜,春花似錦、人聲如沸感昼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,936評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蜕琴,卻和暖如春萍桌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背凌简。 一陣腳步聲響...
    開封第一講書人閱讀 33,054評論 1 270
  • 我被黑心中介騙來泰國打工上炎, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人雏搂。 一個月前我還...
    沈念sama閱讀 48,224評論 3 371
  • 正文 我出身青樓藕施,卻偏偏與公主長得像,于是被迫代替她去往敵國和親凸郑。 傳聞我的和親對象是個殘疾皇子裳食,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,974評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 對于vue來說,組件之間的消息傳遞是非常重要的芙沥,下面是我對組件之間消息傳遞的各種方式的總結(jié)诲祸,總共有8種方式。 1....
    edc余悸閱讀 355評論 0 3
  • 前言 組件是 vue.js最強(qiáng)大的功能之一而昨,而組件實例的作用域是相互獨立的救氯,這就意味著不同組件之間的數(shù)據(jù)無法相互引...
    用技術(shù)改變世界閱讀 2,167評論 1 3
  • 摘要: 總有一款合適的通信方式。 作者:浪里行舟 Fundebug經(jīng)授權(quán)轉(zhuǎn)載歌憨,版權(quán)歸原作者所有着憨。 前言 組件是 v...
    Fundebug閱讀 15,574評論 3 57
  • 前言 組件是 vue.js最強(qiáng)大的功能之一,而組件實例的作用域是相互獨立的躺孝,這就意味著不同組件之間的數(shù)據(jù)無法相互引...
    7abbcd54a89d閱讀 711評論 0 1
  • 前言 組件是 vue.js最強(qiáng)大的功能之一享扔,而組件實例的作用域是相互獨立的,這就意味著不同組件之間的數(shù)據(jù)無法相互引...
    Vicky丶Amor閱讀 5,994評論 10 162