# Label 标签页

html

<Layout>
  <ol class="tags">
    <li v-for="tag in tags" :key="tag">
      <span>{{tag}}</span>
      <Icon name="right"/>
    </li>
  </ol>
  <div class="createTag-wrapper">
    <button class="createTag">新建标签</button>
  </div>
</Layout>

封装 tagListModel,存放tags

const localStorageKeyName = 'tagList';
type TagListModel = {
  data: string[]
  fetch: ()=> string[]
  create:(name:string) => 'success' | 'duplicated'
  save: ()=> void
}
const tagListModel: TagListModel = {
  data: [],
  fetch(){
    this.data = JSON.parse(window.localStorage.getItem(localStorageKeyName) || '[]');
    return this.data;
  },
  create(name){
    if(this.data.indexOf(name) >= 0){ return 'duplicated'}
    this.data.push(name);
    this.save();
    return 'success';
  },
  save(){
    window.localStorage.setItem(localStorageKeyName,JSON.stringify(this.data));
  }
};
export default tagListModel;

使用 tagListModel.data 作为 Label 数据

  import tagListModel from '@/models/tagListModel';
  tagListModel.fetch();
  tags = tagListModel.data;  

实现新增标签功能

createTag(){
  const name = window.prompt('请输出标签名');
  if (name) {
    const message = tagListModel.create(name);
    if (message === 'duplicated') {
      window.alert('标签名重复了');
    } else if (message === 'success') {
      window.alert('添加成功');
    }
  }
}

Money.vue 重新设置 tags

  import tagListModel from '@/models/tagListModel';
  const tagList = tagListModel.fetch();
  // tags = ['衣', '食', '住', '行'];
  tags = tagList;

修改 tag string 为 {id,name}

// tagListModel.ts 
type Tag = { id: string; name: string;}
type TagListModel = {
  // data: string[]
  data: Tag[],    
  fetch: () => Tag[]
}

create(name){
  // if (this.data.indexOf(name) >= 0) {return 'duplicated';}
  const names = this.data.map(item => item.name);
  if(names.indexOf(name) >= 0){ return 'duplicated';}
  // this.data.push(name);
  this.data.push({id: name,name: name});
}

// Labels.vue
<li v-for="tag in tags" :key="tag.id">
  <span>{{tag.name}}</span>
</li>

添加路由

// index.ts
import EditLabel from '@/views/EditLabel.vue';
{
  path: '/labels/edit/:id',
  component: EditLabel
}
// EditLabel.vue
  import tagListModel from '@/models/tagListModel';
   created(){
      const id = this.$route.params.id;  //导航完成后获取数据使用 $route.params.id
      tagListModel.fetch();
      const tags = tagListModel.data;
      const tag = tags.filter(t => t.id === id)[0];
      if(tag){
        console.log(tag);
      }else{
        this.$router.replace('/404');
      }
    }

添加标签至编辑页面

// Labels.vue
<div class="tags">
  <router-link class="tag" v-for="tag in tags" :key="tag.id" :to="`/labels/edit/${tag.id}`"></router-link>
</div>

将 Notes.vue 改造为通用组件

// Notes.vue
@Prop({required: true}) fieldName!: string;
@Prop() placeholder?: string;

<span class="name">this.fieldName</span>
<input type="text" :placeholder="this.placeholder">

// EditLabel.vue
<Notes field-name="标签名" placeholder="请输入标签名"/>
import Notes from '@/components/Money/Notes.vue'
@Component({
  components: {Notes}
})

//Money.vue
<Notes field-name="备注" placeholder="在这里输入备注"/>

封装 Button组件

<button class="button" @click="$emit('click', $event)">
  <slot/>
</button>
 export default class Button extends Vue {
  }
// Labels.vue 引用
<Button class="createTag" @click="createTag">新建标签</Button>

EditLabel 页面布局

<div class="navBar">
  <Icon class="leftIcon" name="left" @click="goBack"/>
  <span class="title">编辑标签</span>
  <span class="rightIcon"></span>
</div>
<div class="form-wrapper">
  <FormItem :value="tag.name" @update:value="update" field-name="标签名" placeholder="请输入标签名"/>
</div>
<div class="button-wrapper">
  <Button @click="remove">删除标签</Button>
</div>

ID 生成器

let id: number = parseInt(window.localStorage.getItem('_idMax') || '0') || 0;

function createId() {
  id++;
  window.localStorage.setItem('_idMax',id.toString());
  return id;
}

export default createId;
//引用
import createId from '@/lib/createId';
const id = createId().toString();