Table of contents
1. provide, inject dependency injection
2.directive custom instruction
3.plugin custom plugin install, app.use()
4 .teleport Hang some elements of the component directly on other dom elements
1. provide, inject dependency injection
When the parent component wants to pass parameters to the descendant components, it is cumbersome to define the props transfer layer by layer
<script>
const app = Vue.createApp({
data() {
return {
count: 1
}
},
template:`
<div>
<child :count="count"/>
</div>
`
})
app.component('child',{
props:['count'],
template:`
<div>
子组件{
{ count }}
<child-child :count="count"/>
</div>
`
})
app.component('child-child',{
props:['count'],
template: '<div>子-子组件{
{ count }}</div>'
})
const vm = app.mount('#root')
</script>
- provide / inject
- The parent component uses provide to pass parameters
- Subcomponents can be received using inject
- But when the parent component changes the parameters, the value of the child component will not change accordingly, because provide is a one-time delivery, not a two-way binding, and there are solutions for subsequent learning
<script>
const app = Vue.createApp({
data() {
return {
count: 1
}
},
provide() {
return {
count: this.count
}
},
template:`
<div>
父组件 {
{ count }}
<child />
<button @click="count++">+1</button> // 后代组件的 count 不会跟着改变
</div>
`
})
app.component('child',{
inject: ['count'],
template:`
<div>
子组件{
{ count }}
<child-child />
</div>
`
})
app.component('child-child',{
inject: ['count'],
template: '<div>子-子组件{
{ count }}</div>'
})
const vm = app.mount('#root')
</script>
2.directive custom instruction
<!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@3"></script>
<style>
.header{
position: absolute
}
</style>
</head>
<body>
<div id="root"></div>
</body>
<script>
// 局部自定义指令
const directives = {
focus: {
mounted(el) {
el.focus()
}
}
}
const app = Vue.createApp({
data() {
return {
distence: 100
}
},
directives: directives, // 局部自定义指令
template: `
<div>
<div class="header" v-pos:right="distence">
<input v-focus/>
</div>
</div>
`
});
// 全局指令
/* app.directive('pos', {
mounted(el, binding) {
el.style[binding.arg] = binding.value + 'px'
},
updated(el, binding) {
el.style[binding.arg] = binding.value + 'px'
},
}) */
// 以上写法可简化为:
app.directive('pos', (el, binding) => {
el.style[binding.arg] = binding.value + 'px'
})
const vm = app.mount('#root');
</script>
</html>
3.plugin custom plugin install, app.use()
- Encapsulate common performance
- app.config.globalProperties extended global properties (vue 3)
Can encapsulate provide, directive, mixin, etc.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>lesson 32</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="root"></div>
</body>
<script>
// 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');
</script>
</html>
Data validation plug-in development example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>lesson 33</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="root"></div>
</body>
<script>
// 对数据做校验的插件
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) => { //或是: install(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');
</script>
</html>
4 .teleport Hang some elements of the component directly on other dom elements
<!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@3"></script>
<style>
.area{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 200px;
height: 300px;
background-color: green;
}
.mask{
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
background-color: #000;
opacity: 0.5;
}
</style>
</head>
<body>
<div id="root"></div>
</body>
<script>
const app = Vue.createApp({
data() {
return {
show: false
}
},
template: `
<div>
<div class="area">
<button @click="show = !show">点击</button>
<teleport to="body">
<div v-show="show" class="mask"></div>
</teleport>
</div>
</div>
`,
created() {
console.log('app created')
},
mounted() {
},
methods: {
handleClick() {
console.log('app click')
}
}
});
const vm = app.mount('#root')
</script>
</html>
5. Non-Props feature
- If the parameters passed by the parent component are not received by the child component through props, then the parameters will be bound to the dom node of the child component
- Do not inherit the parameters passed by the parent component inheritAttrs: false
When to use the Non-Props feature?
Pass attributes such as style or class
When the child component has multiple root nodes, Non-Props is invalid, use $attrs to put all the attributes passed by the parent component on the current component
Get a certain attribute $attrs. attribute value
You can also use this.$attrs in other lifecycle functions or js methods
Do not inherit the parameters passed by the parent component inheritAttrs: false
- When to use the Non-Props feature?
Pass attributes such as style or class
When the child component has multiple root nodes, Non-Props is invalid, use $attrs to put all the attributes passed by the parent component on the current component
Get a certain attribute $attrs. attribute value
You can also use this.$attrs in other lifecycle functions or js methods