#搭建Vue+TypeScript项目(七)

2020-12-29  本文已影响0人  风轻云淡小小木

梳理vue常用知识,自用
最好的行为是看官方文档,比我全

组件间消息传递

1.父组件->子组件

  #父组件传递消息给子组件
    ##父组件
    <topView ref="topView" :data="flag"></topView>
    ##子组件
    @Prop({ default: 1, type: Number })
    flag!: number;
  #父组件使用子组件变量
    (this.$refs.topView as any).data

2.子组件->父组件

#父组件
<topView @change="changeFun" ref="topView" :data="flag"></topView>

changeFun(send:any){
  console.log(send);
}
#子组件合适的时机触发
this.$emit('change',996)

3.同级组件传递

#通过共同父级传递的情况
#组件1
<div @click="change">点击我触发另一个组件事件</div>
change(){
  this.$parent.$emit('change',996)
}
#组件2
mounted() {
  this.$parent.$on("change", (data: any) => {
    console.log(data);
  });
}
#通过公共bus类来实现
class Bus {
  callback: any = {};
  constructor() {
    this.callback = {};
  }
  $on(name: string, fn: Function) {
    this.callback[name] = this.callback[name] || [];
    this.callback[name].push(fn);
  }
  $emit(name: string, argus: object) {
    this.callback[name].forEach((element: Function) => {
      element(argus);
    });
  }
}
export default Bus;
##使用
###在main.ts
Vue.prototype.$bus = new Bus();
####
#ts需要增加types
#在根目录下新建types文件夹。新建vue.d.ts文件
import Vue from "vue";
declare module "vue/types/vue" {
  interface Vue {
    $bus: any;
  }
}
###在组件a中
<div @click="change">点击我触发另一个组件事件</div>
change() {
  this.$bus.$emit("change", { name: "小小木" });
}
###在组件b中
 mounted() {
  this.$bus.$on("change", (data: object) => {
    console.log(data);
  });
}

4.祖先组件与后代组件

  #祖先给后代组件传值
  祖先
  @Provide()
  flag = "ggsmd";
  后代
  @Inject()
  flag:any
  ##注意不是动态改变的,但是对象指向同一个内存地址,可以改变

  #后代给祖先传值
  #后代
  <div @click="dispatch('change', '996福报')">点击我给祖先传值</div>
  dispatch(eventName: string, argus: any) {
    let parent = this.$parent;
    while (parent) {
      parent.$emit(eventName, argus);
      parent = parent.$parent;
    }
  }
  #祖先
  async mounted() {
    this.$on("change", (data: any) => {
      console.log(data);
    });
  }

5.插槽

  #匿名插槽
  #父组件
    <son>我是插槽数据</son>
  #子组件
    <div class="son">
      <slot></slot>
    </div>
  #具名插槽及插槽传值
  #父组件
  <son>
  <template v-slot:default> <div>我是默认插槽</div> </template>
  <template v-slot:content> <div>我是content插槽</div> </template>
  </son>
  
  #子组件
  <div class="son">
    <slot></slot>
    <slot name="content"></slot>
  </div>

  #传值
  #父组件
  <son><template v-slot:content="flag">
        <div>{{ flag.data.name }}</div>
      </template></son>
  #子组件
    <slot name="content" :data="data"></slot>
    data: object = {
      name: "996福报",
    };

5.v-model和.sync

#简单实现一个input组件
#父组件
  <son :value="value" @input="inputFun"></son>
  value: any = "";
  inputFun(value: any) {
    this.value = value;
  }
#子组件
  <div class="son">
    <input type="text" :value="value" @input="inputFun" />
  </div>

  @Prop()
  value: any;

  inputFun(e: any) {
    this.$emit("input", e.target.value);
  }
##使用v-model简化代码
#父组件
  <son v-model="value"></son>
  value: any = "";
#子组件
  <div class="son">
    <input type="text" :value="value" @input="inputFun" />
  </div>

  @Prop()
  value: any;

  inputFun(e: any) {
    this.$emit("input", e.target.value);
  }
##还可以通过model更改默认事件,假设是checkbox,不是input
#父组件
  <son v-model="value"></son>
  value: any = "";
#子组件
  <input type="checkbox" @change="checked" :checked="checked" />

  @Model("change", { type: Boolean })
  checked!: boolean;

  #类似于
  //类似于
  export default {
  model: {
    prop: 'checked',
    event: 'change',
  },
  props: {
    checked: {
      type: Boolean,
    },
  },
}

#sync 操作符
 sync修饰符类似于v-model,它能用于修改传递到子组件的属性,如果像下面这样写  
 <Input :value.sync="username"> 
 等效于下面这行,那么和v-model的区别只有事件名称的变化 
  <Input :value="username" @update:value="username=$event"> 
  这里绑定属性名称可以随意更改,相应的属性名也会变化
  <Input :foo="username" @update:foo="username=$event"> 
  // 所以sync修饰符的控制能力都在父级,事件名称也相对固定update:xx
##例子
#父组件
<son :username.sync="value"></son>
value: any = "默认value";
#子组件
  <div class="son">
    <div>{{ username }}</div>
    <div @click="changename">点击更改username</div>
  </div>

  @Prop()
  username: any;
  changename() {
    this.$emit("update:username", "1231");
  }
上一篇下一篇

猜你喜欢

热点阅读