HOME
HOME
文章目录
  1. 1. filter/map/reduce
  2. 2. v-model
  3. 3. 组件化
  4. 4. slot插槽

vue2学习笔记2

1. filter/map/reduce

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const nums = [1, 2, 4, 10, 15, 20, 200, 40, 300]

// filter:过滤函数
// filter回调函数必须返回一个boolean类型的值
// 返回true: 将回调的n参数加入到新的数组中
let result = nums.filter(function(n){
if (n % 2 === 0){
return true
}
})

//map: 根据规则生成新的数组
let result = nums.map(function(n){
return n*2
})

//reduce: 对数组中所有内容进行汇总, preValue为上一次函数的返回值,初始值为reduce的第二个参数,可省略默认为0
let result = nums.reduce(function(preValue, n){
return preValue+n
}, 0)

2. v-model

表单绑定,实现表单元素和数据的双向绑定

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<div id="app">
<input type="text" v-model="message">
<input type="text" :value="message" @input="message=$event.target.value"> // v-bind加事件实现双向绑定
{{message}}
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
message: 'test'
}
})
</script>

绑定radio控件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<div id="app">
<label for="male">
<input type="radio" id="male" name="gender" v-model="gender" value="男">
</label>
<label for="female">
<input type="radio" id="female" name="gender" v-model="gender" value="女">
</label>
{{gender}}
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
gender: ''
}
})
</script>

修饰符

lazy:懒加载,失焦的时候或者回车的时候,才更新变量

<input type="text" v-model.lazy="message">

number:对输入的类型限定为数字

trim:对输入的内容去除空格

3. 组件化

使用组件的步骤

  1. 创建组件构造器:Vue.extend()
  2. 注册组件:Vue.component()
  3. 使用组件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<div id="app">
<my-cpn></my-cpn>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>

const cpn = Vue.extend({
template: `<div>
<h2>标题</h2>
<p>内容</p>
</div>`
})
Vue.component('my-cpn', cpn) // 全局组件
let app = new Vue({
el: '#app',
components: { // 注册局部组件
cpn2: cpn
}
});

</script>

父组件和子组件

在父组件中的components中定义子组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<div id="app">
<cpn></cpn>
<cpn2></cpn2>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const cpn1 = Vue.extend({
template: `
<div>
<h1>标题1</h1>
<p>内容1</p>
</div>
`
})
const cpn2 = Vue.extend({
template: `
<div>
<h1>标题2</h1>
<p>内容2</p>
<cpn1></cpn1>
</div>
`,
components: {
cpn1: cpn1 // cpn2父组件中定义cpn1子组件
}
})
let app = new Vue({
el: '#app',
components: {
cpn2: cpn2,
}
});

</script>

语法糖写法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<div id="app">
<my-cpn></my-cpn>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>

Vue.component('my-cpn', {
template: `<div>
<h2>标题</h2>
<p>内容</p>
</div>`
})
let app = new Vue({
el: '#app',
});

</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<div id="app">
<my-cpn></my-cpn>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
components: {
cpn2: {
template: `<div>
<h2>标题</h2>
<p>内容</p>
</div>`
}
}
});

</script>

模板分离

text/x-template或者直接template标签

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<div id="app">
<cpn></cpn>
<cpn2></cpn2>
</div>
<script type="text/x-template" id="mycpn">
<div>
<h2>标题</h2>
<p>内容</p>
</div>
</script>
<template id="mycpn2">
<div>
<h2>标题2</h2>
<p>内容2</p>
</div>
</template>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
components: {
cpn: {
template: '#mycpn'
},
cpn2: {
template: '#mycpn2'
}
}
});
</script>

组件数据存放

data属性,但必须是一个函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<template id="mycpn2">
<div>
<h2>标题2</h2>
<p>{{message}}</p>
</div>
</template>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
components: {
cpn2: {
template: '#mycpn2',
data(){ // 必须是一个函数,返回一个对象,函数新分配一个内存空间,组件之间的值不会相互干扰
return {
message: 'testme'
}
}
}
}
});
</script>

组件通信

父组件向子组件传值使用:props

子组件向父组件传值使用:$emit events

父组件传值,通过v-bind读取父组件的值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<div id="app">
<cpn2 :cmovies="movies" :cmessage="message"></cpn2>
</div>
<template id="mycpn2">
<div>
<h2>标题2</h2>
<p>{{cmessage}}</p>
<ul v-for="item in cmovies">
<li>{{item}}</li>
</ul>
</div>
</template>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const cpn = {
template: '#mycpn2',
props: ['cmovies', 'cmessage'],
props: { // 类型限制
cmovies: Array,
cmessage: String
}
props: { // 类型和默认值
cmovies: {
type: String,
default: '123',
required: true
}
}
}

let app = new Vue({
el: '#app',
components: {
cpn2: cpn
},
data: {
movies: ['test1', 'test2', 'test3', 'test4'],
message: '父组件数据'
}
});
</script>

子组件向父组件传递

通过$emit发送事件的方式传递

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<div id="app">
<cpn2 @itemclick="cpnclick"></cpn2>
</div>
<template id="mycpn2">
<div>
<button v-for="item in categories" @click="btnClick(item)">{{item.name}}</button>
</div>
</template>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const cpn = {
template: '#mycpn2',
data(){
return{
categories: [
{id: 'aaa', name: 'test1'},
{id: 'bbb', name: 'test2'},
{id: 'ccc', name: 'test3'},
]
}
},
methods: {
btnClick(item){
this.$emit('itemclick', item)
}
}
}

let app = new Vue({
el: '#app',
components: {
cpn2: cpn
},
methods: {
cpnclick(item){
console.log('父组件收到')
console.log(item)
}
}

});
</script>

父子组件双向绑定

props的属性只能从父组件传过来,不能在子组件进行model绑定

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<template id="counter">
<div>
props: {{number1}}<br>
data: {{cnumber1}}<br>
<input type="text" v-model="cnumber1" @input="update"><br>
props: {{number2}}<br>
data: {{cnumber2}}<br>
<input type="text" v-model="cnumber2">

</div>
</template>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
num1: 0,
num2: 1
},
methods: {
updatefather(num){
this.num1 = num
}
},
components: {
cpn: {
template: '#counter',
props: {
number1: String,
number2: String
},
data(){
return{
cnumber1: this.number1,
cnumber2: this.number2
}
},
methods: {
update(event){
this.$emit('updatefather', event.target.value)
}
}
}
}
});
</script>

监听某个值的改变,可以直接用watch方法

父子组件互相访问

父组件访问子组件:使用$children或者$ref

子组件访问父组件:使用$parent

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<div id="app">
<cpn></cpn>
<cpn ref="aaa"></cpn>
<button @click="btnClick">按钮</button>
</div>
<template id="cpn">
<div>
子组件
</div>
</template>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
methods: {
btnClick() {
this.$children[0].showMessage()
this.$refs['aaa'].showMessage()
this.$refs.aaa.showMessage()
}
},
components: {
cpn: {
template: '#cpn',
methods: {
showMessage(){
console.log('show message')
}
}
}
}
});
</script>

4. slot插槽

组件的插槽为了让封装的组件更具有扩展性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<div id="app">
<cpn><button>按钮</button></cpn>
<cpn><span>span标签</span></cpn>
<cpn></cpn>
</div>
<template id="cpn">
<div>
<div>子组件</div>
<slot><button>默认按钮</button></slot>
</div>
</template>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
components: {
cpn: {
template: '#cpn'
}
}
});
</script>

具名插槽

1
2
3
<slot name='left'></slot>
替换方法:
<cpn><span slot='left'>testme</span></cpn>

作用域插槽

父组件替换插槽的标签,但是内容由子组件来提供

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<div id="app">
<cpn></cpn>
<cpn>
<template slot-scope="slot">
<span v-for="item in slot.data">{{item}}</span> // 数据在子组件中,但是该标签的作用域在父组件里面,需要将内容传递过来
</template>
</cpn>
</div>
<template id="cpn">
<div>
<slot :data="pLanguage">
<ul>
<li v-for="item in pLanguage">{{item }}</li>
</ul>
</slot>
</div>

</template>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
components: {
cpn: {
template: '#cpn',
data(){
return{
pLanguage: ['test1', 'test2', 'test3']
}
}
}
}
});
</script>