js其它

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > js其它 > typescript入门demo

typescript在vue中的入门案例代码demo

作者:微雨即至

这篇文章主要介绍了typescript在vue中的入门案例代码demo,使用技术栈vue2+typescript+scss入门练手项目,天气预报demo,需要的朋友可以参考下。

使用技术栈vue2+typescript+scss入门练手项目,天气预报demo,需要的朋友可以参考下。整体的实现思路比较简单,页面也只有一个,包含三部分,搜索框、热门城市和天气预报,组件库用的是ElementUI。

搜索框searchBox.vue

<template>
  <div id="search">
    <el-input
      placeholder="请输入内容"
      suffix-icon="el-icon-search"
      v-model="city"
      @change="enter"
      @input="edit"
    >
    </el-input>
  </div>
</template>

<script lang="ts">
import { Vue, Component, Emit } from "vue-property-decorator";

@Component({
  components: {},
})
export default class searchBox extends Vue {
  city = "";

  @Emit("sendCity")
  enter(value: string): string {
    //在输入框失去焦点或用户按下回车时触发(会导致一些bug!!!)
    console.log("按下回车,搜索地是:" + value);
    return value;
  }

  edit(value: string | number): void {
    console.log("正在输入中......" + value);
  }
}
</script>

这里不写@component注解,会导致组件中的数据和处理方法不是响应式的,刚开始写的时候根本没有意识到这个问题,点击页面中的输入框el-input组件根本没反应,一直觉得是逻辑或者element有问题,后来查了资料才知道是@component没有写。searchBox子组件需要把自己的数据传给weather组件,两个组件为兄弟关系,通信的话可以借助父组件Home组件。在ts中,组件间的数据传递,通过@Emit,子组件将数据发送出去,父组件通过函数接收,而父组件与子组件通信,通过@Prop。

首页Home.vue

<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png" />
    <searchBox @sendCity="sendCity" />
    <popularCity @popularCity="clickCity" />
    <weather :searchCity="city" :popularCity="city" />
  </div>
</template>

<script lang="ts">
import { Component, Vue } from "vue-property-decorator";
import searchBox from "@/components/searchBox.vue";
import popularCity from "@/components/popularCity.vue";
import weather from "@/components/weather.vue";

@Component({
  components: {
    searchBox,
    popularCity,
    weather,
  },
})
export default class Home extends Vue {
  city = "";

  sendCity(city: string): void {
    //搜索框组件向home组件传值
    this.city = city;
  }

  clickCity(city: string): void {
    //热门城市传值
    this.city = city;
  }
}
</script>

热门城市 popularCity.vue

<template>
  <div id="city">
    <div v-for="(item, index) in message" :key="index">
      <el-button class="box-city" type="text" @click="clickCity(item)">{{
        item
      }}</el-button>
    </div>
  </div>
</template>

<script lang="ts">
import { Vue, Component, Emit } from "vue-property-decorator";

@Component({
  components: {},
})
export default class searchBox extends Vue {
  message = ["北京", "上海", "深圳", "成都", "重庆", "武汉", "南京"];

  @Emit("popularCity")
  clickCity(city: string): string {
    console.log("点击热门城市:" + city);
    return city;
  }
}
</script>

<style lang="scss" scoped>
@import "../style/index.scss";
#city {
  width: 40%;
  @include box-row-flex(center);

  .box-city {
    width: 10%;
    font-style: italic;
    color: $text-color;
    font-size: $font-size;
  }
}
</style>

这个没有什么好说的,主要就是进行了scss的一些尝试,比如@mixin

天气 weather.vue

<template>
  <div id="weather">
    <div v-for="(item, index) in weatherArr" :key="index">
      <el-card class="box-card">
        <div slot="header" class="clearfix">
          <span>{{ city }}</span>
        </div>
        <div class="content">
          <div class="type">{{ item.type }}</div>
          <div class="temp">
            {{ item.low | temperatureFilter }} ~
            {{ item.high | temperatureFilter }}
          </div>
          <div class="time">{{ item.date }}</div>
        </div>
      </el-card>
    </div>
  </div>
</template>

<script lang="ts">
import weather from "../interface/IWeather";
import getWeather from "../utils/getWeather";
import { Vue, Component, Prop, Watch } from "vue-property-decorator";

@Component({
  components: {},
  filters: {
    //过滤器
    temperatureFilter: (value: string): string => {
      return value.substring(2);
    },
  },
})
export default class searchBox extends Vue {
  @Prop({
    type: String,
    default: "",
  })
  searchCity!: string;

  city = "西安";
  weatherArr: Array<weather> = [];

  @Watch("searchCity")
  async handleWatch(value: string): Promise<void> {
    console.log("搜索框或热门城市传入的地区是:" + value);

    const res = await getWeather(value);
    console.log(res);
    if (res.status == 1000) {
      this.city = value;
      this.weatherArr.length = 0; //清空当前数组存入的数据
      this.weatherArr.push(...res.weather);
    } else if (res.status == 1002) {
      this.$message({
        message: res.desc as string,
        type: "error",
      });
    }
  }

  async created(): Promise<void> {
    const res = await getWeather("西安");
    if (res.status == 1000) {
      this.weatherArr.push(...res.weather);
    } else if (res.status == 1002) {
      this.$message({
        message: res.desc as string,
        type: "error",
      });
    }

    console.log(res);
  }
}
</script>

这里是整个demo的核心,负责接收其他组件的数据,发送请求,获取天气数据。

先来说一下其他组件传递数据,上面说了父子组件通信通过@Prop,这里用了@Watch检测数据变化,如果点击了某个热门城市或者搜索框按下回车键,会发送数据到这部分,数据来了就通过axios发送请求,获取天气数据。这里关于发送网络请求的部分,进行了封装。

同时,根据接口的返回数据写interface,这里为了展示数据(同时为了根据不同的返回码status来提示不同的消息),创建接口IWeather,主要用来抽象天气数据,IFiveWeather用来抽象接口返回形式(接口的代码就不在此展示)

getWeather.ts

import axios from "axios";

//获取某地的天气
async function getWeather(city: string): Promise<IFiveWeather> {
  const weatherArr: IFiveWeather = {
    status: 0,
    weather: [],
  };
  try {
    const res = await axios.get(
      `http://wthrcdn.etouch.cn/weather_mini?city=${city}`
    );

    const status: number = res.data.status;

    switch (status) {
      //输入城市错误的返回码
      case 1002:
        weatherArr.status = 1002;
        weatherArr.desc = res.data.desc;
        weatherArr.weather = [];
        break;
      //数据返回成功
      case 1000:
        weatherArr.status = 1000;
        weatherArr.weather.push(...res.data.data.forecast);
    }
  } catch (error) {
    console.log("天气接口出错啦:" + error);
  }

  return weatherArr;
}

export default getWeather;

到此这篇关于typescript在vue中的入门案例代码demo的文章就介绍到这了,更多相关typescript入门demo内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文