18Vue-高级语法补充

认识自定义指令

图片.png

图片.png

图片.png
页面加载完成后,input框默认获取焦点
自定义指令不能再setup中写,全局自定义指令用的更多

默认实现方式一
App.vue

这里要想通过ref拿到input框的步骤:
1.先给input框绑定 ref = "input"
2.在setup中初始化,必须也叫input:const input = ref(null)
这样后续就会自动绑定了
<template>
//ref的属性比较特殊,不用加 v-bind就可以绑定
    <input type = "text" ref="input">
</template>

<script>
    import {ref,onMounted} from 'vue' 
    export default{
        setup(){
            const input = ref(null);
            
            onMounted(()=>{
                input.value.focus();
            })
            
            return{
                input
            }
        }
    }
</script>
复制代码

一旦我的页面多了,需要该需求的页面多了,再用默认的方式实现此操作,会非常的麻烦,所以我们希望用个v-focus,并对他实现(自定义指令)

方式二:(局部自定义指令)

<template>
    <input type = "text" v-focus>
</template>

<script>
    export default{
        //局部自定义指令
        directives:{
            //自定义一个focus指令,使用的时候加 v- 就行
            focus:{
                //指令的生命周期,会传来4个参数
                //mounted(el,bindings,vnode,preVnode)
                mounted(el){
                    el.focus();
                }
            }
        }
    }
</script>
复制代码

方式三:(全局自定义指令)
在main.js中

const app = createApp(App)

app.directive("focus",{
    mounted(el){
        el.focus();
    }
})

app.mount('#app')

然后直接在要使用的页面中使用,即可
<template>
    <input type = "text" v-focus>
</template>
复制代码

自定义指令的生命周期

1.created:在绑定元素的attribute或事件监听器被应用之前调用。

<input>的框里面会有其他属性或监听器,在他们还没有被调用的时候,就开始生命周期了
复制代码

2.beforeMount:当指令第一次绑定到元素并且在挂载父组件之前被调用

元素属性等已经被创建出来,但是还没有被挂载的时候
复制代码

3.mounted:在绑定元素的父组件被挂在后调用

4.beforeUpdate:在更新包含组件的VNode之前调用

5.updated:在包含组件的VNode及子组件的VNode更新后调用

6.beforeUnmount:在卸载绑定元素的父组件之前调用

7.unmounted:当指令与元素解除绑定且父组件已卸载时,只调用一次

自定义指令也是可以有修饰符的,比如.lazy、.stop

<template>
    <input type = "text" v-why>
    
    <button @click="increment">
        当前计数:{{counter}}
    </button>
    
    //当我给自定义指令传入修饰符,并且赋值
    v-why.aaa.bbb="'coderwhy'"
</template>

<script>
    export default{
    import {ref} from 'vue'
        //局部自定义指令
        directives:{
            why:{
                created(bindings){
                
                //修饰符传值,是传到了bindings中
                    console.log(bingdings)
                //获取修饰符传过来的具体值
                    bindings.value
                //获取修饰符(拿到的是一个对象)
                    是一个键值对的形式aaa="true"
                    当我使用到aaa的时候才为true
                    
                    bingings.modifiers
                    
                },
                beforecreated(){
                },
                mounted(){
                },
                beforeUpdate(){
                },
                updated(){
                },
                beforeUnmount(){
                },
                unmounted(){
                },
            }
        },
        setup(){
            const counter = ref(0)
            
            const increment()=()=> counter.value++
            
            return{
                counter,
                increment,
            }
        }
    }
</script>
复制代码

自定义指令练习

图片.png
将时间戳 转变为 正常时间

App.vue

<template>
自己定义时间的格式,只需要传递一下参数就行
    <h2 v-format-time="'YYYY/MM/DD'">{{timestamp}}</h2>
</template>

<script>
    import {ref} from 'vue'
    export default{
        setup(){
            const timestamp = 1624452193
            
            return{
                timestamp
            }
        }
    }
</script>
复制代码

全局自定义指令main.js
但是会造成main.js的代码过多,所以我们最好单独建一个文件夹,专门用来存放全局自定义指令

directives/index.js

import registerFormatTime from './format-time'
export default function registerDirectives(app){
    registerFormatTime(app)
}
复制代码

directives/format-time.js

1.通过安装第三点方库:npm install dayjs
import dayjs from 'dayjs'
export default function(app){
    formatString = "YYYY-MM-DD HH:mm:ss";
//全局注册.directive
    app.directive("format-time",{
    //2.修改timestamp,bindings拿到时间格式化
        mounted(el,bindings){
            if(formatString)
                formatString = bindings.value
        
            3.拿到el中的值(字符串),也就是timestamp
            const textContent = el.textContent;
            4.将字符串转换为int型
            let timestamp = parseInt(textContent)
            if(textContent.length === 10){
                5.长度为10表示秒钟,单位转换为毫秒
                timestamp = timestamp * 1000
            }
            //6.重新对textContent赋值 HH:24小时制
            el.textContent = 
            dayjs(timestamp).
            format(formatString);
        }
    })
}
复制代码

main.js

import registerDirectives from './directives/index'

registerDirectives(app);
复制代码

认识Teleport

应用程序最终会形参一颗DOM树结构,但是我不想成为树

图片.png

图片.png

图片.png

<template>
    <div class="app">
        <h2>当前计数</h2>
        <button>+1</button>
    </div>    
</template>

<script>
    export default{
        components:{
            
        }
    }
</script>
复制代码

默认挂载的样子:

图片.png

<template>
    <div class="app">
        <teleport to="#why">
            <h2>当前计数</h2>
            <button>+1</button>
        </teleport>
    </div>    
</template>
复制代码

图片.png

移动组件:
HelloWorld

<template>
    <div class="HelloWorld">
        <h2>HelloWorld</h2>
    </div>    
</template>
复制代码

App

<template>
    <div class="app">
    组件也同样移动到id标签为why的地方了
        <teleport to="#why">
            <h2>当前计数</h2>
            <button>+1</button>
            <HelloWorld/>
        </teleport>
    </div>    
</template>
<script>
    import HelloWorld from './HelloWorld'
    export default{
        components:{
            HelloWorld
        }
    }
</scrpit>
复制代码

认识Vue插件

图片.png

图片.png

plugins/plugins_object.js

export default{
    必须要有一个install函数,默认传app函数
    install(app){
    全局属性
        app.config.globalProperties.name = "coderwhy"
    }
    后续可以再任何页面,通过window.name拿到coderwhy
}
复制代码

main.js

import pluginObject from './plugins/pluginObject'

app.use(pluginObject)
复制代码

在组件中获取定义的.name值

setup中获取该属性,因为他用不了this
setup(){
    const instance = getCurrentInstance();
    console.log(instance.appContext.
    config.globalProperties.name)
}
复制代码

也可以将插件写成一个函数

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享