Vue2 装饰器与TS结合
  # vue2 TS decorator装饰器
Vue2.x +TypeScript 在市面上大多数是与装饰器语法连用。
vue-property-decorator封装的装饰器有@Component @Prop @Watch @Provide+@Inject @Emit
# 1.data 的定义
基本数据类型直接定义 引用数据类型需要写好类型
<script lang="ts">
import { Component, Vue } from "vue-property-decorator";
import { User } from "@/types";
@Component
export default class App extends Vue {
  //data定义
  name = "张三";
  nums: number[] = [100, 22, 333, 4, 4, 4, 4];
  user: User = { name: "张三", age: 40 };
}
</script>
 1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
//src/types/index.ts
export interface User {
  name: string;
  age: number;
}
 1
2
3
4
5
2
3
4
5
# 2.methods 的定义
<script lang="ts">
import { Component, Vue } from "vue-property-decorator";
@Component
export default class App extends Vue {
  //data定义
  name = "张三";
  nums: number[] = [100, 100, 100, 100, 100, 100, 100];
  //methods
  sum(a: number, b: number): number {
    return a + b;
  }
  //求平均数
  getAvg(): number {
    let avg = this.nums.reduce((pre, next, index, arr) => {
      if (index === arr.length-1) {
        return  (pre+next)/arr.length;
      }
      return pre + next;
    }, 0);
    return avg;
  }
}
</script>
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 3.vue 生命周期钩子函数
export default class App extends Vue {
  //生命周期--
  private created() {
      //调用方法  this.方法名()  
      //使用变量  this.变量
    console.log(this.getAvg());
  }
}
</script>
 1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 4.@Component 装饰器
声明组件,告诉Vue 当前是组件的实例
@Component() 可以接收一个对象,对象中可以写入 components ,filters,directives 【依旧按照之前的写法】
computed,watch 也可以写入,但是装饰器中的this不再指向vue的顶级实例 会找不到 data的数据【不推荐写入装饰器】
# 5.filters 过滤器
@Component({
  //过滤器
  filters: {
    getUserName(str: string): string {
      return "我的名字" + str;
    },
  },
})
 1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 6.components 组件注册
<script lang="ts">
import { Component, Vue } from "vue-property-decorator";
import Son from '@/components/Son.vue'
@Component({
  //组件注册
  components:{
    Son
  },
})
export default class App extends Vue {
}
</script>
 1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 7.自定义指令 directives
@Component({
  //自定义指令
  directives:{
    focus:{
      inserted:(el)=>{
        el.focus()
      }
    }
  },  
})
 1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 8.@Prop装饰器 组件通信-父传子
export default class Son extends Vue {
    @Prop({type:数据类型,defalut:"默认值"}) 接收的变量名[修饰符]:数据类型; //修饰符: ?[可选]   ![必传]
}
 1
2
3
2
3
父组件
   <son title="我是爸爸组件传递的数据"></son>
 1
子组件
import { Component, Prop, Vue } from "vue-property-decorator";
@Component
export default class Son extends Vue {
  //接收父组件传递的数据
  @Prop({ type: String, default: "" }) title!: string;
}
 1
2
3
4
5
6
7
2
3
4
5
6
7
# 9.@Emit 装饰器 组件通信-子传父
如果事件的名称未通过事件参数提供,则使用函数名称。 在这种情况下,camelCase名称将转换为kebab-case。
export default class Son extends Vue {
    @Emit('自定义事件类型')
     自己组件的方法名(){
        return 传递的数据;      
     }
 }   
 1
2
3
4
5
6
2
3
4
5
6
//没有传递自定义事件类型的 自动把 方法名(小驼峰)转换为中划线形式的字符串作为 自定义事件类型
export default class Son extends Vue {
    @Emit()       
     自己组件的方法名(){
        return 传递的数据;      
     }
 }
 1
2
3
4
5
6
7
2
3
4
5
6
7
案例:不传递自定义事件类型
子组件
<button @click="sendData">儿子给爸爸发送数据</button>
<script lang="ts">
import { Component, Vue,Emit} from "vue-property-decorator";
@Component
export default class Son extends Vue {
  @Emit()
  sendData(){
    return '我是子组件传递的数据'
  }
}
</script>
 1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
父组件
<son title="我是爸爸组件传递的数据" @send-data="getData"></son>
<script lang="ts">
import { Component, Vue } from "vue-property-decorator";
import Son from "@/components/Son.vue";
@Component({
  //组件注册
  components: {
    Son,
  }
})
export default class extends Vue {
  getData(str:string):void{
    console.log(str);
  }
}
</script>
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
案例2:传递自定义事件类型
子组件
 @Emit('changeData')
  sendData():string{
    return '我是子组件传递的数据'
  }
 1
2
3
4
2
3
4
父组件
<son title="我是爸爸组件传递的数据" @changeData="getData"></son>
 1
# 10.@Watch 监听数据变化
监听数据的变化,执行一个函数
//immediate 数据发生变化是否立即调用下面的回调函数     deep:是否启用深度监听
@Watch("name", { immediate: true, deep: true })
  xxxx(newVal: string):void {
    console.log(newVal); 
  }
 1
2
3
4
5
2
3
4
5
# 11.computed 计算属性
直接在方法名 前面加上一个 get 就表示计算属性值的获取
   get newName():string {
    return "新的名字:" + this.name;
  }
 1
2
3
2
3
# 12.vuex 获取数据 提交数据
//获取数据 
get dataList():any{
    return this.$store.state.dataList;
  }
//修改数据
addData():void{
   this.$store.commit('addList',{name:"张三",age:19})
}
 1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
编辑  (opens new window)
  上次更新: 2022/07/01, 01:27:13