vue3.0 学习

1、定义变量并更改数据

<template>
  <div>{{ state.info }}</div>
  <button @click="addInfo">新增数据</button>
</template>
<script>
import { reactive } from "vue";
export default {
  setup() {
    // 定义对象
    const state = reactive({ info: "哈哈哈" });

    const addInfo = () => {
      state.info += "上海";
    };
    return { state, addInfo };
  },
};
</script>

2、定义对象

<template>
  <div>{{ state.info }}</div>
  <button @click="addInfo">新增数据</button>
</template>
<script>
import { reactive } from "vue";
export default {
  setup() {
    // 定义对象
    const state = reactive({ info: "哈哈哈" });

    const addInfo = () => {
      state.info += "上海";
    };
    return { state, addInfo };
  },
};
</script>
<template>
  <div v-for="(item, index) in array" :key="index">{{ item }}</div>
</template>
<script>
import { reactive } from "vue";
export default {
  setup() {
    const array = reactive(["铱白", "铱白1", "铱白2", "铱白3", "铱白4", "龚白5"])
    return { array };
  },
};
</script>

3、生命周期

<template>
  <div class="userInfo">
    <div class="name">我叫{{ userInfo.name }}</div>
    <div class="name">我今年{{ userInfo.age }}岁了</div>
    <button @click="updateAge">更新年龄</button>
  </div>
</template>

<script>
import {
  reactive,
  onBeforeMount,
  onMounted,
  onBeforeUpdate,
  onUpdated,
  onBeforeUnmount,
  onUnmounted,
} from "vue";
export default {
  setup() {
    const userInfo = reactive({
      name: "苏小妍",
      age: "18",
    });
    onBeforeMount(() => {
      userInfo.age = 19;
      console.log("onBeforeMount", userInfo.age);
    });
    onMounted(() => {
      userInfo.age = 20;
      console.log("onMounted", userInfo.age);
    });
    /**
     * onBeforeUpdate以及onUpdated禁止修改值,否则会进入死循环
     */
    onBeforeUpdate(() => {
      console.log("onBeforeUpdate", userInfo.age);
    });
    onUpdated(() => {
      console.log("onUpdated", userInfo.age);
    });
    onBeforeUnmount(() => {
      userInfo.age = 21;
      console.log("onBeforeUnmount", userInfo.age);
    });
    onUnmounted(() => {
      userInfo.age = 22;
      console.log("onUnmounted", userInfo.age);
    });
    const updateAge = () => {
      userInfo.age = "29";
    };
    return {
      userInfo,
      updateAge,
    };
  },
};
</script>

4、使用watch

<template>
  <input v-model="text" />
</template>
<script>
import { ref, watch } from "vue";
export default {
  setup() {
    const text = ref("0");
    watch(text, (newValue, oldValue) => {
      console.log("oldValue:", oldValue);
      console.log("newValue:", newValue);
    });
    return { text };
  },
};
</script>

5、使用watchEffect

<template>
  <input v-model="text" />
</template>
<script>
import { ref, watchEffect } from "vue";
export default {
  setup() {
    const text = ref("0");

    watchEffect(() => {
      console.log("watchEffect:", text.value);
    });
    
     // 两秒后输1
     setTimeout(() => {
       text.value = "1";
     }, 2000);

     const unwatch = watchEffect(() => {
       // 仅仅输出0
       console.log(text.value);
     });

     setTimeout(() => {
       text.value = "1";
     }, 2000);
    // 1秒后取消watch,所以上面的代码只会输出0
     setTimeout(() => {
      unwatch();
     }, 1000);

    return { text };
  },
};
</script>

watch和watchEffect的区别
1、watchEffect 类似于懒加载,数据有改变才会触发
2、watchEffect 不需要指定监听属性
3、watchEffect 获取不到新旧值(即更新前后的值)

6、使用computed

<template>
  <div>检测值:{{ fullName }}</div> 
</template>
<script>
import { computed } from "vue";
export default {
  setup() {
   const fullName = computed(()=>{
    return '小龚'
   })
    return { fullName };
  },
};
</script>

7、使用provide以及inject

// provide
<template>
  {{ info.name }}
  <button @click="addName"></button>
  <son />
</template>
<script>
import son from "./inject";
import { reactive, provide } from "vue";
export default {
  components: { son },
  setup() {
    const info = reactive({
      name: "王翠花",
    });
    const addName = () => {
      info.name += "hhh";
    };

    console.log("father:", info.name);
    provide("nameObj", info); //key,值
    provide("geolocation", {
      longitude: 90,
      latitude: 135,
    });
    return {
      info,
      addName,
    };
  },
};
</script>
// inject
<template>
  <div>son===userLocation:{{ name.name }}</div>
  <div>son===userGeolocation:{{ userGeolocation }}</div>
</template>
<script>
import { inject, computed } from "vue";
export default {
  setup() {
    const userLocation = inject("nameObj");
    const userGeolocation = inject("geolocation");
    console.log("userLocation", userLocation);
    
    const name = computed(() => {
      return userLocation;
    });
    return {
      userLocation,
      userGeolocation,
      name,
    };
  },
};
</script>

8、emit以及props的使用

// 父组件
<template>
  <!-- searchVal为子组件emit出来的值 -->
  <div class="right-box">
    <Search
      :placeholder="'请输入搜索内容'"
      :clear="true"
      :category="'search'"
      @searchVal="searchVal"
    />
  </div>
</template>
<script>
import { ref } from "vue";
import Search from "../packageInput";
export default {
  components: { Search },
  setup() {
    // 定义变量
    let searchInput = ref("");
    // 点击搜索
    const searchVal = (e) => {
      searchInput = e;
    };

    return {
      searchInput,
      searchVal,
    };
  },
};
</script>
// 子组件
<template>
  <a-input
    v-if="category === 'text'"
    v-model:value="searchVal"
    :placeholder="placeholder"
    :defaultValue="defaultValue"
    :disabled="disabled"
    :maxlength="maxlength"
    :prefix="prefix"
    :suffix="suffix"
    :size="size"
    :allow-clear="clear"
    :addon-before="addonBefore"
    :addon-after="addonafter"
    @change="inputChange"
    @pressEnter="pressEnter"
  />

  <a-input-password
    v-else-if="category === 'password'"
    v-model:value="searchVal"
    :placeholder="placeholder"
    :defaultValue="defaultValue"
    :disabled="disabled"
    :maxlength="maxlength"
    :prefix="prefix"
    :suffix="suffix"
    :size="size"
    :allow-clear="clear"
    :addon-before="addonBefore"
    :addon-after="addonafter"
    :visibilityToggle="visibilityToggle"
    @change="inputChange"
    @pressEnter="pressEnter"
  />

  <a-input-search
    v-else-if="category === 'search'"
    v-model:value="searchVal"
    :placeholder="placeholder"
    :disabled="disabled"
    :maxlength="maxlength"
    :prefix="prefix"
    :suffix="suffix"
    :size="size"
    :allow-clear="clear"
    :addon-before="addonBefore"
    :addon-after="addonafter"
    @search="search"
  />
</template>
<script>
import { ref } from "vue";
export default {
  // 接收父组件传值
  props: {
    category: String,
    placeholder: String,
    disabled: Boolean,
    maxlength: Number,
    prefix: String,
    suffix: String,
    size: String,
    clear: Boolean,
    addonBefore: String,
    addonafter: String,
  },
  setup(props, { emit }) {
    const searchVal = ref("");
    const search = (e) => {
      // emit传值,需为驼峰式写法
      emit("search-val", e);
    };
    return {
      searchVal,
      search,
    };
  },
};
</script>

9、使用router.push以及router-link

<template>
  <router-link to="/login" custom v-slot="{ navigate }">
    <div role="link" @click="navigate" class="cursor-pointer">未登录</div>
  </router-link>
</template>
<script>
import { reactive } from "vue";
import { useRouter } from "vue-router";
export default {
  setup() {
    const router = useRouter(); // 定义router
    // 跳转登录页面
    const navigate = () => {
      // 传参跳转页面跟vue2一样
      router.push({
        path: "/login",
        query: {
          e: "hhh",
        },
      });
    };

    return {  navigate };
  },
};
</script>

10、使用vuex

在日常使用vue中,我们会遇到一个接口可能多个页面能使用,这时候我们就能使用vuex去解决这个问题,下面我只描述页面中的使用,定义跟vue2x一样

<template>
  {{ store.getters.login_name }}
</template>
<script>
import { useStore } from "vuex";
export default {
  setup() {
    const store = useStore();

    store.dispatch("goLogin");
  },
};
</script>

11、使用await

在有些时候我们需要接口返回数据跟渲染同步时,我们就需要es6某个特性async await。何为async、await呢?他和Promise一样,只不过async、await不能被.then去回调,代码看起来也像同步代码。下面我们来看看在vue3.0中怎么去使用他们

const getPlayList = async e => {
      const result = await api.music.getPlaylistDetails(e);
  // 对接口返回值进行处理
      if (result.code === 200) {
        if (result.playlist.name.includes('喜欢的音乐')) {
          result.playlist.name = '我喜欢的音乐';
        }
        if (state.playListInfo.length > 0) {
          state.playListInfo = [];
        }
        state.playListInfo.push({
          id: result.playlist.id, // 歌曲id
          name: result.playlist.name, // 歌曲名
          coverImgUrl: result.playlist.coverImgUrl, // 歌单头像
          avatar: result.playlist.creator.avatarUrl, // 创建者
          nickname: result.playlist.creator.nickname, // 创建者
          createTime: tools.formatDate(result.playlist.createTime), // 创建时间
          trackCount: result.playlist.trackCount, // 歌曲数量
          playCount: result.playlist.playCount, // 播放数量
        });
      }
    };

12、赋值对象

在做项目的时候发现一个问题:接口返回值是异步的,然而我们需要同步去加载返回更新数据,这时候我们需要用到async、await去返回接口数据并处理(如何使用async、await在11点有讲解,这里不具体描述)。但我们返回值同步回来了又有一个新的问题:如何给对象赋值呢?下面我们来看看

// 你肯定是这样想的,但事实上state并没有更新到对象当中去
const getPlayList = async e => {
      const result = await api.music.getPlaylistDetails(e);
  	// 对接口返回值进行处理
      if (result.code === 200) {
        if (result.playlist.name.includes('喜欢的音乐')) {
          result.playlist.name = '我喜欢的音乐';
        }

        if (user.playListInfo.length > 0) {
          state.playListInfo = [];
        }
        user.playListInfo = {
          id: result.playlist.id, // 歌曲id
          name: result.playlist.name, // 歌曲名
          coverImgUrl: result.playlist.coverImgUrl, // 歌单头像
          avatar: result.playlist.creator.avatarUrl, // 创建者
          nickname: result.playlist.creator.nickname, // 创建者
          createTime: tools.formatDate(result.playlist.createTime), // 创建时间
          trackCount: result.playlist.trackCount, // 歌曲数量
          playCount: result.playlist.playCount, // 播放数量
        };
      }
    };
     // 监听router
     watchEffect(() => {
      getPlayList(route.query.id);
      console.log('watchEffect中的user===>', user);
    });
    console.log('return前的user===>', user);
    return { user, name, getPlayList, list };
// 我们应该这么去做
const getPlayList = async e => {
      const result = await api.music.getPlaylistDetails(e);
      if (result.code === 200) {
        if (result.playlist.name.includes('喜欢的音乐')) {
          result.playlist.name = '我喜欢的音乐';
        }

        if (user.length > 0) {
          state.length = 0;
        }

        let tag = '';
        if (result.playlist.tags.length > 1) {
          for (let i = 0; i < 1; i++) {
            tag =
              result.playlist.tags[i] +
              ' / ' +
              result.playlist.tags[i + 1] +
              ' / ' +
              result.playlist.tags[result.playlist.tags.length - 1];
          }
        }
        console.log('creator==>', result.playlist.creator);
        // 获取头部
        user.id = result.playlist.id; // 歌曲id
        user.name = result.playlist.name; // 歌曲名
        user.coverImgUrl = result.playlist.coverImgUrl; // 歌单头像
        user.avatar = result.playlist.creator.avatarUrl; // 创建者头像
        user.nickname = result.playlist.creator.nickname; // 创建者
        user.createTime = tools.formatDate(result.playlist.createTime); // 歌单创建时间
        user.trackCount = result.playlist.trackCount; // 歌曲数量
        user.playCount = result.playlist.playCount; // 播放数量
        user.description = result.playlist.description; // 简介
        user.tags = tag ? tag : '添加标签'; // 标签
        console.log('渲染==user===>', user);
        }
      }
    };
    
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值