구성 요소 및 구성 요소 통신
- 모든 응용 프로그램은 구성 요소 트리로 추상화 될 수 있습니다.
- 구성 요소 사용 단계 :
- 구성 요소 생성자 만들기
- 등록 된 구성 요소
- 구성 요소 사용
<div id="app"><!--注意这是vue的作用范围-->
<my-cpn></my-cpn><!--使用组件-->
</div>
<script src="../practice/vue.js"></script>
<script>
//1、创建组件构造器对象,与创建vue对象一样也需要传入一个对象作为参数
const cpnC = Vue.extend({
template: ` <div id="app">
<h2>蔡蔡</h2>
<p>你好</p>
<p>水果</p>
</div>`
})
//2.注册组件,Vue.component("定义的组件名字",组件构造器)
Vue.component("my-cpn",cpnC)
const app = new Vue({
el: "#app",
data: {
message: "嘿嘿"
}
})
</script>
전역 구성 요소 및 로컬 구성 요소
- 전역 구성 요소는 여러 vue 인스턴스에서 사용할 수 있고 로컬 구성 요소는 vue 인스턴스 개체에 구성 요소 속성을 추가하며 다른 인스턴스는이를 사용할 수 없음을 의미합니다.
부모 및 자식 구성 요소
- 예:
<body>
<div id="app">
<!-- <cpn1></cpn1> 直接输出这个会报错因为该组件不是在全局VUe注册的也不是在app这个域内注册的-->
<cpn2></cpn2>
</div>
<script src="./vue.js"></script>
<script>
//创建第一个组件构造器(子组件)
const cpnc1 = Vue.extend({
template: ` <div>
<h2>我是标题1</h2>
<p>我是内容1</p>
</div>`
})
//创建第二个组件构造器(父组件)
const cpnc2 = Vue.extend({
template: `<div>
<h2>我是标题2</h2>
<p>我是内容2</p>
<cpn1></cpn1>
</div>`,
components:{
cpn1:cpnc1
}
//组件一在组件2中注册的,组件2在vue实例中注册的
})
const app=new Vue({
el:"#app",
data:{
message:"你好"
},
components:{
cpn2:cpnc2
}
})
</script>
</body>
- 템플릿 템플릿 별도 작성
- 스크립트 태그를 사용하십시오.
<script type="text/x-template" id="mycpn"> 用的时候在component属性里面的template:"#mycpn"
- 템플릿 태그 사용
<template id="mycpn">
- 스크립트 태그를 사용하십시오.
- 구성 요소의 데이터 (구성 요소의 데이터가 분리됨)
- 구성 요소는 실제로 vue 인스턴스와 매우 유사합니다.
- 데이터 속성 인 data () {}는 객체를 반환하는 함수입니다.
<div id="app">
<cpn></cpn>
</div>
<template id="cpn">
<div>
<h2>
当前计数:{
{cnt}}
</h2>
<button @click=incre()>+</button>
<button @click=decre()>-</button>
</div>
</template>
<script src="../practice/vue.js"></script>
<script>
Vue.component('cpn',{
template:'#cpn',
data(){
return{
cnt:0
}
},
methods:{
incre(){
this.cnt++
},
decre(){
this.cnt--
}
}
})
const app=new Vue({
el:"#app",
data:{
message:'嘿嘿'
}
})
</script>
- 따라서 컴포넌트의 데이터는 위의 카운터 예제와 같이 함수 (vue 인스턴스의 데이터가 객체 임)입니다. 함수 인 경우 각 페이지가 해당 카운터 컴포넌트를 호출 할 때마다 새로운 cnt 객체가 생성됩니다. 각 페이지 카운터 구성 요소의 데이터 개체가 다릅니다.
但是如果这个时候的组建的data是一个对象而不是一个函数的话,一个页面点击了按钮,所有用这个组件的cnt都会变
구성 요소는 단일 기능 모듈입니다. 캡슐화 된 구성 요소는 인스턴스 개체에 직접 액세스 할 수 없으며 자식 구성 요소는 부모 구성 요소의 내용에 직접 액세스 할 수 없습니다.
##### Parent-child 구성 요소 통신
-
노트:
- 페이지에서 서버에 많은 데이터를 요청해야하지만 일부 데이터는 작은 구성 요소에 표시되지만 작은 구성 요소는 네트워크 요청을 보내지 않지만 큰 구성 요소는 데이터를 작은 구성 요소로 전달합니다.
- 많은 네트워크 요청을 보내면 서버에 많은 부담을 주므로
-
props : (속성의 약어, 부모에서 자식으로) 유형 제한을 달성 할 수 있습니다. 코드는 다음과 같습니다.
-
$ emit 이벤트 : (하위에서 부모로)
-
주의 사항 :
- vue 인스턴스 자체는 상위 구성 요소로 간주 될 수 있습니다.
- 하위 구성 요소는 상위 구성 요소의 데이터를 직접 참조 할 수 없습니다.
-
-
프로세스 이해 : 하위 구성 요소가 상위 구성 요소에 무언가를 전달하려는 경우 이벤트를 내 보냅니다.이 이벤트 유형은 사용자 정의해야합니다. 상위 구성 요소의 템플릿이 사용자 정의 태그를 사용하는 경우 이벤트를 수신합니다. 수신 후 이동 메서드 또는 부모 구성 요소에. 다른 곳에서 이벤트를 처리하십시오.
-
케이스
- 첫 번째 작은 경우 (하지만 코드 구조는 약간 지저분하며 다음 파일은 템플릿, JS 코드 및 스타일로 더 표준화되었습니다. Vue 파일)
<body>
<!--父组件的模板-->
<div id="app">
<cpn @itemclick="cpnclick"></cpn>
<!-- 浏览器默认的事件对象会传入event但是如果不是的话会自动传入自己的设置的那个参数此处即是event -->
</div>
<!--子组件的模板-->
<template id="cpn">
<div>
<button v-for="item in catego" @click="btnclick(item)">{
{item.name}}</button>
<!-- 存储类别父组件根据点击的子对象去请求相对应的数据 -->
</div>
</template>
<script src="./vue.js"></script>
<script>
const cpn = {
template: "#cpn",
data() {
return {
catego: [{
id: 1,
name: "热门推荐"
}, {
id: 2,
name: "排行榜"
}, {
id: 3,
name: "歌单"
}, {
id: 4,
name: "数字专辑"
}]
}
},
methods:{
btnclick(item){
// console.log(item);
this.$emit("itemclick",item)
}//自定义事件类型点击拿到对应子对象通过发射出去给父组件该事件并且传递参数
}
}
const app = new Vue({
el: "#app",
data: {
message: "app1"
},
components:{
cpn:cpn
},
methods:{
cpnclick(item){
console.log('cpnclick',item);
}
}
})
</script>
</body>
- 두 번째 경우 (양방향 바인딩 이해와 결합)
<body>
<div id="app">
<cpn :number1="num1" :number2="num2" @num1change="num1change" @num2change="num2change"/>
</div>
<template id="cpn">
<div>
<h2>props:{
{number1}}</h2>
<h2>data:{
{dnumber1}}</h2>
<!-- <input type="text" v-model="dnumber1"> -->
<input type="text" :value="dnumber1" @input="num1input">
<h2>props:{
{number2}}</h2>
<h2>data:{
{dnumber2}}</h2>
<!-- 两种进行比较,要修改的数据一定要放进data函数里面 -->
<!-- <input type="text" v-model="dnumber2"> -->
<input type="text" :value="dnumber2" @input="num2input">
</div>
</template>
<script src="./vue.js"></script>
<script>
const app=new Vue({
el:'#app',
data:{
num1:1,
num2:0//也可以改变父组件中这个值
},
methods: {
num1change(value){
this.num1=parseFloat(value)
//默认情况转换成string类型所以要进行转化用parse系列方法
},
num2change(value){
this.num2=parseFloat(value)
}
},
components:{
cpn:{
template:'#cpn',
props: {
number1:Number,
number2:Number
},
data(){
return {
dnumber1:this.number1,
dnumber2:this.number2
}//展示可以直接展示,但是如果要修改数据一定要放到data里面
},
methods:{
num1input(){
this.dnumber1=event.target.value;
this.$emit('num1change',this.dnum1)
},
num2input(){
this.dnumber2=event.target.value;
this.$emit('num1change',this.dnum1)
//将数据的改变进行传输回去给num1 num2
}
}
}
}
})
</script>
</body>