Vue-5

Vue 3 的优势

  • 更容易维护(组合式API)
  • 更快的速度
  • 更小的体积
  • 更优的数据响应

创建 Vue 3 项目

  • 前提环境条件:已安装 16.0 或更高版本的 Node.js
node -v
  • 创建一个 Vue 应用(下面的指令将会安装并执行 create-vue )
npm init vue@latest

setup

组合式API - setup选项

  • setup 函数在什么时候执行?
<script>
export default {
  setup() {
    console.log('setup函数比八大钩子中最早执行的beforeCreate函数还要早一点')
  },

  beforeCreate() {
    console.log('我是beforeCreate函数')
  }
}
script>
  • setup 函数的"原始复杂写法"
<script>
export default {
  // 在 setup 的最后加上 return,才能使用 数据 和 函数
  setup() {
    // 数据
    const message = 'hello world'
    // 函数
    const logMessage = () => {
      console.log(message)
    }
    return {
      message,
      logMessage
    }
  }
}
script>
  • setup 函数的"语法糖写法"
<script setup>
// 数据
const message = 'hello world'
// 函数
const logMessage = () => {
  console.log(message)
}
script>

<template>
	<div>{{ message }}div>
    <button @click="logMessage">点我button>
template>

<style>
style>

reactive

接收一个对象类型的数据,返回一个响应式的对象

<script setup>
// reactive:接收一个对象类型的数据,返回一个响应式的对象
import { reactive } from 'vue'

// 对象类型
const state = reactive({
  count: 100
})

// 进行 +1 的函数
const setCount = () => {
  state.count++
}
script>

<template>
  <div>{{ state.count }}div>
  <button @click="setCount">+1button>
template>

ref

接收简单类型或者对象类型的数据传入并返回一个响应式的对象(推荐统一使用 ref )

<script setup>
// ref:接收简单类型或者对象类型的数据传入并返回一个响应式的对象
import { ref } from 'vue'

// 简单类型 或者 复杂数据类型
const count = ref(100)

// 注意:
//  1. 在脚本中访问数据,需要通过 .value 的形式
//  2. 在template中,.value不需要加
const setCount = () => {
  count.value++
}

console.log(count.value)

script>

<template>
  <div>{{ count }}div>
  <button @click="setCount">+1button>
template>

<style>
style>

computed

计算属性函数

<script setup>
// const 计算属性 = computed(() => {
//   return 计算返回结果
// })

import { computed, ref } from "vue";

// 声明数据
const list = ref([1, 2, 3, 4, 5, 6, 7, 8, 9])
console.log(list.value) // 打印list的值

// 过滤 >5 的数据
const computedList = computed(() => {
  return list.value.filter(item => item > 5)
})

script>

<template>
  <div>
    <div>原始数据:{{ list }}div>
    <div>计算后的数据:{{ computedList }}div>
  div>
template>

watch

作用:监听一个或者多个数据的变化,数据变化时执行回调函数

<script setup>
import { ref, watch } from "vue";
const count = ref(0)
const nickname = ref('张三')

const changeCount = () => {
  count.value++
}

const changeNickname = () => {
  nickname.value += '哈'
}

// 1. 监视单个数据的变化
// watch(ref对象, (newValue, oldValue) => {...})

// 2. 监视多个数据的变化
// watch([ref对象1, ref对象2], (newArr, oldArr) => {...})

script>

<template>
  <div>{{ count }}div>
  <button>改数字button>
  <div>{{ nickname }}div>
  <button>改昵称button>
template>

immediate

<script setup>
import { ref, watch } from "vue";
const count = ref(0)
const nickname = ref('张三')

const changeCount = () => {
  count.value++
}

const changeNickname = () => {
  nickname.value += '哈'
}

// immediate 一进入页面就立即执行
watch(count, (newValue, oldValue) => {
  console.log(newValue, oldValue)
}, { immediate: true })

script>

<template>
  <div>{{ count }}div>
  <button>改数字button>
  <div>{{ nickname }}div>
  <button>改昵称button>
template>

deep

  • 集体式的深度监视,只要有一个变化了就会执行函数
<script setup>
import { ref, watch } from "vue";
const count = ref(0)
const nickname = ref('张三')

const changeCount = () => {
  count.value++
}

const changeNickname = () => {
  nickname.value += '哈'
}

// deep 深度监视,默认 watch 进行的是浅层监视
//      const ref1 = ref(简单类型)  可以直接监视
//      const ref2 = ref(复杂类型)  监视不到复杂类型内部数据的变化
watch(count, (newValue, oldValue) => {
  console.log(newValue, oldValue)
}, {
  immediate: true,
  deep: true
})

script>

<template>
  <div>{{ count }}div>
  <button>改数字button>
  <div>{{ nickname }}div>
  <button>改昵称button>
template>
  • 精确的为某一个元素对象进行深度监视,它变化了才会触发函数
<script setup>
import { ref, watch } from "vue";
const userInfo = ref({
  name: 'zs',
  age: 18
})

const setUserInfo = () => {
  userInfo.value.age++
}

// 深度监视之"精准定位"
watch(() => { userInfo.value.age }, (newValue, oldValue) => {
  console.log(newValue, oldValue)
})

script>

<template>
  <div>{{ userInfo.age }}div>
  <button @click="setUserInfo">改年龄button>
template>

生命周期

选项式API 组合式API
beforeCreate/created setup
beforeMount onBeforeMount
mount onMounted
beforeUpdate onBeforeUpdate
updated onUpdated
beforeUnmount onBeforeUnmount
unmounted onUnmounted
<script setup>
import { onMounted } from 'vue';

// beforeCreate 和 created 的相关代码一律放在 setup 中
const getList = () => {
  console.log('发送请求成功')
}
getList()

// 如果有些代码需要在 mounted 生命周期中执行,就调用对应函数
onMounted(() => { console.log('mounted生命周期函数 - 逻辑1') })

// 可以使用多次 mounted,并不会冲突,它会按顺序执行
onMounted(() => { console.log('mounted生命周期函数 - 逻辑2') })
script>

<template>
  <div>div>
template>

<style>
style>

父子数据传递

父级内容

<script setup>

// 父传子
// 1. 给子组件,添加属性的方式传值
// 2. 在子组件,通过props接收

import { ref } from "vue";
import SonCom from '@/components/son-com.vue'   // 局部组件(导入进来就能用)

const money = ref(100)
const makeMoney = () => {
  money.value++
}
const reduce = () => {
  money.value--
}
script>

<template>
  <div>
    <h3>这是父组件的地盘h3>
    <hr>
    <SonCom info="父组件的余额: " :num="money" @reduceMoney="reduce">SonCom>
    <hr>
    <h3>还是父组件的地盘h3>
    <div>当前余额: {{ money }}div>
    <button @click="makeMoney">点击赚钱button>
  div>
template>

<style>
style>

子级内容

<script setup>

// 注意:由于写了 setup,所以无法直接配置 props 选项
// 所以:此处需要借助于"编译器宏"函数接收子组件传递的数据

const props = defineProps({
  info: String,
  num: Number
})

console.log(props.info)
console.log(props.num)

const emit = defineEmits(['reduceMoney'])
const payment = () => {
  emit('reduceMoney', 5)   // 通过emit触发父组件标签的reduceMoney属性
}
script>

<template>
  <div>我是子组件div>
  <div>{{ info }}{{ num }}div> 
  <button @click="payment">点击消费button>
template>

<style>
style>

模板引用

父级内容

<script setup>

import TestCom from "@/components/test-com.vue";
import { onMounted, ref } from "vue";

// 模板引用 (可以用来获取dom元素,也可以用来获取组件)
// 1. 调用ref函数,生成一个对象
const inp = ref(null)

// 3. 在加载渲染完DOM后,才能访问到绑定的元素
//    这时候我们需要使用到 生命周期钩子函数"onMounted"
onMounted(() => {
  console.log(inp.value)  // 输出绑定的元素内容 
  inp.value.focus()       // 实现:进入页面立即聚焦输入框
})

// 4. 使用同样的方法,获取组件
const testRef = ref(null)


// 6. 渲染结束后,当用户点击按钮,将触发下面"获取组件的函数"
const getCom = () => {
  console.log(testRef.value)  // 输出该组件对象
  console.log(testRef.value.num)      // 输出该组件对象中的一些数据
  console.log(testRef.value.sayHi())  // 输出该组件对象中的一些数据


}
script>

<template>
  <div>
    
    <input ref="inp" type="text">
    <button>点击让输入框聚焦button>
  div>

  
  <TestCom ref="testRef">TestCom>
  <button @click="getCom">点击获取组件button>
template>

子级内容

<script setup>

const num = 999
const sayHi = () => { console.log('hi') }

// 上面定义的数据或方法,在 


使用 defineModel

  1. 修改 vite.config.js 配置文件,在 vue( ) 括号里面加上{ script:{ defineModel: true } },具体如下所示:
vue({
      script: {
        defineModel: true
      }
    }),
  1. 重启服务
  2. 具体使用方法,如下所示
<script setup>
import MyInput from "@/components//temp.vue"
import { ref } from "vue";
const txt = ref('123456')
script>

<template>
  <div>
    <MyInput v-model="txt">MyInput>
    {{ txt }}
  div>
template>
<script setup>
import { defineModel } from "vue";
const modelValue = defineModel()

script>

<template>
  <input 
    type="text" 
    :value="modelValue" 
    @input="e => modelValue = e.target.value"
  >
template>

Pinia

概念简述

Pinia 是 Vue 的最新状态管理工具,是 Vuex 的替代品

回顾 Vuex 涉及哪些概念:
	state
	mutaions
	actions
	getters
	modules
Pinia 涉及的概念:
	state
	actions
	getters

注意:在实际开发项目的时候,关于Pinia的配置,可以在项目创建时自动添加,而手动添加的方式如下:

  1. 安装 Pinia 包: npm install pinianpm i pinia
  2. 配置 Pinia:
import { createApp } from 'vue'
import { createPinia } from 'pinia'  // 导入 Pinia 包
import App from './App.vue'

const pinia = createPinia()    // 创建 Pinia 实例
const app = createApp(App)    // 创建根实例
app.use(pinia)    // pinia 插件的安装配置
app.mount('#app')   // 视图的挂载

基本使用(store)

在 src 文件夹下创建一个 store 文件夹,在 store 里面新建一个 js 文件,这里演示为 counter.js

import { defineStore } from "pinia"
import { computed, ref } from "vue"

// 定义store
// defineStore(仓库的唯一标识,() => { ... })

export const useCounterStore = defineStore('counter', () => {
  // 声明数据 state
  const count = ref(999)

  // 声明操作数据的方法 action
  const addCount = () => count.value++
  const reduceCount = () => count.value--

  // 声明基于数据派生的计算属性 getters
  const double = computed(() => count.value * 2)

  // 与上面类似
  const msg = ref('hello pinia')
  const changeMsg = () => { msg.value += '_plus' }

  // 返回要被访问的数据
  return {
    count,
    double,
    addCount,
    reduceCount,

    msg,
    changeMsg
  }
})
  • src/App.vue
<script setup>
import Son1Com from "@/components/Son1Com.vue";
import Son2Com from "@/components/Son2Com.vue";

import { useCounterStore } from "@/store/counter.js"
const counterStore = useCounterStore()

script>

<template>
  <div>
    <h1>我是App.vue根组件 - {{ counterStore.count }} - {{ counterStore.double }}h1>
    <button @click="counterStore.changeMsg">改变button>
    {{ counterStore.msg }}
    <hr>
    <Son1Com>Son1Com>
    <Son2Com>Son2Com>
  div>
template>
  • src/components/Son1Com.vue
<script setup>
import { useCounterStore } from "@/store/counter.js"
const counterStore = useCounterStore()
script>

<template>
  <div>
    <h3>我是Son1Com子组件 - {{ counterStore.count }} <button @click="counterStore.addCount">+button>h3>
  div>
template>
  • src/components/Son2Com.vue
<script setup>
import { useCounterStore } from "@/store/counter.js"
const counterStore = useCounterStore()
script>

<template>
  <div>
    <h3>我是Son2Com子组件 - {{ counterStore.count }} <button @click="counterStore.reduceCount">-button>h3>
  div>
template>

异步实现(action)

  • src/store/channel.js
import { defineStore } from "pinia"
import { ref } from "vue";
import axios from "axios"

export const useChannelStore = defineStore('channel', () => {
  const channelList = ref([])
  const getList = async () => {
    const res = await axios.get('http://geek.itheima.net/v1_0/channels')
    
    // 解构: 在返回的信息中找到真正需要的数据
    const { data: { data: { channels } } } = res
    channelList.value = channels
  }
  return {
    channelList,
    getList
  }
})
  • src/App.vue
<script setup>

import { useChannelStore } from "@/store/channel.js"
const channelStore = useChannelStore()

script>

<template>
  <div>
    <button @click="channelStore.getList">获取数据频道button>
    <ul>
      <li v-for="item in channelStore.channelList" :key="item.id">{{ item.name }}li>
    ul>
  div>
template>

持久化存储插件

官方文档:https://prazdevs.github.io/pinia-plugin-persistedstate/zh/guide/

AI 插件

Github Copilot 插件安装步骤:

  • 登录 GitHub,试用 Copilot
  • 打开 VScode,搜索并安装插件 Copilot

Github Copilot 插件使用说明:

  • 删除键:表示不接受本次 AI 的智能生成代码
  • Tab键:表示接收本次 AI 的智能生成代码
  • Ctrl + Enter:查看更多方法

你可能感兴趣的:(#,Vue,vue.js)