Vue3基础1

1、optionsApi 与 Composition Api

选项式与组合式

组合就是一个一个 的函数 ,每个函数里都有 data,methods,compute 等等

2、拉开序幕的setup

setup执行时机 在 beforeCreate之前

<template>
  <div class="person">
    <h2>姓名:{{ name }}</h2>
    <h2>年龄:{{ age }}</h2>

    <button @click="changeName">修改名字</button>
    <button @click="changeAge">修改年龄</button>
    <button @click="showTel">查看联系方式</button>
  </div>
</template>

<script lang="ts">
export default {
  name: "Person",
  setup() {
    //setup 函数中的this是undefined vue3中已经弱化this了
    //数据,原来是写在data中的,此时的name,age,tel都不是响应式的数据
    //数据
    let name = "张三";//注意此时的name不是响应式的
    let age = 13;//注意此时的age不是响应式的
    let tel = "123123123";

    function changeName() {
      name = "李四";//注意这样修改name,页面是没有变化的,因为name不是响应式的
    }

    function changeAge() {
      age = 20;
    }

    function showTel() {
      alert(tel);
    }

    return {
      name,
      age,
      changeName,
      changeAge,
      showTel,
    };
  },
  //选项式,配置式写法
  //   data() {
  //     return {
  //       name: "张三",
  //       age: 18,
  //       tel: "123456",
  //     };
  //   },
  //   methods: {
  //     changeAge() {
  //       this.age = 13;
  //     },
  //     changeName() {
  //       this.name = "zhang-san";
  //     },
  //     showTel() {
  //       alert(this.tel);
  //     },
  //   },
};
</script>

<style scoped>
.person {
  background-color: skyblue;
  box-shadow: 0 0 10px;
  border-radius: 10px;
  padding: 20px;
}
button {
  margin: 0 5px;
}
</style>

3.Setup语法糖

<template>
  <div class="person">
    <h2>姓名:{{ name }}</h2>
    <h2>年龄:{{ age }}</h2>

    <button @click="changeName">修改名字</button>
    <button @click="changeAge">修改年龄</button>
    <button @click="showTel">查看联系方式</button>

  </div>
</template>

<script lang="ts">
export default {
  name: "Person",
 
  
};
</script>

<script  lang="ts" setup>
    

let name = "张三"; //注意此时的name不是响应式的
let age = 13; //注意此时的age不是响应式的
let tel = "123123123";

function changeName() {
  name = "李四"; //注意这样修改name,页面是没有变化的,因为name不是响应式的
}

function changeAge() {
  age = 20;
}

function showTel() {
  alert(tel);
}



</script>



<style scoped>
.person {
  background-color: skyblue;
  box-shadow: 0 0 10px;
  border-radius: 10px;
  padding: 20px;
}
button {
  margin: 0 5px;
}
</style>

但还是太麻烦,为了一个名字多写几行代码

我们安装一个插件

npm i  vite-plugin-vue-setup-extend -D

-D 代表是开发时用的插件, 打包以后就不用了

在配置文件里面配置一下插件

import { fileURLToPath, URL } from 'node:url'

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import VueSetupExtend from 'vite-plugin-vue-setup-extend'
// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    VueSetupExtend()
  ],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    }
  }
})

<template>
  <div class="person">
    <h2>姓名:{{ name }}</h2>
    <h2>年龄:{{ age }}</h2>

    <button @click="changeName">修改名字</button>
    <button @click="changeAge">修改年龄</button>
    <button @click="showTel">查看联系方式</button>

  </div>
</template>



<!-- 会自动暴露出去 -->
<script  lang="ts" setup  name="Person123">
    

let name = "张三"; //注意此时的name不是响应式的
let age = 13; //注意此时的age不是响应式的
let tel = "123123123";

function changeName() {
  name = "李四"; //注意这样修改name,页面是没有变化的,因为name不是响应式的
}

function changeAge() {
  age = 20;
}

function showTel() {
  alert(tel);
}



</script>



<style scoped>
.person {
  background-color: skyblue;
  box-shadow: 0 0 10px;
  border-radius: 10px;
  padding: 20px;
}
button {
  margin: 0 5px;
}
</style>

 4.ref响应式数据(定义基本类型数据)

<template>
  <div class="person">
    <h2>姓名:{{ name }}</h2>
    <h2>年龄:{{ age }}</h2>

    <button @click="changeName">修改名字</button>
    <button @click="changeAge">修改年龄</button>
    <button @click="showTel">查看联系方式</button>
  </div>
</template>



<!-- 会自动暴露出去 -->
<script  lang="ts" setup  name="Person">
import { ref } from "vue";

let name = ref("张三"); //注意此时的name不是响应式的
let age = ref(13); //注意此时的age不是响应式的
let tel = "123123123";

function changeName() {
  name.value = "李四"; //注意这样修改name,页面是没有变化的,因为name不是响应式的
}

function changeAge() {
  age.value = 20;
}

function showTel() {
  alert(tel);
}
</script>



<style scoped>
.person {
  background-color: skyblue;
  box-shadow: 0 0 10px;
  border-radius: 10px;
  padding: 20px;
}
button {
  margin: 0 5px;
}
</style>

5.reactive (引用类型的数据)

<template>
  <div class="person">
    <div>一辆{{ car.brand }}车,价值{{ car.price }}万</div>
    <button @click="changePrice">修改汽车的价格</button>
    <hr />
    <h2>游戏列表</h2>
    <ul>
      <li v-for="game in games" :key="game.id">
        {{ game.name }}
      </li>
    </ul>
    <button @click="changeGame">改变第三个游戏的名字</button>
  </div>
</template>



<!-- 会自动暴露出去 -->
<script  lang="ts" setup  name="Person">
import { reactive } from "vue";
let car = reactive({ brand: "奔驰", price: 100 });
let games = reactive([
  { id: "001", name: "LOL" },
  { id: "002", name: "CS" },
  { id: "003", name: "CF" },
]);

function changePrice() {
  car.price += 10;
}

function changeGame() {
  games[2].name = '逆战';
}
</script>



<style scoped>
.person {
  background-color: skyblue;
  box-shadow: 0 0 10px;
  border-radius: 10px;
  padding: 20px;
}
button {
  margin: 0 5px;
}
</style>

 6.ref 定义对象类型的数据

<template>
  <div class="person">
    <div>一辆{{ car.brand }}车,价值{{ car.price }}万</div>
    <button @click="changePrice">修改汽车的价格</button>
    <hr />
    <h2>游戏列表</h2>
    <ul>
      <li v-for="game in games" :key="game.id">
        {{ game.name }}
      </li>
    </ul>
    <button @click="changeGame">改变第三个游戏的名字</button>
  </div>
</template>



<!-- 会自动暴露出去 -->
<script  lang="ts" setup  name="Person">
import { ref } from "vue";
let car = ref({ brand: "奔驰", price: 100 });
let games = ref([
  { id: "001", name: "LOL" },
  { id: "002", name: "CS" },
  { id: "003", name: "CF" },
]);

function changePrice() {
  car.value.price += 10;
}

function changeGame() {
  games.value[2].name = '逆战';
}
</script>



<style scoped>
.person {
  background-color: skyblue;
  box-shadow: 0 0 10px;
  border-radius: 10px;
  padding: 20px;
}
button {
  margin: 0 5px;
}
</style>

7.ref对比reactive

这个开启能让ref自动加上 value

8.计算属性

<template>
  <div class="person">

    姓: <input type="text" v-model="firstName"><br>
    名: <input type="text" v-model="lastName"><br>
    <button @click="changeFullName">将全名改为li-4</button>
    全名: <span>{{ fullName }}</span>
  </div>
</template>



<!-- 会自动暴露出去 -->
<script  lang="ts" setup  name="Person">
 import { ref ,computed} from 'vue'

 let firstName = ref('张');
 let lastName = ref('三');

 //这么定义的fullName 是只读的不允许修改的
//  let fullName = computed(()=>{
//    return firstName.value +'-'+ lastName.value;
//  })

//也是一个ref响应式数据
 let fullName = computed({
   get(){
     return firstName.value +'-'+ lastName.value;
   },
   set(value){
      const [first,last] = value.split('-')
      firstName.value = first;
      lastName.value = last;
   }
 })


function changeFullName(){
  console.log(fullName.value);
  fullName.value = 'li-4';
  
  
}


</script>



<style scoped>
.person {
  background-color: skyblue;
  box-shadow: 0 0 10px;
  border-radius: 10px;
  padding: 20px;
}
button {
  margin: 0 5px;
}
</style>

9.监听WatchEffect

<template>
  <div class="person">
    <h2>需求:当水温达到60度,或水位达到80cm 时,给服务器发请求</h2>
    <h2>当前水温为{{ tmp }} ℃</h2>
    <h2>当前水位为{{ height }} cm</h2>
    <button @click="changeTmp">水温+10</button>
    <button @click="changeHeight">水位+10</button>
  </div>
</template>



<!-- 会自动暴露出去 -->
<script  lang="ts" setup  name="Person">
import { ref, watch, watchEffect } from "vue";

const tmp = ref(10);
const height = ref(0);

function changeTmp() {
  tmp.value += 10;
}
function changeHeight() {
  height.value += 10;
}
//watch实现
// watch([tmp,height],(value)=>{
//  // 从value中获取最新的temp值、height值
//  const [newTemp,newHeight] = value
//     // 室温达到60℃,或水位达到80cm,立刻联系服务器
//     if(newTemp >= 60 || newHeight >= 80){
//       console.log('联系服务器')
//     }

// })

//watchEffect实现 一上来会执行一遍
watchEffect(() => {
  console.log("@");
  //这两个数据变化的时候,这个函数的回调会执行一次
  if (tmp.value >= 60 || height.value >= 80) {
    console.log("联系服务器");
  }
});
</script>



<style scoped>
.person {
  background-color: skyblue;
  box-shadow: 0 0 10px;
  border-radius: 10px;
  padding: 20px;
}
button {
  margin: 0 5px;
}
</style>

10.ref属性

Person组件 

<template>
  <div class="person">
      <h1>中国</h1>
      <h2 ref="titie2">北京</h2>
      <h3>尚硅谷</h3>

      <button @click="showLog">点我输出H2</button>
  </div>
</template>



<!-- 会自动暴露出去 -->
<script  lang="ts" setup  name="Person">

import { ref ,defineExpose} from "vue";
//创建一个 title2,用于存储ref标记的内容

let titie2 = ref();
let a = ref(1);
let b = ref(2);
let c = ref(3);
  function showLog(){
      // console.log(document.getElementById('titie2'));
      console.log(titie2.value);
      
      

  }

  //要暴露出去,父组件才能看到子组件实例暴露的数据
  defineExpose({
      a,
      b,
      c
  })
  

</script>



<style scoped>
.person {
  background-color: skyblue;
  box-shadow: 0 0 10px;
  border-radius: 10px;
  padding: 20px;
}
button {
  margin: 0 5px;
}
</style>

 App组件

<template>
    <h2 ref="title2">你好</h2>
    <button @click="showLog">点击输出Person组件</button>
     <Person ref="ren"/>
</template>

<script lang="ts" setup name="App">
//js 或 ts
import Person from './components/Person.vue';
import {ref,watchEffect} from 'vue';

let title2 = ref();
let ren = ref();

function showLog(){
    console.log(ren.value);
}


</script>

<style scoped>
/* css */
.app{
    background-color: #ddd;
    box-shadow: 0 0 10px;
    border-radius: 10px;
    padding: 20px;
}
</style>

11.回顾TS 接口 类 泛型 

但是得在 

{
  "compilerOptions": {
    // ...
    "baseUrl": "./",  // 这里需要配置
    "paths": {
      "@/*": ["./src/*"]  // 这里需要配置
    }
    // 如果baseUrl设置为'src',那paths就应该配置为{"@/*": "./*"},如下:
    // "baseUrl": "src",
    // "paths": {
    //  "@/*": ["./*"]
    // }
    // 相关baseUrl,paths说明请查看官方文档
  },
  // include也需要配置以下:
  "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
  "exclude": ["node_modules"]
}

加上上面的配置 ,这样 @/ 是 src 目录 而且不会飘红

回顾

<template>
  <div class="person">???</div>
</template>



<!-- 会自动暴露出去 -->
<script  lang="ts" setup  name="Person">
import { type PersonInter,type PersonS } from "@/types";

// let person: PersonInter = {
//   id: "01",
//   name: "张三",
//   age: 18,
// };

// let personList: Array<PersonInter> = [
//   {
//     id: "01",
//     name: "张三",
//     age: 18,
//   },
//   {
//     id: "02",
//     name: "李四",
//     age: 19,
//   },
// ];

 
let personList: PersonS = [
  {
    id: "01",
    name: "张三",
    age: 18,
  },
  {
    id: "02",
    name: "李四",
    age: 19,
  },
];







</script>



<style scoped>
.person {
  background-color: skyblue;
  box-shadow: 0 0 10px;
  border-radius: 10px;
  padding: 20px;
}
button {
  margin: 0 5px;
}
</style>

 

//定义了一个接口,用于限制person对象的具体属性
export  interface PersonInter{
    id:string,
    name:string,
    age:number
}

// export type PersonS = Array<PersonInter>

export type PersonS = PersonInter[]
{
  "compilerOptions": {
    // ...
    "baseUrl": "./",  // 这里需要配置
    "paths": {
      "@/*": ["./src/*"]  // 这里需要配置
    }
    // 如果baseUrl设置为'src',那paths就应该配置为{"@/*": "./*"},如下:
    // "baseUrl": "src",
    // "paths": {
    //  "@/*": ["./*"]
    // }
    // 相关baseUrl,paths说明请查看官方文档
  },
  // include也需要配置以下:
  "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
  "exclude": ["node_modules"]
}

12.props 使用

<template>
  <div class="person">
    <ul>
      <li v-for="item in personList" :key="item.id">
        {{ item.id }} -- {{ item.name }} -- {{ item.age }}
      </li>
    </ul>
  </div>
</template>



<!-- 会自动暴露出去 -->
<script  lang="ts" setup  name="Person">
//带有 define开头的函数不用引入 在 vue3 里叫做宏函数 可以直接使用
  import {defineProps,withDefaults} from 'vue'
  import {type PersonS} from '@/types'

  //第一种写法 接受list,a 同时将props保存起来
//  let x = defineProps(['personList','a'])

// 第二种写法 限制类型
// let x = defineProps<{
//   personList?:PersonS,//可空
//   a:string
// }>()

//第三种写法 接受list+限制类型+限制必要性+指定默认值

 
let x = withDefaults(defineProps<{
  personList?:PersonS,//可空
  a:string
}>(),{
  personList:()=>
    [{
    id:'009',
    name:'王五',
    age:20
  }],
  a:'哈哈哈'
  
})
 console.log(x.a);
 


</script>



<style scoped>
.person {
  background-color: skyblue;
  box-shadow: 0 0 10px;
  border-radius: 10px;
  padding: 20px;
}
button {
  margin: 0 5px;
}
</style>
<template>
     <Person :person-list="personList" :a="'哈哈'"/>
</template>

<script lang="ts" setup name="App">
//js 或 ts
import Person from './components/Person.vue';
import {type PersonS} from '@/types';
import {reactive} from 'vue';

//可以传入泛型
let personList = reactive<PersonS>([
     {
          id:'001',
          name:'张三',
          age:18
     },
     {
          id:'002',
          name:'李四',
          age:19
     }
     ,
     {
          id:'003',
          name:'王五',
          age:20,
     }

])

</script>

<style scoped>

</style>

13.生命周期

<template>
  <div class="person">
    <h2>当前求和为:{{ sum }}</h2>
    <button @click="add">点我加一</button>
  </div>
</template>



<!-- 会自动暴露出去 -->
<script  lang="ts" setup  name="Person">
import {
  ref,
  onBeforeMount,
  onMounted,
  onBeforeUpdate,
  onUpdated,
  onBeforeUnmount,
  onUnmounted,
} from "vue";

let sum = ref(0);

//创建 beforeCreate created
console.log("创建");

//挂载之前
onBeforeMount(() => {
  console.log("挂载之前");
});

//挂载完毕
onMounted(() => {
  console.log("挂载完毕");
});
//更新之前
onBeforeUpdate(() => {
  console.log("更新之前");
});

//更新完毕
onUpdated(() => {
  console.log("更新完毕");
});

//卸载之前
onBeforeUnmount(() => {
  console.log("卸载之前");
});

//卸载完毕
onUnmounted(() => {
  console.log("卸载完毕");
});

function add() {
  sum.value++;
}
</script>



<style scoped>
.person {
  background-color: skyblue;
  box-shadow: 0 0 10px;
  border-radius: 10px;
  padding: 20px;
}
button {
  margin: 0 5px;
}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值