vue中多个input焦点切换问题

2019-04-02  本文已影响0人  一个被程序员耽误的厨师

业务场景是这样的:左边菜单栏有多个菜单项,点击不同的菜单项,右侧相对应的input获得焦点

需求图

开始以为问题很简单只是一个focus问题,其实问题不是那么简单,vue框架中的表单输入框不支持focus以及blur事件的解决方案,那么如何解决这个问题呢?

这里用到的Vue.directive 自定义指令,下面简单的说下自定义指令。

1、自定义指令中三个参数
el://指令所绑定的元素
binding://一个对象、包含指令的很多信息
vnode://vue编译生成的虚拟节点
2、自定义指令的生命周
1、bind://只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个绑定时执行一次的初始化动作。
2、inserted://被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于document中)。
3、update://被绑定于元素所在的模板更新时调用,而无论绑定值是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新。
4、componentUpdated://被绑定元素所在模板完成一次更新周期时调用。
5、unbind://只调用一次,指令与元素解绑时调用。

下面就是实现代码

<!--  -->
<template>
  <el-container>
    <el-header>Header</el-header>
    <el-container>
      <el-aside width="200px">
        <el-tree :data="data" :props="defaultProps" @node-click="handleNodeClick"></el-tree>
      </el-aside>
      <el-main>
        <input type="text" v-focus="data[0].children[0].focus"><br>
        <input type="text" v-focus="data[0].children[1].focus"><br>
        <input type="text" v-focus="data[0].children[2].focus"><br>
        <input type="text" v-focus="data[0].children[3].focus"><br>
        <input type="text" v-focus="data[0].children[4].focus"><br>
      </el-main>
    </el-container>
  </el-container>
</template>

<script>
export default {
  data() {
    return {
      data: [
        {
          label: "root [结构类型]",
          children: [
            {
              id: "0",
              label: "单行文字",
              focus:true
            },
            {
              id: "1",
              label: "单行数字",
              focus:false
            },
            {
              id: "2",
              label: "多行文字",
              focus:false
            },
            {
              id: "3",
              label: "表格类型",
              focus:false
            },
            {
              id: "4",
              label: "图片文件",
              focus:false
            },
          ]
        }
      ],
      defaultProps: {
        children: "children",
        label: "label"
      },
      labelPosition: "top",
      formLabelAlign: {
        name: "",
        region: "",
        type: ""
      }
    };
  }, 
  directives: {
    focus: {
      // 绑定判断
      inserted: function (el, {value}) {
        if (value) {
          el.focus()
        }
      },
      //更新判断    
      update: function (el, {value}) {
        if (value) {
          el.focus()
        }
      },
      //更新完成
      componentUpdated:function(el, {value}){
        console.log('111:'+value)
      }
    }
  },
  methods: {
    updateFocusStatus(id){
      let _this = this;
      let children = _this.data[0].children;

      if(children[id].focus){
        children[id].focus=!children[id].focus;
        return;
      }

      children.map(n =>{
        n.id != id ? n.focus = false : n.focus = true;
      })
    },
    handleNodeClick(data) {
      let _this = this;
      console.log(data.id+":"+data.focus);
      _this.updateFocusStatus(data.id);
    }
  }
};
</script>
<style>
* {
  margin: 0;
  padding: 0;
}
html,
body,
#app {
  height: 100%;
}
.el-container {
  height: 100%;
}
.el-header {
  background-color: #b3c0d1;
  color: #333;
  padding: 0;

  line-height: 60px;
}

.el-aside {
  background-color: #d3dce6;
  color: #333;
  height: 100%;
}

.el-main {
  background-color: #e9eef3;
  color: #333;
  height: 100%;
}
</style>
上一篇下一篇

猜你喜欢

热点阅读