VueJs 컴포넌트의 부모-자식 통신 방법

不言
풀어 주다: 2018-05-07 14:57:36
원래의
1290명이 탐색했습니다.

이 글에서는 주로 VueJs 컴포넌트의 부모-자식 통신 방법을 소개합니다. 매우 훌륭하고 참고할만한 가치가 있습니다. 도움이 필요한 친구들은

Component (Father-Child Communication)

을 참조하세요. 1. 요약

다른 구성 요소 내에 정의된 구성 요소를 상위-하위 구성 요소라고 합니다. 1 하지만 다음 사항에 유의해야 합니다. 1. 하위 구성 요소는 상위 구성 요소 내부에서만 사용할 수 있습니다(상위 구성 요소 Tempalte에 작성됨).

2. 기본적으로 하위 구성 요소는 상위 구성 요소의 데이터에 액세스할 수 없습니다. 구성 요소 인스턴스 범위는 독립적입니다.

부모와 자식 간의 통신을 완료하는 방법은 무엇입니까? 간단한 문장으로 말하면: props는 아래로, 이벤트는 up입니다. 상위 구성 요소는 props를 통해 하위 구성 요소로 데이터를 전달하고 하위 구성 요소는 데이터를 하위 구성 요소로 보냅니다. 이벤트를 통한 부모 구성요소

부모 아들에서 아들로 전달: Props

아들에서 아버지로 전달: 아들: $emit(eventName) 부모 $on(eventName)

부모 방문 아들: ref

다음은 세 가지 사례 설명입니다. :

2. 아버지에서 아들로 전달: Props 구성 요소 인스턴스의 범위는 격리됩니다. 즉, 하위 구성 요소의 템플릿 내에서 상위 구성 요소의 데이터를 직접 참조할 수 없으며 참조해서는 안 됩니다. 하위 컴포넌트가 상위 컴포넌트의 데이터를 사용하게 하려면 하위 컴포넌트

의 props 옵션을 사용해야 합니다. Prop을 사용하여 데이터를 전송하는 방법에는 정적 양식과 동적 양식이 포함됩니다. 먼저 정적 props

1의 효과를 소개하겠습니다. static props

<script src="https://unpkg.com/vue"></script>
<p id="example">
 <parent></parent>
</p>
<script>
 //要想子组件能够获取父组件的,那么在子组件必须申明:props
 var childNode = {
  template: &#39;<p>{{message}}</p>&#39;,
  props: [&#39;message&#39;]
 }
 //这里的message要和上面props中值一致
 var parentNode = {
  template: `
   <p class="parent">
   <child message="我是"></child>
   <child message="徐小小"></child>
   </p>`,
  components: {
   &#39;child&#39;: childNode
  }
 };
 // 创建根实例
 new Vue({
  el: &#39;#example&#39;,
  components: {
   &#39;parent&#39;: parentNode
  }
 })
</script>
로그인 후 복사

명명 규칙:

props로 선언된 속성의 경우 상위 HTML 템플릿에서 속성 이름은 대시로 작성해야 합니다.

하위 props 속성이 다음과 같은 경우 선언, 작은 카멜 케이스 또는 대시 사용 어떤 작성 방법이라도 허용됩니다. 하위 템플릿이 상위에서 전달된 변수를 사용하는 경우 해당 카멜 케이스를 사용해야 합니다.

위 문장은 무엇을 의미하나요?

<script>
 //这里需要注意的是props可以写成[&#39;my-message&#39;]或者[&#39;myMessage&#39;]都是可以的
 //但是template里的属性名,只能是驼峰式{{myMessage}},如果也写成{{my-message}}那么是无效的
 var childNode = {
  template: &#39;<p>{{myMessage}}</p>&#39;,
  props: [&#39;myMessage&#39;]
 }

 //这里的属性名为my-message
 var parentNode = {
  template: `
   <p class="parent">
   <child my-message="我是"></child>
   <child my-message="徐小小"></child>
   </p>`,
  components: {
   &#39;child&#39;: childNode
  }
 };
</script>
로그인 후 복사

childNode의 myMessage를 {{my-message}}로 변경하면 실행 결과를 확인하세요.

2. 동적 소품

템플릿에서 다음의 데이터를 동적으로 바인딩해야 합니다. 하위 템플릿에 대한 상위 구성 요소 Props는 v-bind를 사용하여 일반 HTML 기능에 바인딩됩니다. 상위 구성 요소의 데이터가 변경될 때마다 변경 내용이 하위 구성 요소에도 전송됩니다

 var childNode = {
  template: &#39;<p>{{myMessage}}</p>&#39;,
  props: [&#39;my-message&#39;]
    }

 var parentNode = {
  template: `
 <p class="parent">
 <child :my-message="data1"></child>
 <child :my-message="data2"></child>
 </p>`,
  components: {
   &#39;child&#39;: childNode
  },
  data() {
   return {
    &#39;data1&#39;: &#39;111&#39;,
    &#39;data2&#39;: &#39;222&#39;
   }
  }
 };
로그인 후 복사

3. 숫자 전달

초보자가 흔히 범하는 실수는 리터럴 구문을 사용하여 값을 전달하는 것입니다

<script src="https://unpkg.com/vue"></script>
<p id="example">
 <parent></parent>
</p>
<script>
 var childNode = {
  template: &#39;<p>{{myMessage}}的类型是{{type}}</p>&#39;,
  props: [&#39;myMessage&#39;],
  computed: {
   type() {
    return typeof this.myMessage
   }
  }
 }
 var parentNode = {
  template: `
 <p class="parent">
 <my-child my-message="1"></my-child>
 </p>`,
  components: {
   &#39;myChild&#39;: childNode
  }
 };
 // 创建根实例
 new Vue({
  el: &#39;#example&#39;,
  components: {
   &#39;parent&#39;: parentNode
  }
 })
</script>
로그인 후 복사

결과:

리터럴 prop이므로 해당 값은 숫자 대신 문자열 "1"입니다. 실제 숫자를 전달하려면 해당 값이 JS 표현식으로 계산되도록 v-bind를 사용해야 합니다.

문자열을 숫자로 변환하는 방법 실제로 한 곳만 변경하면 됩니다.

 var parentNode = {
  template: `
 <p class="parent">
 //只要把父组件my-message="1"改成:my-message="1"结果就变成number类型
 <my-child :my-message="1"></my-child>
 </p>`,
 };
로그인 후 복사

물론, v-bind를 통해 문자열 유형을 전달하려면 어떻게 해야 할까요?

동적 props를 사용하고 데이터 속성에 해당 숫자 1을 설정할 수 있습니다

var parentNode = {
 template: `
 <p class="parent">
 <my-child :my-message="data"></my-child>
 </p>`,
 components: {
 &#39;myChild&#39;: childNode
 },
 //这里&#39;data&#39;: 1代表就是number类型,&#39;data&#39;: "1"那就代表String类型
 data(){
 return {
  &#39;data&#39;: 1
 }
 }
};
로그인 후 복사

3. 하위에서 상위로: $emit $emit의 사용법에 대해

1. 상위 구성 요소는 소품을 사용하여 하위 구성 요소에 데이터를 전달할 수 있습니다.

2. 하위 구성 요소는 $emit를 사용하여 상위 구성 요소의 사용자 정의 이벤트를 트리거할 수 있습니다.


하위 기본 키

<template> 
 <p class="train-city"> 
 <span @click=&#39;select(`大连`)&#39;>大连</span> 
 </p> 
</template> 
<script> 
export default { 
 name:&#39;trainCity&#39;, 
 methods:{ 
 select(val) { 
  let data = { 
  cityname: val 
  }; 
  this.$emit(&#39;showCityName&#39;,data);//select事件触发后,自动触发showCityName事件 
 } 
 } 
} 
</script>
로그인 후 복사

상위 구성 요소

<template> 
 <trainCity @showCityName="updateCity" :index="goOrtoCity"></trainCity> //监听子组件的showCityName事件。 
<template> 
<script> 
export default { 
 name:&#39;index&#39;, 
 data () { 
 return { 
  toCity:"北京" 
 } 
 } 
 methods:{ 
 updateCity(data){//触发子组件城市选择-选择城市的事件 
  this.toCity = data.cityname;//改变了父组件的值 
  console.log(&#39;toCity:&#39;+this.toCity)  
 } 
 } 
} 
</script>
로그인 후 복사

결과는 다음과 같습니다. toCity: Dalian

두 번째 사례

<script src="https://unpkg.com/vue"></script>

 <p id="counter-event-example">
  <p>{{ total }}</p>
  <button-counter v-on:increment1="incrementTotal"></button-counter>
  <button-counter v-on:increment2="incrementTotal"></button-counter>
 </p>
<script>
 Vue.component(&#39;button-counter&#39;, {
  template: &#39;<button v-on:click="increment">{{ counter }}</button>&#39;,
  //组件数据就是需要函数式,这样的目的就是让每个button-counter不共享一个counter
  data: function() {
   return {
    counter: 0
   } 
  },
  methods: {
   increment: function() {
   //这里+1只对button的值加1,如果要父组件加一,那么就需要$emit事件
    this.counter += 1;
    this.$emit(&#39;increment1&#39;, [12, &#39;kkk&#39;]);
   }
  }
 });
 new Vue({
  el: &#39;#counter-event-example&#39;,
  data: {
   total: 0
  },
  methods: {
   incrementTotal: function(e) {
    this.total += 1;
    console.log(e);
   }
  }
 });
</script>
로그인 후 복사

상세 설명:

1: 버튼 카운터 상위 기본 키, 상위 기본 키에 버튼 버튼이 있습니다.

2: 두 버튼 모두 클릭 이벤트에 바인딩됩니다. this.$emit('increment1', [12, 'kkk']); 메서드에서 상위 클래스 v-on이 모니터링하는 increment1이 호출됩니다. 이벤트.

3: increment1 이벤트가 모니터링되면 incrementTotal이 실행됩니다. 이때 값이 상위 컴포넌트로 전달되고 상위 클래스의 메소드가 호출됩니다.

4: 여기에서 두 번째 버튼 카운터에 해당하는 v-on:'increment2에 주목하세요. 그 안에 있는 버튼은 이에 해당합니다.$emit('increment1', [12, 'kkk']) so 두 번째 버튼 버튼은 상위 기본 키에 값을 전달할 수 없습니다.

예: 버튼을 한 번 클릭하면 그 자체와 그 위의 버튼 모두 1씩 증가하지만, 두 번째 버튼은 그 자체만 증가하며 위의 버튼에는 영향을 주지 않습니다.

还有就是第一个按钮每点击一次,后台就会打印一次如下:

四、ref ($refs)用法

ref 有三种用法

1.ref 加在普通的元素上,用this.ref.name 获取到的是dom元素

2.ref 加在子组件上,用this.ref.name 获取到的是组件实例,可以使用组件的所有方法。

3.如何利用v-for 和ref 获取一组数组或者dom 节点

1.ref 加在普通的元素上,用this.ref.name 获取到的是dom元素

<script src="https://unpkg.com/vue"></script>

<p id="ref-outside-component" v-on:click="consoleRef">
 <component-father ref="outsideComponentRef">
 </component-father>
 <p>ref在外面的组件上</p>
</p>
<script>
 var refoutsidecomponentTem = {
  template: "<p class=&#39;childComp&#39;><h5>我是子组件</h5></p>"
 };
 var refoutsidecomponent = new Vue({
  el: "#ref-outside-component",
  components: {
   "component-father": refoutsidecomponentTem
  },
  methods: {
   consoleRef: function() {
    console.log(this.); // #ref-outside-component  vue实例
    console.log(this.$refs.outsideComponentRef); // p.childComp vue实例
   }
  }
 });
</script>
로그인 후 복사

效果:当在p访问内点击一次:

2.ref使用在外面的元素上

<script src="https://unpkg.com/vue"></script>

<!--ref在外面的元素上-->
<p id="ref-outside-dom" v-on:click="consoleRef">
 <component-father>
 </component-father>
 <p ref="outsideDomRef">ref在外面的元素上</p>
</p>
<script>
 var refoutsidedomTem = {
  template: "<p class=&#39;childComp&#39;><h5>我是子组件</h5></p>"
 };
 var refoutsidedom = new Vue({
  el: "#ref-outside-dom",
  components: {
   "component-father": refoutsidedomTem
  },
  methods: {
   consoleRef: function() {
    console.log(this); // #ref-outside-dom vue实例
    console.log(this.$refs.outsideDomRef); // <p> ref在外面的元素上</p>
   }
  }
 });
</script>
로그인 후 복사


效果:当在p访问内点击一次:

3.ref使用在里面的元素上---局部注册组件

<script src="https://unpkg.com/vue"></script>
<!--ref在里面的元素上-->
<p id="ref-inside-dom">
 <component-father>
 </component-father>
 <p>ref在里面的元素上</p>
</p>
<script>
 var refinsidedomTem = {
  template: "<p class=&#39;childComp&#39; v-on:click=&#39;consoleRef&#39;>" +
   "<h5 ref=&#39;insideDomRef&#39;>我是子组件</h5>" +
   "</p>",
  methods: {
   consoleRef: function() {
    console.log(this); // p.childComp vue实例 
    console.log(this.$refs.insideDomRef); // <h5 >我是子组件</h5>
   }
  }
 };
 var refinsidedom = new Vue({
  el: "#ref-inside-dom",
  components: {
   "component-father": refinsidedomTem
  }
 });
</script>
로그인 후 복사

效果:当在click范围内点击一次:

4.ref使用在里面的元素上---全局注册组件

<script src="https://unpkg.com/vue"></script>
<!--ref在里面的元素上--全局注册-->
<p id="ref-inside-dom-all">
 <ref-inside-dom-quanjv></ref-inside-dom-quanjv>
</p>
<script>
 //v-on:input指当input里值发生改变触发showinsideDomRef事件
 Vue.component("ref-inside-dom-quanjv", {
  template: "<p class=&#39;insideFather&#39;> " +
   "<input type=&#39;text&#39; ref=&#39;insideDomRefAll&#39; v-on:input=&#39;showinsideDomRef&#39;>" +
   " <p>ref在里面的元素上--全局注册 </p> " +
   "</p>",
  methods: {
   showinsideDomRef: function() {
    console.log(this); //这里的this其实还是p.insideFather
    console.log(this.$refs.insideDomRefAll); // <input type="text">
   }
  }
 });
 var refinsidedomall = new Vue({
  el: "#ref-inside-dom-all"
 });
</script>
로그인 후 복사

效果:当我第一次输入1时,值已改变出发事件,当我第二次在输入时在触发一次事件,所以后台应该打印两次

相关推荐:

基于vue-element组件实现音乐播放器功能

VUE-地区选择器(V-Distpicker)组件的使用

위 내용은 VueJs 컴포넌트의 부모-자식 통신 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿