天天看点

vue写组件应该注意的问题高度抽离组件功能

vue写组件应该注意的问题

  • 高度抽离组件功能

高度抽离组件功能

我们知道,vue中的数据流是单项的,所以提升组件复用性最好的办法就是使子组件只展示数据,将功能函数写在最大的父组件中,使用props将函数或者数据进行向下传递,一层一层,当需要维护时,只需要在最大的组件中进行修改即可。

下面我们将一个vue的todolist使用组件进行写

下面上代码

<template>
  <div>
    <my-input :addNew="addNew"></my-input>
    <h2>已完成{{ list.filter((item) => item.done).length }}</h2>
    <my-list
      :listData="list.filter((item) => item.done)"
      :delItem="delItem"
      :edit="edit"
      :changeStatus="changeStatus"
    ></my-list>
    <h2>未完成{{ list.filter((item) => !item.done).length }}</h2>
    <my-list
      :listData="list.filter((item) => !item.done)"
      :delItem="delItem"
      :edit="edit"
      :changeStatus="changeStatus"
    ></my-list>
  </div>
</template>

<script>
import myInput from "./components/Input";
import myList from "./components/List";
export default {
  components: {
    myInput,
    myList,
  },
  data() {
    return {
      list: [
        { title: "学习vue", done: false, status: 1 },
        { title: "学习react", done: false, status: 1 },
        { title: "学习webpack", done: false, status: 1 },
      ],
    };
  },
  created() {},
  mounted() {},
  methods: {
    //删除计划方法
    delItem(item) {
      let index = this.list.indexOf(item);
      this.list.splice(index, 1);
    },
    //添加新的计划方法
    addNew(item) {
      //遍历
      let flag = false;
      let tempObj = { ...item };
      //遍历判断
      this.list.forEach((it) => {
        if (tempObj.title === it.title) {
          alert("您已经添加了这条计划");
          flag = true;
        }
      });
      if (flag) {
        return false;
      } else {
        this.list.unshift(tempObj);
      }
    },
    //可以整和为一个方法
    //编辑方法
    edit(str, itemData) {
      let index = this.list.indexOf(itemData);
      this.list[index].title = str;
      itemData.status = 1;
    },
    //切换状态
    changeStatus(item) {
      let index = this.list.indexOf(item);
      item.status = 0;
      this.list.forEach((it, ind) => {
        if (index != ind) {
          it.status = 1;
        }
      });
    },
  },
};
</script>
<style scoped></style>
           

这个就是最大的index组件,这里可以看倒,todolist的增,删,改都放在了最大的父组件中

list组件

<template>
  <div>
    <list-item
      v-for="item in listData"
      :key="item.title"
      :itemData="item"
      :delItem="delItem"
      :edit="edit"
      :changeStatus="changeStatus"
    ></list-item>
  </div>
</template>

<script>
import ListItem from "./ListItem";
export default {
  components: {
    ListItem,
  },
  data() {
    return {};
  },
  created() {},
  mounted() {},
  methods: {},
  props: {
    listData: {
      type: Array,
      reqiured: true,
    },
    delItem: {
      type: Function,
    },
    edit: {
      type: Function,
    },
    changeStatus: {
      type: Function,
    },
  },
};
</script>

<style scoped></style>

           

listitem组件

<template>
  <div>
    <div class="show" v-if="itemData.status">
      <input type="checkbox" v-model="itemData.done" />
      <span
        v-text="itemData.title"
        @dblclick="
          changeStatus(itemData);
          tempStr = itemData.title;
        "
      ></span>
      <button @click="delItem(itemData)">删除</button>
    </div>
    <div class="edit" v-else>
      <input type="text" v-model="tempStr" autofocus />
      <button @click="edit(tempStr, itemData)">确定</button>
      <button
        @click="
          tempStr = '';
          itemData.status = 1;
        "
      >
        取消
      </button>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      tempStr: "",
    };
  },
  props: {
    itemData: {
      type: Object,
      required: true,
    },
    delItem: {
      type: Function,
    },
    edit: {
      type: Function,
    },
    changeStatus: {
      type: Function,
    },
  },
};
</script>

<style scoped></style>

           

input组件

<template>
  <div>
    <input
      type="text"
      @keyup.enter="
        addNew(temp);
        temp.title = '';
      "
      v-model="temp.title"
    />
  </div>
</template>

<script>
export default {
  data() {
    return {
      temp: {
        title: "",
        done: false,
      },
    };
  },
  props: {
    addNew: {
      type: Function,
    },
  },
};
</script>

<style scoped></style>