vue 数据通信总结

数据单向流动prop   react也是一样prop 

 

1. prop / $emit  (常用 父子组件传递)     

//父传给子
<child :title="title"></child>

//子通过props接收
export default {
  name: 'demo',
  data: function() {},
  props: {
    title: {
      type: String
    }
  },
};
//子传给父

methods: {
    childTitle() {
      this.$emit('changeTitle', `我给父组件的第${this.key}次`);      
    }
  }
};


//父接收

<child @changeTitle="parentTitle"></child>  //自定义事件

 

2. $emit / $on  (任意组件间传递)

创建个空的组件,来作eventbus 用来触发及监听事件  

// 父组件
<template>
  <div class="container">
    <child1 :Event="Event"></child1>
    <child2 :Event="Event"></child2>
    <child3 :Event="Event"></child3>
  </div>
</template>

<script>

const Event = new vue();  //***重点

export default {
  name: "demo",
  data: function() {
    return {
      Event: Event
    };
  },
  components: {
    Child1,
    Child2,
    Child3
  },
};
</script>

// 子组件1
<template>
  <div class="center">    
    <button @click="send">我给3组件赋值</button>
  </div>
</template>

<script>
export default{
  name: "demo1",
  data() {
    return {
      name: "政采云"
    };
  },
  props: {
    Event
  },
  methods: {
    send() {
      this.Event.$emit("message-a", this.name);  //***触发事件
    }
  }
};
</script>


// 子组件2
<template>
  <div class="center">    
    <button @click="send">我给3组件赋值</button>
  </div>
</template>

<script>
/* eslint-disable */
export default {
  name: "demo2",
  data() {
    return {
      age: "3"
    };
  },
  props: {
    Event
  },
  methods: {
    send() {
      this.Event.$emit("message-b", this.age);  //***触发事件
    }
  }
};
</script>


// 子组件3
<template>
  <div class="center">我的名字是{{name}},今年{{age}}岁</div>
</template>

<script>
export default{
  name: 'demo3',
  data() {
    return {
      name: '',
      age: ''
    };
  },
  props: {
    Event
  },
  mounted() {
    this.Event.$on('message-a', name => {    //**** 重点: 监听事件message-a
      this.name = name;
    });
    this.Event.$on('message-b', age => {     //**** 重点: 监听事件message-b
      this.age = age;
    });
  },
};
</script>

可以任意传。  思想类似传对象给子组件,在子组件里修改对象的属性   父组件里的跟着响应

 

3.vuex  牛刀

集中式存储管理应用的所有组件的状态。

Vuex 实现了一个单项数据流,通过创建一个全局的 State 数据,组件想要修改 State 数据只能通过 Mutation 来进行,页面上的操作想要修改 State 数据时,需要通过 Dispatch (触发 Action ),而 Action 也不能直接操作数据,还需要通过 Mutation 来修改 State 中数据,最后根据 State 中数据的变化,来渲染页面

const store = new Vuex.Store({
  state: {
    count: 1
  },
  mutations: {
    increment(state) {
      state.count++;
    },
    reduce(state) {
      state.count--;
    }
  },
  actions: {
    actIncrement({ commit }) {
      commit('increment');
    },
    actReduce({ commit }) {
      commit('reduce');
    }
  },
  getters: {
    doubleCount: state => state.count*2
  }
});

//vue实例
export default {
  name: "demo",
  data: function() {
    return {};
  },
  components: {},
  props: {},
  computed: {
    ...mapState(["count"]),
    ...mapGetters(["doubleCount"])
  },
  methods: {
    ...mapActions(["actIncrement", "actReduce"])
  }
};

 

4. $attrs / $listeners

vue2.4后的新方法,加强props。

$attrs: 包含了父作用域中不作为 Prop 被识别 (且获取) 的特性绑定(Class 和  Style 除外)。当一个组件没有声明任何 Prop 时,这里会包含所有父作用域的绑定 (Class 和 Style 除外),并且可以通过 v-bind="$attrs" 传入内部组件——在创建高级别的组件时非常有用

$listeners: 包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件

//父组件
 <button style="backgroundColor:lightgray" @click="reduce">减dd</button>
 <child1 :aa="aa" :bb="bb" :cc="cc" :dd="dd" @reduce="reduce"></child1>


// 子组件1
<template>
  <div>
    <div class="center">
      <p>aa:{{aa}}</p>
      <p>child1的$attrs:{{$attrs}}</p>
      <button @click="this.reduce1">组件1减dd</button>
    </div>
    <child2 v-bind="$attrs" v-on="$listeners"></child2> //写法
  </div>
</template>

//子组件1的子组件也可以获得子组件1的父组件的属性和监听  

简单来说,$attrs 里存放的是父组件中绑定的非 props 属性,$listeners 里面存放的是父组件中绑定的非原生事件。  解决一级一级prop的痛点

 

5. Provider / Inject   需要一起使用

vue2.2新增的API。允许一个祖先组件向其所有子孙注入一个依赖,不论组件层级多深,在其上下游关系成立的时间里始终生效

// 父组件
<template>
  <div class="container">
    <button @click="this.changeName">我要改名字了</button>
    <p>我的名字:{{name}}</p>
    <child1></child1>
  </div>
</template>

<script>

export default {
  name: 'demo',
  data: function() {
    return {
      name: '节能'
    };
  },
  // provide() {
  //   return {
  //     name: this.name //这种绑定方式是不可响应的   !注意!  
  //   };
  // },
  provide() {
    return {
      obj: this   //绑定对象
    };
  },
  components: {
    Child1
  },
  methods: {
    changeName() {
      this.name = '节能晚上';
    }
  }
};
</script>


// 子组件
<template>
  <div>
    <div class="center">
      <!-- <p>子组件名字:{{name}}</p> -->
      <p>子组件名字:{{this.obj.name}}</p>
    </div>
    <child2></child2>
  </div>
</template>

<script>

export default {
  name: 'demo1',
  data() {
    return {};
  },
  props: {},
  // inject: ["name"],  //这种方式注入,改变了name是 非响应式的,
  inject: {             //这种注入  是响应式的。 
    obj: {  
      default: () => {
        return {};
      }
    }
  },
  components: {
    child2
  },
};
</script>


简单来说,就是父组件通过 Provider 传入变量,任意子孙组件通过 Inject 来拿到变量。 Provide 和 Inject 绑定并不是可响应的。然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的. 这是js对象引用类型的原故

资源搜索网站大全 https://www.renrenfan.com.cn 广州VI设计公司https://www.houdianzi.com

6. $parent / $children & $refs

$parent / $children: 指定已创建的实例之父实例,在两者之间建立父子关系。子实例可以用 this.$parent 访问父实例,子实例被推入父实例的 $children 数组中  。

$refs: 一个对象,持有注册过 ref 特性的所有 DOM 元素和组件实例。ref 被用来给元素或子组件注册引用信息。引用信息将会注册在父组件的 $refs 对象上。如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件。

posted @ 2020-12-06 12:46  陌路y  阅读(184)  评论(0编辑  收藏  举报