VUE+TS 方法整理

实操

内容VUE3.0 -文档
vue-property-decorator -git 文档
!!! vue3-study -文档语雀
《Vue.js 权威指南》GIT源码篇 -双向绑定
Javascript -DOM 模型目录
【高赞】biaochenxuying -夜尽天明 GIT
【高赞】Armour TS 后台管理 -GIT
Vue 封装 svg-icon 组件; — svg-sprite-loader; — js 随记;Sass 总结笔记
【高赞】理解Vue中的nextTick
内容【知】 -TypeScript入门问题!!!
【知】 -TypeScript 泛型、关键字; — 2;
【知】 -TypeScript 专栏; — 2 工具类型; — n个技巧;
TypeScript -文档手册 !!!
Typescriptlang 在线编写 !!!
ESlint+Prettier+VScode;
Vscode 解决 Setting.json 报警告;
Vscode Reactjs code 插件提示;
GITvue2.0-element-ts 1; — ts- md、store 2;
面试【1】 thWinterSun -GIT面试!!!
【2】 FrankKai-GIT面试!!!
【1】9 年小厂老前端的年终总结【2】三十七个常见Vue面试题
【3】 关于 let 暂时性死区
  • 1、keep-alive -生命周期刷新操作;

  • 2、window.scrollTo()offsetTop 滚动条操作;
    获取JS文件

  • 获取 JSON.parse(),转为一个对象。将URL解析成对象的形式;

  • 设置 JSON.stringify(),转为 JSON 字符串。将对象 序列化成URL的形式,以&进行拼接;

  • JSON.parse(JSON.strightfy(this.value)) 拷贝一层;

  • this.$refs[formName].validate() : - 此时表单内的 dom 还没有加载完成就执行了,从而报错。this.$nextTick(()=>{}) - 等 form 表单的 dom渲染 完在执行;


TypeScript 特点:

TypeScript 是一种有微软开发的自由和开源的编程语言,是JavaScript的超集。
  • 1、类型批注和编译时的类型检查(声明变量 var a:number) ;2、强类型语言;3、面向对象;4、类class;5、接口(Interface),类型别名(type); 6、泛型(< T>);7、lambda 函数;

【1】 Type 和 Interface 都可以描述一个对象或者函数,选用时机?

  • Interface 用来描述 对象(object) 的形状 或者对 类(class) 的行为 进行抽象。
  • 在定义公共 API 时(比如编辑一个库)使用 interface,这样可以方便使用者继承接口;
  • 在定义组件属性(Props)和 状态(State)时,建议使用 type,因为 type的约束性更强;
Interface 和 Type 在ts中是两个不同的概念, type 和 interface 最大的区别是: type 类型不能二次编辑,而 interface 可以随时扩展;
  • 接口 Interface属性: 可选属性 在属性后边加? - 含义是该属性可以不存在;
  • Type 声明可以定义联合类型,基本类型等多种类型,而 interface 只能定义对象类型

【2】泛型

// 【1】泛型约束
// 泛型 T 不一定包含属性 length,所以编译的时候报错了
function getLength<T>(arg:T):T {
  console.log(arg.length) // error: Property 'length' does not exist on type 'T'
  return arg;
}

// 【2】使用 extends 约束泛型 <T> 必须符合 Ilength 的形状,也就是必须包含 length 属性
interface Ilength {
  length: number
}
// 泛型约束
function getLength<T extends Ilength>(arg:T):T {
  console.log(arg.length)
  return arg;
}
getLength('abcd') // 4

=========================

// 举个栗子
function identity<T>(arg: T): T {
    return arg;
}
// 这里的 T 为类型变量,表示类型而不是值。
// 这里 T 帮助ts捕捉用户输入的类型,之后就可以使用这个类型。使用T当做返回值类型,这样可以知道传入值和返回值类型是相同的。
// 这样就可以跟踪函数里使用的类型的信息。这个就叫做泛型。可以适用于多个类型,不会丢失信息。保持准确性,传入数值类型并返回数值类型。

// 使用泛型函数
// 1. 传入所有参数,包含类型参数
let output = identity<string>('mystring');
// 2. 利用类型推论 -- 即编译器会根据传入的参数自动的帮助我们确定T的类型
let output = identity('mystring');
// 类型推论帮助我们保持代码精简和高可读性。如果编译器不能够自动地推断出类型的话,只能像上面那样明确的传入T的类型,在一些复杂的情况下,这是可能出现的。

// 泛型接口
interface genFn<T> {
    ( arg : T ) : T;
};
let ide : genFn<number> = identity;

// 泛型类
class Gen <T> {
    zero : T;
    add : ( x : T, y : T ) => T;
}
let gen = new Gen<Number>();
//泛型类指的是实例部分的类型,所以类的静态属性不能使用这个泛型类型。

// 泛型约束
// 利用接口来描述约束条件,然后使用这个接口和extends关键字实现约束
interface Lengthwise {
    length: number;
}

function loggingIdentity<T extends Lengthwise>(arg: T): T {
    console.log(arg.length);  // Now we know it has a .length property, so no more error
    return arg;
}
// 这时的泛型函数被定义了约束,因此它不再是适用于任何类型。

【3】 实用工具类型:

  • 1、Partial<T> — 将 T 中所有属性转换为可选属性,返回的类型可以是 T 的任意子集。
  • 2、Pick<T,K> — 通过在T中抽取一组属性K构建一个新类型。

VUE - @Component / @Prop

vue-property-decorator 装饰器的使用。

<script lang="ts">
import { Component, Vue, Prop, Emit, Watch } from 'vue-property-decorator';
import { UserInfo, NavListItem } from "@/types/index";

export interface NavListItem {
  index: string;
  path: string;
  name: string;
}
// HTTP
export interface ResponseData {
  code: number;
  data?: any;
  message: string;
}
@Component({  //Component组件装饰器,用于增加一些全局的配置,比如过滤器filters
  components: {
     //components里面放一些全局的组件,引入子组件后写在这,跟vue中的components一样
  },
})
export default class Home extends Vue {
  @Prop({ default: 'default value' }) readonly propB!: string;    // Prop, ! -值不能为空
  @Prop(String)
  propA:string;
  @Prop([String,Number])
  propB:string|number;
  
  @Watch('child', { immediate: true, deep: true })   // 监听器
  onChildChanged(val: string, oldVal: string) {}   // 监听器相应方法

  private articlesList: Array<object> = [];
  private list: Array<NavListItem> = [];  // 适合写死的

  mounted(): void { // 钩子函数
    this.onChildChanged(this.$route, this.$route);
  }

  // 父: @cancel="onHandleCancel"
  @Emit()
  private cancel(): boolean {
    return false;
  }

  private handleOAuth(): void {
    // 保存授权前的页面链接内容
    let preventHistory: object = {
      name: this.$route.name,
      query: this.$route.query
    };
    window.sessionStorage.preventHistory = JSON.stringify(preventHistory);
    // window.location.href = 'https://github.com/login/oauth/authorize?client_id=6de90ab270aea2bdb01c&redirect_uri=http://biaochenxuying.cn/login'
    window.location.href = `${config.oauth_uri}?client_id=${config.client_id}&redirect_uri=${config.redirect_uri}`;
  }
}
</script>

@Provide

<script lang="ts">
import { Provide, Vue } from 'vue-property-decorator';
export default class Home extends Vue {
    @Provide() private name: string = 'weipingping'; //定制属性,替换data,正常情况下直接使用
    //private   修饰的属性或者方法是私有的,只在此类中有效
    //public    修饰的属性或者方法是公有的,任何组件都可以访问到
    //protected 修饰的属性或者方法是私有的,但它的子组件可以访问到
}
</script>

@Emit

<script lang="ts">
import { Emit, Vue } from 'vue-property-decorator';
export default class Home extends Vue {
    //Emit 给父组件传值
    //方式一
    private add(): void{
      @Emit("add","传递的参数")
    }
    //方式二
    @Emit ("add","传递的参数")
    private add(): void{
      console.log("这个方法运行完成后触发Emit")
    }
}
</script>

计算属性

<script lang="ts">
import { Component, Vue, Provide } from 'vue-property-decorator';
@Component({
  components: {},
})
export default class Home extends Vue {
   @Provide() private one: number = 5;
   @Provide() private two: number = 6;
   // 计算属性直接前面加get就可以了
   get allNum() {
     return this.one + this.two;
   }
}
</script>
var arr = [[1,1,1],[2,2,2],[3,3,3],[4,4,4],[5,5,5]]
console.log(arr)
var newArray = arr[0].map(function(col, i) {
  console.log(i)
  return arr.map(function(row) {
  	console.log(row)
  	return row[i];
  })
});
console.log(newArray) // [[1,2,3,4,5],[1,2,3,4,5]]

1、keep-alive -生命周期刷新操作

简介: 是 Vue 内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染。

适用场景: https://www.jb51.net/article/131110.htm

beforeRouteEnter 总会触发:
  • 不使用 keep-alive 时,
    beforeRouteEnter --> created --> mounted --> destroyed (组件被停用时)

  • 使用 keep-alive 时,
    beforeRouteEnter --> created --> mounted --> activated (组件被激活时)–> deactivated


2、window.scrollTo()offsetTop 滚动条操作

<template>
    <!-- 实时资讯 -->
    <main class="item-content" :ref="myRefThree">
      <RumorList :rumorListData="rumorListData"/>
    </main>

    <!-- 疫情科普 -->
    <main class="item-content" ref="myRefFour">
      <WikiList :wikiListData="wikiListData"/>
    </main>
</template>

export default {
  setup() {
    onMounted(() => {
      // 1、获取 arrScrollDom 数组列表
      stateData.arrScrollDom = document.getElementsByClassName("item-content")
      // 2、获取滚动条
      window.addEventListener('scroll', handleScroll)
    })

    // 3、ref 获取DOM元素,setRefOne -获取后的值  
    let setRefOne = ''
    let setRefTwo = ''
    const myRefOne = el => { setRefOne = el }
    const myRefTwo = el => { setRefTwo = el }
    
    // 3.5、标题TAB点击-获取滚动条位置
    const onTitleTopClick = (id) => {
      let dom
      if (id == 1) dom = setRefOne.offsetTop
      else if (id == 2) dom = setRefTwo.offsetTop
      else if (id == 3) dom = setRefThree.offsetTop
      else dom = setRefFour.offsetTop
      window.scrollTo(0, dom)    // 滚动条位置
      stateData.titleTopId = id
    }
    
    // 4、标题TAB滚动条位置
    const handleScroll = () => {
      let scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
      // 获取 arrScrollDom 数组长度
      let arrScrollDomLength = stateData.arrScrollDom.length
      stateData.headerFixed = scrollTop > ctx.offsetTop     // 返回布尔值

      for (let i = 0; i < arrScrollDomLength; i++) {
        // 因为下面使用到了i+1,所以需要把最后一个分离出来判断
        if (stateData.arrScrollDom[arrScrollDomLength-1].offsetTop-scrollTop > 80) {
          if (stateData.arrScrollDom[i].offsetTop-scrollTop <= 80 && stateData.arrScrollDom[i+1].offsetTop-scrollTop > 80) {
            stateData.titleTopId = i + 1    // 更新头部标题的 id(选中的)
          }
        } else {
          stateData.titleTopId = arrScrollDomLength
        }
      }
    }
    
    // 页面离开销毁
    onUnmounted(() => {
      // 5、销毁 handleScroll 事件
      window.removeEventListener('scroll', handleScroll);
    })
    
    return {
      ...toRefs(stateData),
      myRefOne,
      myRefTwo,
      onTitleTopClick,
      handleScroll,
    }
  }
}
  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值