04 Vue 高级语法
loyalvi Lv7

04 Vue高级语法

mixin 混入

局部的mixin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// mixin 混入
// 组件 data, methods 优先级高于 mixin data, methods 优先级
// 生命周期函数,先执行 mixin 里面的,再执行组件里面的
// 子组件要使用mixin的值,仍然需要载入
const myMixin = {
number: 1
}
const app = Vue.createApp({
mixins: [myMixin],
number: 2,
template: `
<div>
<div>{{this.$options.number}}</div>
</div>
`
});

全局mixin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
const myMixin = {
number: 1
}
const app = Vue.createApp({
data(){
returen{
number:2
}
},
template: `
<div>
<div>{{number}}</div>
</div>
`
});
app.mixin({
data(){
returen{
number:1
}
},
})

自定义属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 自定义的属性,组件中的属性优先级高于 mixin 属性的优先级
const myMixin = {
number: 1
}
const app = Vue.createApp({
mixins: [myMixin],
number: 2,
template: `
<div>
<div>{{this.$options.number}}</div>
</div>
`
});
// 自定义属性的优先级修改
app.config.optionMergeStrategies.number = (mixinVal, appValue) => {
return mixinVal || appValue;
}

自定义指令directive

局部和全局类比mixin

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
// 自定义指令 directive
const app = Vue.createApp({
data() {
return {
distance: 110
}
},
template: `
<div>
<input v-focus />
</div>
`
});
app.directive('focus', () => {
//在实例生成之前
beforeCreate(){
},
//在实例生成之后
created(){
},
//在组件内容被渲染到页面之前
beforeMount(){
},
//在组件内容被渲染到页面之后
mounted(){
},
//当数据发生变化时
beforeUpdate(){
},
})
const vm = app.mount('#root');
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 自定义指令 directive
const app = Vue.createApp({
data() {
return {
distance: 110
}
},
template: `
<div>
<div v-pos:right="distance" class="header">
<input />
</div>
</div>
`
});
app.directive('pos', (el, binding) => {
el.style[binding.arg] = (binding.value + 'px');
})
//上下等价
app.directive('pos', {
mounted(el, binding){ el.style[binding.arg] = (binding.value + 'px');},
updated(el, binding){ el.style[binding.arg] = (binding.value + 'px');},
})
const vm = app.mount('#root');

传送门teleport

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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title></title>
<style>
.area {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 200px;
height: 300px;
background: green;
}
.mask {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
background: #000;
opacity: 0.5;
color: #fff;
font-size: 100px;
}
</style>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="root"></div>
<div id="hello"></div>
</body>
<script>
// teleport 传送门
const app = Vue.createApp({
data() {
return {
show: false,
message: 'hello'
}
},
methods: {
handleBtnClick() {
this.show = !this.show;
}
},
template: `
<div class="area">
<button @click="handleBtnClick">按钮</button>
<teleport to="#hello">
<div class="mask" v-show="show">{{message}}</div>
</teleport>
</div>
`
});
const vm = app.mount('#root');
</script>
</html>

render

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// render function
// template -> render -> h -> 虚拟DOM(JS对象)-> 真实 DOM -> 展示到页面上
const app = Vue.createApp({
template: `
<my-title :level="2">
hello dell
</my-title>
`
});
app.component('my-title', {
props: ['level'],
render() {
const { h } = Vue;
return h('h' + this.level, {}, [
this.$slots.default(),
h('h4', {}, 'dell')
])
}
})

插件的定义和使用 plugin

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
// plugin 插件, 也是把通用性的功能封装起来
const myPlugin = {
install(app, options) {
app.provide('name', 'Dell Lee');
app.directive('focus', {
mounted(el) {
el.focus();
}
})
app.mixin({
mounted(){
console.log('mixin')
}
})
app.config.globalProperties.$sayHello = 'hello world';
}
}
const app = Vue.createApp({
template: `
<my-title />
`
});
app.component('my-title', {
inject: ['name'],
mounted() {
console.log(this.$sayHello);
},
template: `<div>{{name}}<input v-focus /></div>`
})
app.use(myPlugin, { name: 'dell'});
const vm = app.mount('#root');

数据校验插件实战

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
// 对数据做校验的插件
const app = Vue.createApp({
data() {
return { name: 'dell', age: 23}
},
rules: {
age: {
validate: age => age > 25,
message: 'too young, to simple'
},
name: {
validate: name => name.length >= 4,
message: 'name too short'
}
},
template: `
<div>name:{{name}}, age:{{age}}</div>
`
});
const validatorPlugin = (app, options) => {
app.mixin({
created() {
for(let key in this.$options.rules) {
const item = this.$options.rules[key];
this.$watch(key, (value) => {
const result = item.validate(value);
if(!result) console.log(item.message);
})
}
}
})
}
app.use(validatorPlugin);
const vm = app.mount('#root');
由 Hexo 驱动 & 主题 Keep
访客数 访问量