标签:类型 number 元素 绑定 目的 基本使用 required 简化 访问
将一个页面拆分成一个个小的功能块,每个功能块完成属于自己这部分独立的功能,从而简化整个页面的管理和维护,提高项目的扩展性,这样的流程称作组件化
<body>
<div id="app">
<!--step3.使用组件-->
<my-cpn></my-cpn>
</div>
<script src="../js/vue.js"></script>
<script>
/*
完整写法:
// step1.构建组件
const cpnC = Vue.extend({
template: `
<div>
<h2>我是标题</h2>
<p>我是内容, 哈哈哈哈</p>
<p>我是内容, 呵呵呵呵</p>
</div>`
})
// step2.注册组件
Vue.component(‘my-cpn‘, cpnC)
*/
// 语法糖
Vue.component(‘cpn1‘, {
template: `
<div>
<h2>我是标题1</h2>
<p>我是内容, 哈哈哈哈</p>
</div>
` //` ` 是es6的语法,和""功能类似,但是可以实现任意的换行,书写更为方便
})
//注意:组件的使用前提是该区域要被vue渲染
const app = new Vue({
el: ‘#app‘,
data: {
message: ‘你好啊‘
}
})
</script>
</body>
<body>
<div id="app">
<cpn></cpn>
</div>
<!--1.script标签, 注意:类型必须是text/x-template-->
<script type="text/x-template" id="cpn">
<div>
<h2>我是标题</h2>
<p>我是内容,哈哈哈</p>
</div>
</script>
<!--2.template标签(推荐)-->
<template id="cpn">
<div>
<h2>我是标题</h2>
<p>我是内容,呵呵呵</p>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
// 1.注册一个全局组件
Vue.component(‘cpn‘, {
template: ‘#cpn‘ //这里用一个#号绑定对象模板
})
const app = new Vue({
el: ‘#app‘,
data: {
message: ‘你好啊‘
}
})
</script>
</body>
<body>
<div id="app">
<cpn1></cpn1>
<cpn2></cpn2>
</div>
<div id="app2">
<cpn1></cpn1>
<cpn2></cpn2>
</div>
<script src="../js/vue.js"></script>
<script>
// 构造组件
const cpn1 = Vue.extend({
template: `
<div>
<h2>我是cpn1</h2>
</div>
`
})
// 构造组件
const cpn2 = Vue.extend({
template: `
<div>
<h2>我是cpn2</h2>
</div>
`
})
// 注册全局组件(全局组件, 意味着可以在多个Vue的实例下面使用)
Vue.component(‘cpn1‘, cpn1)
const app = new Vue({
el: ‘#app‘,
data: {
message: ‘你好啊‘
},
components: {
// cpn使用组件时的标签名
cpn2: cpn2
}
})
const app2 = new Vue({
el: ‘#app2‘
})
</script>
<body>
<div id="app">
<father></father>
</div>
<script src="../js/vue.js"></script>
<script>
const son = Vue.extend({
template: `
<div>
<h2>我是son</h2>
</div>
`
})
Vue.component(‘father‘, {
template: `
<div>
<h2>father</h2>
<p>我是father</p>
<son></son>
</div>
`,
components: {
son: son
}
})
// root组件(最外层的Vue实例也可以理解为一个父节点)
const app = new Vue({
el: ‘#app‘
})
</script>
</body>
<body>
<div id="app">
<cpn></cpn>
</div>
<template id="cpn">
<div>
<h2>{{title}}</h2>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
// 1.注册一个全局组件
Vue.component(‘cpn‘, {
template: ‘#cpn‘,
// 组件中也可以定义data对象,该对象以函数的形式存在,每个组件只可以访问自己的data数据,同一组件多次使用数据不共享
data() {
return {
title: ‘abc‘
}
}
})
const app = new Vue({
el: ‘#app‘,
data: {
message: ‘你好啊‘,
title: ‘Root‘
}
})
</script>
</body>
父传子基本原理 :借助props 传递数据
<body>
<div id="app">
<son :param1="param1" :param2="param2" :param3="param3"></son>
</div>
<template id="cpn">
<div>
<ul>
<li v-for="item in param2">{{item}}</li>
</ul>
<h2>{{param1}}</h2>
<h2>{{param3.name}}</h2>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
// 父传子: props
const son = {
template: ‘#cpn‘,
/* // 写法1
props: [‘param1‘, ‘param2‘, ‘param3‘],
// 写法2 可以提供类型限制
props: {
param1: String,
param2: Array,
param3: Object
},
*/
// 写法3 可以提供类型限制,默认值,是否必须 注意:型是数组或对象时, 默认值必须是一个函数
props: {
param1: {
type: String,
default: ‘yyyy‘,
required: true
},
param2: {
type: Array,
default() {
return []
}
},
param3: {
type: Object,
default() {
return []
}
}
},
data() {
return {}
},
methods: {}
}
const app = new Vue({
el: ‘#app‘,
data: {
param1: ‘xxx‘,
param2: [‘test1‘, ‘test2‘, ‘test3‘],
param3: {name: ‘wangshijia‘, age: 25}
},
components: {
son
}
})
</script>
</body>
子传父基本原理 :子组件中,通过$emit()来发射一个自定义事件。在父组件中,通过v-on来监听子组件事件。
<body>
<!--父组件模板-->
<div id="app">
<son @item-click="cpnClick"></son>
</div>
<!--子组件模板-->
<template id="son">
<div>
<button v-for="item in categories" @click="btnClick(item)">
{{item.name}}
</button>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
// 1.子组件
const son = {
template: ‘#son‘,
data() {
return {
categories: [
{id: ‘aaa‘, name: ‘热门推荐‘},
{id: ‘bbb‘, name: ‘手机数码‘},
{id: ‘ccc‘, name: ‘家用家电‘},
{id: ‘ddd‘, name: ‘电脑办公‘},
]
}
},
methods: {
btnClick(item) {
// 发射事件: 自定义事件
this.$emit(‘item-click‘, item)
}
}
}
// 2.父组件
const app = new Vue({
el: ‘#app‘,
data: {
message: ‘你好啊‘
},
components: {
son
},
methods: {
cpnClick(item) {
console.log(‘cpnClick‘, item);
}
}
})
</script>
</body>
解析: 一般情况下,父组件与子组件是单向绑定,即父组件的值改变,子组件中props改变 ,不建议之间修改props去改变父组件的值,这样会导致父子组件之间耦合度过高,可以使用发送自定义事件或的方式实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<son :father-to-son1="this.num1" @num1change="num1change"></son>
</div>
<template id="son">
<div>
<h2>fatherToSon1 :{{this.fatherToSon1}}</h2>
<h2>sonToFather1 :{{sonToFather1}}</h2>
<input type="text" :value="sonToFather1" @input="num1Input">
</div>
</template>
<script src="../js/vue.js"></script>
<script>
const son = {
template: ‘#son‘,
props: {
fatherToSon1: Number
},
data() {
return {
sonToFather1: this.fatherToSon1
}
},
methods: {
num1Input(event) {
this.sonToFather1 = event.target.value;
this.$emit(‘num1change‘, this.sonToFather1)
}
}
}
const app = new Vue({
el: ‘#app‘,
data: {
num1: 100
},
methods: {
num1change(value) {
this.num1 = parseFloat(value)
}
},
components: {son}
}
)
</script>
</body>
</html>
<body>
<div id="app">
<son :father-to-son1="num1" @num1change="num1change"></son>
</div>
<template id="son">
<div>
<h2>props:{{fatherToSon1}}</h2>
<h2>data: {{sonToFather1}}</h2>
<input type="text" v-model="sonToFather1">
</div>
</template>
<script src="../js/vue.js"></script>
<script>
const son = {
template: ‘#son‘,
props: {
fatherToSon1: Number
},
data() {
return {
sonToFather1: this.fatherToSon1
}
},
watch: {
sonToFather1(newValue) {
this.$emit(‘num1change‘, newValue);
}
}
}
const app = new Vue({
el: ‘#app‘,
data: {
num1: 1
},
methods: {
num1change(value) {
this.num1 = parseFloat(value)
}
},
components: {son}
})
</script>
</body>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<cpn></cpn>
<cpn></cpn>
<my-cpn></my-cpn>
<y-cpn></y-cpn>
<cpn ref="aaa"></cpn>
<button @click="btnClick">按钮</button>
</div>
<template id="cpn">
<div>我是子组件</div>
</template>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: ‘#app‘,
data: {
message: ‘你好啊‘
},
methods: {
btnClick() {
// 1.$children
// console.log(this.$children);
// for (let c of this.$children) {
// console.log(c.name);
// c.showMessage();
// }
// console.log(this.$children[3].name);
// 2.$refs => 对象类型, 默认是一个空的对象 ref=‘bbb‘
console.log(this.$refs.aaa.name);
}
},
components: {
cpn: {
template: ‘#cpn‘,
data() {
return {
name: ‘我是子组件的name‘
}
},
methods: {
showMessage() {
console.log(‘showMessage‘);
}
}
},
}
})
</script>
</body>
</html>
Slot 翻译为插槽 , 可以理解为电脑中的USB插槽 或是插排中的电源插槽 ,作用是放在组件中以使得组件拥有更多的扩展性
1.插槽的基本使用
2.插槽的默认值button
3.如果有多个值, 同时放入到组件进行替换时, 一起作为替换元素
<body>
<div id="app">
<cpn><i>按钮</i></cpn>
<cpn></cpn>
</div>
<template id="cpn">
<div>
<h2>组件</h2>
<slot><button>按钮</button></slot>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: ‘#app‘,
data: {
message: ‘你好啊‘
},
components: {
cpn: {
template: ‘#cpn‘
}
}
})
</script>
</body>
当一个组件中存在多个插槽时,需要使用具名插槽加以区分
<body>
<div id="app">
<cpn><span slot="center">中间</span></cpn>
<cpn><span slot="left">左边</span></cpn>
<cpn><span slot="right">右边</span></cpn>
</div>
<template id="cpn">
<div>
<slot name="left"></slot>
|
<slot name="center"></slot>
|
<slot name="right"></slot>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: ‘#app‘,
data: {
message: ‘你好啊‘
},
components: {
cpn: {
template: ‘#cpn‘
}
}
})
</script>
</body>
Vue 编译准则:父组件模板的所有东西都会在父级作用域内编译;子组件模板的所有东西都会在子级作用域内编译 也就是说父组件给子组件赋值时,只能使用父组件的数据,但有时候我们可以希望插槽中的值由子组件提供,这是就需要使用作用域插槽
<body>
<div id="app">
<cpn></cpn>
<cpn>
<template slot-scope="cslot">
<span>{{cslot.cdata.join(‘ - ‘)}}</span>
</template>
</cpn>
<cpn>
<template slot-scope="cslot">
<span>{{cslot.cdata.join(‘ * ‘)}}</span>
</template>
</cpn>
</div>
<template id="cpn">
<div>
<slot :cdata="pLanguages"></slot>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: ‘#app‘,
data: {
message: ‘你好啊‘
},
components: {
cpn: {
template: ‘#cpn‘,
data() {
return {
pLanguages: [‘JavaScript‘, ‘C++‘, ‘Java‘, ‘C#‘, ‘Python‘, ‘Go‘, ‘Swift‘]
}
}
}
}
})
</script>
</body>
标签:类型 number 元素 绑定 目的 基本使用 required 简化 访问
原文地址:https://www.cnblogs.com/wangshijia/p/14509170.html