Vue3基础(API风格、监听、生命周期、toRefs、组件通信、插槽、axios,Promise)
目录
- Vue3基础(API风格、监听、生命周期、toRefs、组件通信、插槽、axios,Promise)
 - API 风格
 - 选项式API
 - 组合式API
 - 混合式
 
- 事件监听
 - watchEffect
 
- 生命周期
 - 选项式API
 - 组合式API
 
- toRefs
 - 父传子defineProps
 - 子传父defineEmits
 - 插槽
 - 具名插槽
 
- axios
 - async和await
 - axios其它配置项
 
- Promise
 
API 风格
选项式API和组合式API都适用于不同场景,生产项目中,低复杂度场景用选项式API,单页应用用组合式API+单文件组件。
选项式API
该方法也是Vue2中所使用的,其特点是例如 data、methods 和 mounted等对象所定义的属性都会暴露在函数内部的 this 上,它会指向当前的组件实例
<script>
export default {
  data(){
    return {
      count:100
    }
  },
  methods:{
    handleAdd(){
      this.count++
    }
  }
}
</script>
<template>
  <div class="card">
    <button type="button" @click="handleAdd">count is {{ count }}</button>
  </div>
</template>
 
组合式API
单文件组件中组合式API通常和
<script setup>
import { ref } from 'vue'
const count = ref(0)
const name = reactive({'name': '张三'})
function handleChange(){
  count.value++
  name.name = '李四'
}
</script>
<template>
  <div class="card">
    <button type="button" @click="handleChange">count is {{ count }},name is {{name.name}}</button>
  </div>
</template>
 
混合式
<script>
import {reactive, ref} from 'vue'
export default {
  setup() {
    const count = ref(0)
    const name = reactive({'name': '张三'})
    return {
      count,
      name
    }
  },
  methods: {
    handleAdd() {
      this.count++
      this.name.name = '李四'
    }
  }
}
</script>
<template>
  <div class="card">
    <button type="button" @click="handleAdd">count is {{ count }},name is {{ name.name }}</button>
  </div>
</template>
 
事件监听
watch 函数用于监视一个数据,并在数据变化时执行特定的逻辑
<script setup>
import {reactive, ref, watch} from 'vue'
const count = ref(0)
const name = reactive({'name': '张三'})
function handleAdd() {
  count.value++
  name.name = '李四'
}
watch(count, (newValue, oldValue) => {
  console.log('count数据发生了变化,老数据是:' + oldValue + '新数据是:' + newValue)
})
watch(()=>name.name, (newValue, oldValue) => {
  console.log('count数据发生了变化,老数据是:' + oldValue + '新数据是:' + newValue)
})
</script>
<template>
  <div class="card">
    <button type="button" @click="handleAdd">count is {{ count }},name is {{name.name}}</button>
    <p>
      Edit
      <code>components/HelloWorld.vue</code> to test HMR
    </p>
  </div>
</template>
 
watchEffect
watchEffect函数不用指定监听谁,只要watchEffect内部用了某个变量,某个变量发送变化,就会触发
import { watchEffect } from 'vue'
watchEffect(()=>{
    const x1 = sum.value
    const x2 - person.name
	console.log('某个数据被改变')
})
 
生命周期
选项式API
- beforeCreate:组件实例被创建,但是数据和事件方法均未初始化时被调用
 - created:数据观测 (data observer) 和事件配置完成,但尚未挂载到DOM时被调用
 - beforeMount:模板编译完成,但尚未将模板挂载到DOM时被调用
 - mounted:组件挂载到DOM之后时被调用
 - beforeUpdate:数据更新但尚未重新渲染视图时被调用
 - updated:数据更改导致重新渲染和打补丁完成时被调用
 - beforeUnmount:组件卸载之前时被调用
 - unmounted:组件卸载之后时被调用
 
组合式API
官方文档:组合式API生命周期钩子

- onMounted():在组件挂载完成后执行
 - onUpdated():在组件响应状态变更后执行
 - onUnmounted():当组件实例被卸载后调用
 - onBeforeMount():组件被挂载之前调用
 - onBeforeUpdate():组件更新前调用
 - onBeforeUnmount():组件实例被卸载前调用
 - onErrorCaptured():捕获了后代组件传递错误时调用
 - onRenderTracked():组件渲染过程中追踪到响应式依赖时被调用
 - onRenderTriggered():响应式依赖的变更触发了组件渲染时调用
 - onActivated():若组件实例是 缓存树的一部分,当组件被插入到 DOM 中时调用
 - onDeactivated():若组件实例是 缓存树的一部分,当组件从DOM 中移除时调用
 - onServerPrefetch():组件实例在服务器上被渲染之前调用
 
示例:
<script setup>
import { onMounted } from 'vue'
onMounted(() => {
  console.log(`the component is now mounted.`)
})
</script>
 
toRefs
toRefs的作用将一个包含响应式对象属性的普通对象转换为包含 ref 对象的普通对象,通俗一点就是将reactive包裹的对象全部转换成ref对象
其意义在于当组件引用这些属性时能够保持其响应性
<script>
import {reactive, ref, toRefs} from 'vue'
export default {
  setup() {
    const data = reactive({
      count : 0,
      name : {'name': '张三'}
    })
    const handleChange = ()=>{
      data.count++
      data.name.name = '李四'
      console.log(toRefs(data).count.value)
      console.log(toRefs(data).name.value.name)
    }
    return {
      ...toRefs(data),handleChange
    }
  },
}
</script>
<template>
  <div class="card">
    <button type="button" @click="handleChange">count is {{ count }},name is {{ name.name }}</button>
  </div>
</template>
 
...toRefs(data):toRefs(data)是将data中的数据全部转成ref包裹的对象,使其带有响应性,name : {'name': '张三'}本身就是对象且带有响应性因此不会对其造成影响,...是展开运算符,它的作用是将toRefs(data)展开
// 用...展开
return {
      ...toRefs(data),handleChange
    }
// 没用...的写法
const count = toRefs(data).count
const name = toRefs(data).name
return {
  count, name, handleChange
}
 
父传子defineProps
父组件:
<script setup>
// 导入子组件
import HelloWorld from './components/HelloWorld.vue'
const info = '你好'
</script>
<template>
  <HelloWorld :msg="info" />
</template>
 
子组件:
<script setup>
import {reactive, ref, toRefs, defineProps} from 'vue'
// defineProps定义传给子组件的属性
defineProps(['msg'])
const count = ref(0)
const name = reactive({'name': '张三'})
const handleChange = () => {
  count.value++
  name.name = '李四'
}
</script>
<template>
  <div class="card">
      // 调用父组件的属性
    <p>{{ msg }}</p>
    <button type="button" @click="handleChange">count is {{ count }},name is {{ name.name }}</button>
  </div>
</template>
 
子传父defineEmits
子组件:
<script setup>
import {reactive, ref, defineEmits} from 'vue'
const name = reactive({'name': '张三'})
// 创建defineEmits实例并将自定义事件名取为myevent
let $emit = defineEmits(['myevent'])
function handleSend() {
  // myevent:事件名,name.name:任意参数
  $emit('myevent', name.name)
}
</script>
<template>
  <div class="card">
    <button type="button" @click="handleSend">点我给父组件发数据</button>
  </div>
</template>
 
父组件:
<script setup>
import son from './components/son.vue'
import {ref} from "vue";
const receivedName = ref('')
const handleGetson = (name) => {
  // 这个name就是子组件传过来的数据
  // 将原name替换为子组价的name
  receivedName.value = name
}
</script>
<template>
  <div>
    <p>{{receivedName}}</p>
	// son标签必须是子组件,意为收到数据后触发handleGetson方法
    <son @myevent="handleGetson"/>
  </div>
</template>
 
插槽
主组件
<script setup>
import FancyButton from './components/FancyButton.vue'
</script>
<template>
  <div>
    // 在FancyButton内定义插槽内容
    <FancyButton>
      按钮
    </FancyButton>
  </div>
</template>
 
FancyButton组件
<script setup>
function sayHello() {
  console.log('你好')
}
</script>
<template>
  <div class="card">
    <button @click="sayHello">
      // 插槽出口
      <slot></slot>
    </button>
    <p>上面是插槽</p>
  </div>
</template>
 
实际效果就相当于:
<button @click="sayHello">
	按钮
</button>
 
具名插槽
v-slot:buttonName指定要使用的插槽slot name="buttonName"为插槽命名
<button @click="sayHello">
  <slot name="buttonName"></slot>
</button>
 
<FancyButton v-slot:buttonName>
	按钮
</FancyButton>
 
axios
基础示例:使用前先安装npm install axios
<script setup>
import axios from "axios"
function sendAxios() {
  axios.get('https://jsonplaceholder.typicode.com/todos/1').then(res => {
    console.log('请求成功' + res.data)
  }).catch(error => {
    // 处理请求失败的情况
    console.error('请求失败:', error);
  })
}
</script>
<template>
  <div class="card">
    <button @click="sendAxios">
      发送请求
    </button>
  </div>
</template>
 
post请求:
axios.post('https://jsonplaceholder.typicode.com/posts', {
  body: 'bar',	// 请求体
  userId: 1
})
.then(response => {
  console.log('成功发送 POST 请求:', response.data);
})
.catch(error => {
  console.error('发送 POST 请求失败:', error);
});
 
async和await
<script setup>
import axios from "axios"
const sendAxios = async () => {
  try {
    const response = await axios.get('https://jsonplaceholder.typicode.com/todos/1');
    console.log(response)
  } catch (error) {
    console.error('请求失败:', error);
  }
}
</script>
<template>
  <div class="card">
    <button @click="sendAxios">
      发送请求
    </button>
  </div>
</template>
 
axios其它配置项
常用参数:
axios({
    url:'地址',
    method:'post',
    headers: {'token': 'adsfa.adsfa.adsf',contentType:'application/json'},
    params: {name: lqz,age:19},
    data: {firstName: 'Fred'},
    timeout: 1000, 
})
 
更多参数
Promise
- resolve:Promise状态成功时会将成功结果传递给
then方法中的成功处理函数 - reject:Promise状态失败时会将失败结果传递给
catch方法 
<script setup>
function handlePromise() {
  const myPromise = new Promise((resolve, reject) => {
    const randomNum = Math.random()
    if (randomNum > 0.5) {
      // 将randomnum传给.then方法
      resolve(randomNum)
    } else {
      // 将error信息传给.catch方法
      reject(new Error('数据小于0.5'))
    }
  })
  myPromise.then((res) => {
    console.log('操作成功:' + res)
  }).catch((error) => {
    console.log('操作失败:' + error.message)
  })
}
</script>
<template>
  <div class="card">
    <button @click="handlePromise">
      调用Promise
    </button>
  </div>
</template>
olve, reject) => {
    const randomNum = Math.random()
    if (randomNum > 0.5) {
      // 将randomnum传给.then方法
      resolve(randomNum)
    } else {
      // 将error信息传给.catch方法
      reject(new Error('数据小于0.5'))
    }
  })
  myPromise.then((res) => {
    console.log('操作成功:' + res)
  }).catch((error) => {
    console.log('操作失败:' + error.message)
  })
}
</script>
<template>
  <div class="card">
    <button @click="handlePromise">
      调用Promise
    </button>
  </div>
</template>
                


















