コンポーネントとコンポーネント通信
- すべてのアプリケーションをコンポーネントツリーに抽象化できます
- コンポーネントの使用手順:
- コンポーネントコンストラクターを作成する
- 登録されたコンポーネント
- コンポーネントを使用する
<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都会变
コンポーネントは単一の機能モジュールです。カプセル化されたコンポーネントはインスタンスオブジェクトに直接アクセスできず、子コンポーネントは親コンポーネントのコンテンツに直接アクセスできません
#####親子コンポーネントの通信
-
注意:
- ページでは、サーバーに大量のデータを要求する必要がありますが、一部のデータは小さいコンポーネントに表示されますが、小さいコンポーネントはネットワーク要求を送信しませんが、大きいコンポーネントはデータを小さいコンポーネントに渡します
- 多くのネットワーク要求を送信すると、サーバーに大きなプレッシャーがかかるためです。
-
小道具:(プロパティの省略形、親から子)は型制限を実現でき、コードは次のとおりです
-
$ 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>
- 2番目のケース(双方向バインディングの理解と組み合わせて)
<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>