<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>
<!-- 模板组件抽离写法 -->
<div id="app1">
<cpn1></cpn1>
<cpn2></cpn2>
</div>
<!-- 方法一 -->
<script type="text/x-template" id="cpn1">
<div>
<p>一:我分离出来了</p>
<p>一:我分离出来了</p>
</div>
</script>
<!-- 方法二 -->
<template id="cpn2">
<div>
<p>二:我分离出来了</p>
<p>二:我分离出来了</p>
</div>
</template>
<script>
Vue.component('cpn1',{
template: '#cpn1'
})
Vue.component('cpn2',{
template: '#cpn2'
})
const app1 = new Vue({
el: '#app1'
})
</script><hr>
<!--
组件的数据存放问题
1. 组件无法访问Vue实例中的data
2. 组件对象也有一个data属性(也可以有methods等属性)
3. 该data属性必须是一个函数,且这个函数返回一个对象,对象内保存着数据
-->
<div id="app2">
<cpn3></cpn3>
</div>
<template id="cpn3">
<div>
<p>动态绑定数据:{{msg}}</p>
<p>动态绑定数据:{{msg}}</p>
</div>
</template>
<script>
Vue.component('cpn3',{
template: '#cpn3',
data() {
return {
msg: '我是动态数据'
}
}
})
const app2 = new Vue({
el: '#app2'
})
</script><hr>
<!--
父子组件通信
子组件是不能引用父组件或者Vue实例的数据的,但开发中常常需要一些数据从上层传递到下层
比如在一个页面中,我们从服务器请求到了很多数据,其中一部分数据并不是由整个页面的大组件展示
而是需要下面的子组件进行展示,这时候就需要让大组件(父组件)将数据传递给小组件(子组件)
-->
<!-- 父传子:Pass props -->
<div id="app3">
<cpn4 v-bind:cpeople="people" :cmsg="msg" :cdemo="demo"></cpn4>
</div>
<template id="cpn4">
<div>
<p>人物数组:{{cpeople}}</p>
<p>msg对象:{{cmsg}}</p>
<p>demo对象:{{cdemo}}</p>
</div>
</template>
<script>
const cpn4 = {
template: '#cpn4',
// props: ['cpeople'] 使用一:不进行类型限制
props: {
// 使用二:进行类型限制
cpeople: Array,
cmsg: String,
cdemo: {
type: Object,
default: { // 还可以添加默认值
name: "小王",
age: 18
},
required: true // 设置为必传
}
}
}
// Vue环境(根组件)
const app3 = new Vue({
el: '#app3',
data: {
people: ['张三','李四','王五','赵六'],
msg:{
name: '麻子',
weight: "120斤"
},
demo:{
name:"小李",
age: 19
}
},
components: {
cpn4
}
})
</script><hr>
<!--
子传父
当子组件需要向父组件传递事件时,就要用到自定义事件
之前学习的 v-on 不仅可以用来监听DOM事件,也可以用于监听组件间的自定义事件
自定义事件流程:
在子组件中,通过
-->
<!-- 父组件模板 -->
<div id="app4">
<cpn5 @itemclick="cpnClick"></cpn5>
</div>
<!-- 子组件模板 -->
<template id="cpn5">
<div>
<button v-for='item in categories' @click="btnClick(item)">{{item.name}}</button>
</div>
</template>
<script>
// 1. 子组件
const cpn5 = {
template: '#cpn5',
data() {
return {
categories: [
{id: 'aaa', name: '热门推荐'},
{id: 'bbb', name: '手机数码'},
{id: 'ccc', name: '家具家电'},
{id: 'ddd', name: '电脑办公'}
]
}
},
methods: {
btnClick: function(item) {
// $emit('发送给父组件的事件')
this.$emit('itemclick')
}
}
}
// 2. 父组件
const app4 = new Vue({
el: '#app4',
data: {
},
components: {
cpn5
},
methods: {
cpnClick() {
console.log('cpnClick');
}
}
})
</script><hr>
<!-- 父子组件通信--双向绑定 -->
<div id="app5">
<cpn6 :number1="num1"
:number2="num2"
@num1change="num1change"
@num2change="num2change"/>
</div>
<template id="cpn6">
<div>
<p>props:{{number1}}</p>
<p>data:{{dnumber1}}</p>
<!-- <input type="text" v-model="dnumber1"> -->
<input type="text" :value="dnumber1" @input="num1Input">
<p>props:{{number2}}</p>
<p>data:{{dnumber2}}</p>
<!-- <input type="text" v-model="dnumber2"> -->
<input type="text" :value="dnumber2" @input="num2Input">
</div>
</template>
<script>
const app5 = new Vue({
el: '#app5',
data: {
num1: 1,
num2: 0
},
methods: {
num1change(value) {
// console.log(typeof value); 默认传字符串类型
this.num1 = parseInt(value); // 转换为数字类型
},
num2change(value) {
// console.log(typeof value);
this.num2 = parseInt(value);
}
},
components: {
cpn6: {
template: '#cpn6',
props: {
number1: Number,
number2: Number
},
data() {
return {
dnumber1: this.number1,
dnumber2: this.number2
}
},
methods: {
num1Input(event) {
this.dnumber1 = event.target.value;
this.$emit('num1change',this.dnumber1)
},
num2Input(event) {
this.dnumber2 = event.target.value;
this.$emit('num2change',this.dnumber2)
},
}
}
}
})
</script>
</body>
</html>
更多相关内容大家可以前往我的个人博客浏览:eyes++的个人空间