Vue通过封装全局获取焦点指令
作者:花哥码天下
这篇文章主要为大家详细介绍了Vue通过封装全局获取焦点指令的相关知识,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以参考下
在main.js封装v-focus指令
// 封装全局指令 focus Vue.directive('focus', { // 指令所在的dom元素,被插入到页面中时触发 inserted (el) { el.focus() } })
使用
<template> <div class="my-tag"> <input v-if="isEdit" v-focus ref="inp" class="input" type="text" placeholder="输入标签" :value="value" @blur="isEdit = false" @keyup.enter="handleEnter" /> <div v-else @dblclick="handleClick" class="text"> {{ value }} </div> </div> </template> <script> export default { props: { value: String }, data () { return { isEdit: false } }, methods: { handleClick () { // 双击后,切换到显示状态 (Vue是异步dom更新) this.isEdit = true // // 等dom更新完了,再获取焦点 // this.$nextTick(() => { // // 立刻获取焦点 // this.$refs.inp.focus() // }) }, handleEnter (e) { // 非空处理 if (e.target.value.trim() === '') return alert('标签内容不能为空') // 子传父,将回车时,[输入框的内容] 提交给父组件更新 // 由于父组件是v-model,触发事件,需要触发 input 事件 this.$emit('input', e.target.value) // 提交完成,关闭输入状态 this.isEdit = false } } } </script> <style lang="less" scoped> .my-tag { cursor: pointer; .input { appearance: none; outline: none; border: 1px solid #ccc; width: 100px; height: 40px; box-sizing: border-box; padding: 10px; color: #666; &::placeholder { color: #666; } } } </style>
<template> <table class="my-table"> <thead> <tr> <slot name="head"></slot> </tr> </thead> <tbody> <tr v-for="(item, index) in data" :key="item.id"> <slot name="body" :item="item" :index="index" ></slot> </tr> </tbody> </table> </template> <script> export default { props: { data: { type: Array, required: true } } }; </script> <style lang="less" scoped> .my-table { width: 100%; border-spacing: 0; img { width: 100px; height: 100px; object-fit: contain; vertical-align: middle; } th { background: #f5f5f5; border-bottom: 2px solid #069; } td { border-bottom: 1px dashed #ccc; } td, th { text-align: center; padding: 10px; transition: all .5s; &.red { color: red; } } .none { height: 100px; line-height: 100px; color: #999; } } </style>
<template> <div class="table-case"> <MyTable :data="goods"> <template #head> <th>编号</th> <th>名称</th> <th>图片</th> <th width="100px">标签</th> </template> <template #body="{ item, index }"> <td>{{ index + 1 }}</td> <td>{{ item.name }}</td> <td> <img :src="item.picture" /> </td> <td> <MyTag v-model="item.tag"></MyTag> </td> </template> </MyTable> </div> </template> <script> // my-tag 标签组件的封装 // 1. 创建组件 - 初始化 // 2. 实现功能 // (1) 双击显示,并且自动聚焦 // v-if v-else @dbclick 操作 isEdit // 自动聚焦: // 1. $nextTick => $refs 获取到dom,进行focus获取焦点 // 2. 封装v-focus指令 // (2) 失去焦点,隐藏输入框 // @blur 操作 isEdit 即可 // (3) 回显标签信息 // 回显的标签信息是父组件传递过来的 // v-model实现功能 (简化代码) v-model => :value 和 @input // 组件内部通过props接收, :value设置给输入框 // (4) 内容修改了,回车 => 修改标签信息 // @keyup.enter, 触发事件 $emit('input', e.target.value) // --------------------------------------------------------------------- // my-table 表格组件的封装 // 1. 数据不能写死,动态传递表格渲染的数据 props // 2. 结构不能写死 - 多处结构自定义 【具名插槽】 // (1) 表头支持自定义 // (2) 主体支持自定义 import MyTag from './components/MyTag.vue' import MyTable from './components/MyTable.vue' export default { name: 'TableCase', components: { MyTag, MyTable }, data () { return { // 测试组件功能的临时数据 tempText: '水杯', tempText2: '钢笔', goods: [ { id: 101, picture: 'https://yanxuan-item.nosdn.127.net/f8c37ffa41ab1eb84bff499e1f6acfc7.jpg', name: '梨皮朱泥三绝清代小品壶经典款紫砂壶', tag: '茶具' }, { id: 102, picture: 'https://yanxuan-item.nosdn.127.net/221317c85274a188174352474b859d7b.jpg', name: '全防水HABU旋钮牛皮户外徒步鞋山宁泰抗菌', tag: '男鞋' }, { id: 103, picture: 'https://yanxuan-item.nosdn.127.net/cd4b840751ef4f7505c85004f0bebcb5.png', name: '毛茸茸小熊出没,儿童羊羔绒背心73-90cm', tag: '儿童服饰' }, { id: 104, picture: 'https://yanxuan-item.nosdn.127.net/56eb25a38d7a630e76a608a9360eec6b.jpg', name: '基础百搭,儿童套头针织毛衣1-9岁', tag: '儿童服饰' }, ] } } } </script> <style lang="less" scoped> .table-case { width: 1000px; margin: 50px auto; img { width: 100px; height: 100px; object-fit: contain; vertical-align: middle; } } </style>
以上就是Vue通过封装全局获取焦点指令的详细内容,更多关于Vue获取焦点指令的资料请关注脚本之家其它相关文章!