>  기사  >  웹 프론트엔드  >  Vue 데이터 통신에 대한 자세한 소개(예제 포함)

Vue 데이터 통신에 대한 자세한 소개(예제 포함)

不言
不言앞으로
2018-11-20 14:27:272514검색

이 글은 Vue 데이터 통신에 대한 자세한 소개를 제공합니다(예제 포함). 도움이 필요한 친구들이 참고할 수 있기를 바랍니다.

1. 소개

컴포넌트는 vue.js의 가장 강력한 기능 중 하나이며, 컴포넌트 인스턴스의 범위는 서로 독립적입니다. 즉, 서로 다른 컴포넌트 간의 데이터가 서로 참조할 수 없습니다. 구성 요소 간에 데이터를 전송하는 방법이 중요합니다. 이 글에서는 props, $emit/$on和vuex以及新出的$attrs/$listeners 및 제공/주입과 같은 몇 가지 일반적인 데이터 전송 방법을 나열하고 이해하기 쉬운 예를 들어 차이점을 설명합니다. 친구들에게 도움이 되기를 바랍니다.

2. Props

부모 컴포넌트 A는 props를 통해 자식 컴포넌트 B에 전달되고, B에서 A로의 동작은 B 컴포넌트에서 $emit, A 컴포넌트에서 v-on을 통해 구현됩니다.

Prop은 단방향 바인딩입니다. 상위 구성 요소의 속성이 변경되면 하위 구성 요소로 전송되지만 그 반대는 아닙니다.
그리고 하위 구성 요소 내에서 직접 prop을 변경할 수 없습니다. 그렇지 않으면 오류가 발생합니다. 보고됩니다. 그런 다음 전달된 prop을 수정하려는 경우 다음과 같은 방법이 있습니다.

방법 1: 하위 구성 요소가 이를 로컬 데이터로 사용하려는 경우 해당 데이터를 다른 변수에 저장한 다음 데이터에 영향을 주지 않고 작동할 수 있습니다. 상위 구성 요소 데이터.

    <div>
    <h2>父组件:{{name}}</h2>
    <input>
    <my-hello></my-hello>
  </div>
  <template>
    <div>
      <h3>子组件{{username}}</h3>
      <button>修改数据</button>
    </div>
  </template>
  <script>
    var vm = new Vue({ //父组件
      el: &#39;#itany&#39;,
      data: {
        name: "tom"
      },
      components: {
        &#39;my-hello&#39;: { //子组件
          props: ["name"],
          template: &#39;#hello&#39;,
          data() {
            return {
              username: this.name
            }
          },
          //   computed: {
          //     changeName() { //如果要实时监测父组件数据的变化,还必须用到计算属性,
                                 然而计算属性不能直接被更改
          //       return this.name
          //     }
          //   },
          methods: {
            change() {
              this.username = "alice";
              // this.changeName = "alice";该方法无效,不能直接更改计算属性
            }
          },
        }
      }
    });
  </script>

이 방법은 다른 변수를 연산하여 상위 컴포넌트가 전달한 데이터에 영향을 줄 수 있지만, 앞으로는 상위 컴포넌트의 데이터가 변경됨에 따라 하위 컴포넌트도 변경할 수 없다는 것이 큰 단점입니다. 이때 계산된 속성을 사용하면 변경 내용을 동기화할 수 있지만 하위 구성 요소는 전달된 데이터를 변경할 수 없습니다. 따라서 이 방법은 덜 일반적으로 사용됩니다.

방법 2: 하위 구성 요소가 데이터를 수정하고 이를 상위 구성 요소에 동기식으로 업데이트하려는 경우 다음 두 가지 방법이 있습니다.

a .sync 사용(버전 1.0에서는 지원되고 버전 2.0에서는 지원되지 않음) 버전 2.3에서는 다시)가 표시되어야 합니다. 업데이트 이벤트를 트리거합니다.

<div>
  <h2>父组件:{{name}}</h2>
  <input>
  <hr>
  <my-hello></my-hello>
</div>
<template>
  <div> 
    <h3>子组件:{{name}}</h3>
    <button>修改数据</button>
  </div>
</template>
<script>
  var vm = new Vue({ //父组件
      el: &#39;#itany&#39;,
      data: {
        name: &#39;tom&#39;
      },
      components: {
        &#39;my-hello&#39;: { //子组件
           template: &#39;#hello&#39;,
           props: [&#39;name&#39;],
           methods: {
             change() {
              // this.name=&#39;alice&#39;;这种写法不行
                 this.$emit(&#39;update:name&#39;, &#39;alice123&#39;);
            //方式2:a.使用.sync,需要显式地触发一个更新事件
             }
           }
           }
        }
    });
</script>

Vue 데이터 통신에 대한 자세한 소개(예제 포함)

b 상위 구성 요소의 데이터를 객체로 래핑한 다음 하위 구성 요소에서 객체의 속성을 수정할 수 있습니다(객체가 참조 유형이고 동일한 항목을 가리키기 때문). 메모리 공간), 권장

<div>
    <h2>父组件:{{name}}</h2>
    <input>
    <h2>父组件:{{user.age}}</h2>
    <hr>
    <my-hello></my-hello>
</div>

<template>
    <div>
        <h3>子组件:{{name}}</h3>
        <h3>子组件:{{user.age}}</h3>
        <button>修改数据</button>
    </div>
</template>
<script>
    var vm = new Vue({ //父组件
        el: &#39;#itany&#39;,
        data: {
            name: &#39;tom&#39;,
            user: { //父组件中的数据包装成对象
                name: &#39;zhangsan&#39;,
                age: 24
            }
        },
        components: {
            &#39;my-hello&#39;: { //子组件
                template: &#39;#hello&#39;,
                props: [&#39;name&#39;, &#39;user&#39;],
                methods: {
                    change() {
                        this.user.age = 18;
                    }
                }
            }
        }
    });
</script>

Vue 데이터 통신에 대한 자세한 소개(예제 포함)

이는 JavaScript에서 객체와 배열이 참조로 전달되기 때문입니다. 따라서 배열 또는 객체 유형 prop의 경우 하위 구성 요소에서 객체 또는 배열 자체를 변경합니다. 상위 구성 요소의 상태에 영향을 미칩니다 .

3. $emit/$on

이 방법은 빈 Vue 인스턴스를 중앙 이벤트 버스(이벤트 센터)로 사용하여 이벤트를 트리거하고 이벤트를 수신하여 모든 구성 요소 간의 통신을 영리하고 가볍게 구현합니다. , 아버지-아들, 형제, 교차 수준을 포함합니다. 프로젝트 규모가 상대적으로 클 경우 더 나은 상태 관리 솔루션인 vuex를 선택할 수 있습니다.

1. 구체적인 구현 방법:

    var Event=new Vue();
    Event.$emit(事件名,数据);
    Event.$on(事件名,data => {});

2. 예: A, B, C라는 세 가지 구성 요소가 있습니다. 구성 요소 C는 구성 요소 A 또는 B

<div>
    <my-a></my-a>
    <my-b></my-b>
    <my-c></my-c>
</div>
<template>
  <div>
    <h3>A组件:{{name}}</h3>
    <button>将数据发送给C组件</button>
  </div>
</template>
<template>
  <div>
    <h3>B组件:{{age}}</h3>
    <button>将数组发送给C组件</button>
  </div>
</template>
<template>
  <div>
    <h3>C组件:{{name}},{{age}}</h3>
  </div>
</template>
<script>
var Event = new Vue();//定义一个空的Vue实例
var A = {
    template: &#39;#a&#39;,
    data() {
      return {
        name: &#39;tom&#39;
      }
    },
    methods: {
      send() {
        Event.$emit(&#39;data-a&#39;, this.name);
      }
    }
}
var B = {
    template: &#39;#b&#39;,
    data() {
      return {
        age: 20
      }
    },
    methods: {
      send() {
        Event.$emit(&#39;data-b&#39;, this.age);
      }
    }
}
var C = {
    template: &#39;#c&#39;,
    data() {
      return {
        name: &#39;&#39;,
        age: ""
      }
    },
    mounted() {//在模板编译完成后执行
     Event.$on(&#39;data-a&#39;,name => {
         this.name = name;//箭头函数内部不会产生新的this,这边如果不用=>,this指代Event
     })
     Event.$on(&#39;data-b&#39;,age => {
         this.age = age;
     })
    }
}
var vm = new Vue({
    el: &#39;#itany&#39;,
    components: {
      &#39;my-a&#39;: A,
      &#39;my-b&#39;: B,
      &#39;my-c&#39;: C
    }
});    
</script>

Vue 데이터 통신에 대한 자세한 소개(예제 포함)

4. vuex

Vue 데이터 통신에 대한 자세한 소개(예제 포함)

1. Vuex

의 원리를 간략하게 소개합니다. Vuex는 단방향 데이터 흐름을 구현하며, 컴포넌트가 State에서 데이터를 변경하려고 할 때 데이터를 전역적으로 저장하는 State를 가지고 있습니다. Mutation은 상태 데이터에 대한 업데이트를 얻기 위해 호출할 외부 플러그인에 대한 구독자 모드도 제공합니다. 모든 비동기 작업(업데이트 데이터를 비동기식으로 얻기 위해 일반적으로 백엔드 인터페이스라고 함) 또는 일괄 동기 작업에 작업이 필요한 경우 작업은 상태를 직접 수정할 수 없으며 여전히 Mutation을 통해 수정해야 합니다. 마지막으로 State의 변경 사항에 따라 뷰에 렌더링됩니다.

2. 프로세스 내 각 모듈의 주요 기능을 간략하게 소개합니다:

  • Vue 구성 요소: Vue 구성 요소. HTML 페이지에서는 사용자 작업 및 기타 대화형 동작을 수신하고 디스패치 메서드를 실행하여 응답할 해당 작업을 트리거하는 일을 담당합니다.

  • dispatch: 작업 동작을 트리거하는 메서드는 작업을 실행할 수 있는 유일한 메서드입니다.

  • actions:操作行为处理模块,由组件中的$store.dispatch('action 名称', data1)来触发。然后由commit()来触发mutation的调用 , 间接更新 state。负责处理Vue Components接收到的所有交互行为。包含同步/异步操作,支持多个同名方法,按照注册的顺序依次触发。向后台API请求的操作就在这个模块中进行,包括触发其他action以及提交mutation的操作。该模块提供了Promise的封装,以支持action的链式触发。

  • commit:状态改变提交操作方法。对mutation进行提交,是唯一能执行mutation的方法。

  • mutations:状态改变操作方法,由actions中的commit('mutation 名称')来触发。是Vuex修改state的唯一推荐方法。该方法只能进行同步操作,且方法名只能全局唯一。操作之中会有一些hook暴露出来,以进行state的监控等。

  • state:页面状态管理容器对象。集中存储Vue components中data对象的零散数据,全局唯一,以进行统一的状态管理。页面显示所需的数据从该对象中进行读取,利用Vue的细粒度数据响应机制来进行高效的状态更新。

  • getters:state对象读取方法。图中没有单独列出该模块,应该被包含在了render中,Vue Components通过该方法读取全局state对象。

如果你想深入了解,请点击从头开始学习Vuex这篇文章

五、localStorage

1.简介

HTML5中新增了本地存储的解决方案----WebStorage,它分成两类:sessionStorage和localStorage。localStorage保存的数据长期存在,除非被清除,下一次访问该网站的时候,网页可以直接读取以前保存的数据

localStorage保存的数据,以“键值对”的形式存在。也就是说,每一项数据都有一个键名和对应的值。所有的数据都是以文本格式保存。
存入数据使用setItem方法。它接受两个参数,第一个是键名,第二个是保存的数据。
localStorage.setItem("key","value");
读取数据使用getItem方法。它只有一个参数,就是键名。
var valueLocal = localStorage.getItem("key");

如果想深入了解,请点击浏览器存储这篇文章

2.localStorage与Vuex区别

vuex 是 vue 的状态管理器,存储的数据是响应式的。但是并不会保存起来,刷新之后就回到了初始状态,具体做法应该在vuex里数据改变的时候把数据拷贝一份保存到localStorage里面,刷新之后,如果localStorage里有保存的数据,取出来再替换store里的state。

let defaultCity = "上海"
try {   // 用户关闭了本地存储功能,此时在外层加个try...catch
  if (!defaultCity){
    defaultCity = JSON.parse(window.localStorage.getItem('defaultCity'))
  }
}catch(e){}
export default new Vuex.Store({
  state: {
    city: defaultCity
  },
  mutations: {
    changeCity(state, city) {
      state.city = city
      try {
      window.localStorage.setItem('defaultCity', JSON.stringify(state.city));
      // 数据改变的时候把数据拷贝一份保存到localStorage里面
      } catch (e) {}
    }
  }
})

3.注意点

由于vuex里,我们保存的状态,都是数组,而localStorage只支持字符串,所以需要用JSON转换:

JSON.stringify(state.subscribeList);   // array -> string
JSON.parse(window.localStorage.getItem("subscribeList"));    // string -> array

六、$attrs/$listeners

1.简介

多级组件嵌套需要传递数据时,通常使用的方法是通过vuex。但如果仅仅是传递数据,而不做中间处理,使用 vuex 处理,未免有点大材小用。为此Vue2.4 版本提供了另一种方法,当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件。通常配合 interitAttrs 选项一起使用

// demo.vue
  <template>
    <div>
      <foo>
    </foo>
</div>
  
  <script>
  const childCom = ()=> import(&#39;./childCom1.vue&#39;)
  export default {
    data () {
      return {
        foo: &#39;Hello World!&#39;,
        boo: &#39;Hello Javascript!&#39;,
        coo: &#39;Hello Vue&#39;,
        doo: &#39;Last&#39;
      }
    },
    components: { childCom }
  }
  </script></template>
// childCom1.vue
<template>
  <div>
    <p>foo: {{ foo }}</p>
    <p>attrs: {{ $attrs }}</p>
    <child-com2></child-com2>
  </div>
</template>
<script>
const childCom2 = ()=> import(&#39;./childCom2.vue&#39;)
export default {
  props: [&#39;foo&#39;],  // foo作为props属性绑定
  inheritAttrs: false,
  created () {
    console.log(this.$attrs) // { boo: &#39;Hello Javascript!&#39;, coo: &#39;Hello Vue&#39;, doo: &#39;Last&#39; }
  }
}
</script>
// childCom2.vue
<template>
  <div>
   <p>boo: {{ boo }}</p>
   <p>attrs: {{ $attrs }}</p>
   <child-com3></child-com3>
  </div>
</template>
<script>
const childCom3 = ()=> import(&#39;./childCom3.vue&#39;)
export default {
  props: [&#39;boo&#39;] // boo作为props属性绑定
  inheritAttrs: false,
  created () {
    console.log(this.$attrs) // { coo: &#39;Hello Vue&#39;, doo: &#39;Last&#39; }
  }
}
</script>

<span style="font-family: 微软雅黑, Microsoft YaHei;">$attrs表示没有继承数据的对象,格式为{属性名:属性值}。Vue2.4提供了$attrs , $listeners 来传递数据与事件,跨级组件之间的通讯变得更简单</span>

七、provide/inject

1.简介

Vue2.2.0新增API,这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。一言而蔽之:祖先组件中通过provider来提供变量,然后在子孙组件中通过inject来注入变量。

2.举个例子

// 父组件
  export default {
    name: "Parent",
    provide: {
      parent: "父组件的值"
    }
  }
// 子组件
 export default {
    name: "",
    inject: ['parent'],
    data() {
      return {
        demo: this.parent //"父组件的值"
      }
    }
  }

上例中子组件中inject注入了父组件provide提供的变量parent,并将它提供给了data属性

如果需要源代码,请戳源代码

위 내용은 Vue 데이터 통신에 대한 자세한 소개(예제 포함)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 segmentfault.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제