创建Vue3项目

方式一:
    使用vue-cli:vue的脚手架----->创建vue项目----->构建vue项目----->前端工具链
    创建方式还是和之前一样,Vue版本要选择Vue3的版本
方式二:
    使用vite创建:
    vite:https://cn.vitejs.dev/
        :npm create vue@latest
        
运行Vue项目:
    -vue-cli跟之前一样
    -vite 创建的:npm install   npm run dev

编程语言中的链式调用

# 编程语言的链式调用
	对象.changeName('lqz').printName().showAge()
    
# python 如何实现链式调用
	class Person:
        def changeName(self,name):
            self.name=name
            return self
        def printName(self):
            print(self.name)
            return self

setup函数

setup 的两个注意点:
	# setup什么时候执行的
    	在beforCreate之前执行一次,this是undefined
    # setup的参数
        props:值为对象,包含:组件外部传递过来,且组件内部声明接收了的属性。
        context:上下文对象
        attrs: 值为对象,包含:组件外部传递过来,但没有在props配置中声明的属性, 相当于 this.$attrs。
            slots: 收到的插槽内容, 相当于 this.$slots。
                emit: 分发自定义事件的函数, 相当于 this.$emit。
                    
总结:
    setup执行是在beforeCreate,没有this对象
    如果写setup函数,想接收父组件自定义属性传入的值,需要
        export default {
            setup(props) {
                console.log(props.msg)
            },
            props: ['msg']
        }
        
    如果是vue3的最新写法,想接收父组件自定义属性传入的值,需要
        <script setup>
        defineProps(['msg'])
        </script>
<template>
  <div class="home">
    <h1>这是首页</h1>
    <p>我叫:{{ name }}</p>
    <p>我的年龄:{{ age }}</p>
    <hr>
    <button @click="handeruserinfo">点我查看信息</button>
  </div>
</template>

<script>

export default {
  setup() {
    // 定义数据
    let name = "杨赋华"
    let age = 18
    // 定义方法
    const handeruserinfo = () => {
      console.log(name, age)
      alert(`我的名字是:${name},我的年龄是${age}`)
    }
    return {
      name, age, handeruserinfo
    }
  }
}
</script>

ref 函数

<template>
  <div class="home">
    <h1>这是首页</h1>
    <p>我叫:{{ name }}</p>
    <p>我的年龄:{{ age }}</p>
    <hr>
    <button @click="handeruserinfo">点我查看信息</button>
    <hr>
    <button @click="handeradd">点我年龄加一</button>
    <hr>
    <button @click="handerone">点我变彭于晏</button>
  </div>
</template>

<script>
import {ref} from "vue";

export default {
  setup() {
    let name = ref("杨赋华")
    let age = ref(18)
    const handeruserinfo = () => {
      console.log(name, age)
      alert(`我的名字是:${name},我的年龄是${age}`)
    }
    // 变量要具备响应式--->页面内容变化,变量和变,变量变化,页面也变
    // 普通变量,通过ref绑定响应式
    // 引用类型变量:通过reactive 绑定响应式
    const handeradd = () => {
      // 使用ref之后真正的数据就放在value中
      age.value += 1
    }
    const handerone = () => {
      name.value = "彭于晏"
    }
    return {
      name, age, handeruserinfo, handeradd, handerone
    }
  }
}
</script>

reactive函数

<template>
  <div class="home">
    <h1>这是首页</h1>
    <p>我叫:{{ data.name }}</p>
    <p>我的年龄:{{ data.age }}</p>
    <br>
    <button @click="handeradd">点我年龄++</button>
    <hr>
    <HelloWorld></HelloWorld>
  </div>
</template>

<script>
import {ref, reactive} from "vue";
import HelloWorld from "@/components/HelloWorld.vue";

export default {
  setup() {
    let data = reactive({
      name: "晁梦圆",
      age: 18
    })
    let handeradd = () => {
      data.age++
    }
    return {
      data,handeradd
    }
  },
  components: {
    HelloWorld
  }
}
/*
ref:
	作用:
		定义一个响应式数据
	语法:
		const xxx = ref("value")
	创建一个包含响应式数据的引用对象(reference,简称ref对象)
	JS中操作数据: xxx.value
	模板中读取数据: 不需要.value,直接:<div>{{xxx}}</div>
	备注:
		接受的数据可以是:基本类型(值类型),也可以是对象(引用类型)类型。
		
reactive:
	作用:
		定义一个对象类型的响应式数据(基本类型不要用它,要用ref函数)
	语法:
		const 代理对象 = reactive(源对象)接收一个对象(或数组),返回一个代理对象(Proxy的实例对象,简称proxy对象)
	reactive定义的响应式数据是“深层次的”,无论套多少层,都具备响应式
	
# 总结:
  如果用基本数据类型:数字,字符串,布尔,用ref做响应式
  如果是对象类型,用ref和reactive都可以,但是建议使用reactive
  如果使用ref包裹对象类型,多了一层value

*\
</script>

计算监听属性

<template>
  <div class="home">
    <h1>这是首页</h1>
    <input type="text" v-model="name.fisterName">
    <input type="text" v-model="name.lastName">
    <hr>
    <input type="text" v-model="fullName">
    <hr>
    <button @click="age++">点我年龄++</button>
  </div>
</template>

<script>
import {ref, reactive, computed, watch, watchEffect} from "vue";

export default {
  setup() {
    let name = reactive({
      fisterName: "彭于晏",
      lastName: "大帅哥"
    })
    let fullName = computed({
      get() {
        return name.fisterName + "_" + name.lastName
      },
      set(value) {
        // 当我修改fullName的时候,我的fisterName和lastName也发生改变
        const nameArr = value.split("_")
        name.fisterName = nameArr[0]
        name.lastName = nameArr[1]
      }
    })
    let age = ref(19)
    // 监听属性
    watch(age, (newValue, oldValue) => {
      console.log(newValue)
      console.log(oldValue)
    })
    // 监听对象
    watch(() => name.fisterName, (newValue, oldValue) => {
      console.log(oldValue)
      console.log(newValue)
    })
    // watchEffect函数
    watchEffect(() => {
      const x1 = age.value
      const x2 = name.fisterName
      console.log('watchEffect配置的回调执行了')
    })
    return {
      name, fullName, age
    }
  }
}
</script>

生命周期

# vue2 生命周期---8个

# vue3 变了
	-想把生命周期写下setup函数中
    	
    -把生命周期写在配置项中
        beforeDestroy改名为 beforeUnmount
        destroyed改名为 unmounted
        
        beforeCreate
        created
        beforeMount 
        mounted
        beforeUpdate
        updated
        beforeUnmount 
        unmounted
<template>
  <div class="home">
    <h1>首页</h1>
  </div>
</template>

<script>

import axios from "axios";
import {
  computed,
  watch,
  reactive,
  ref,
  watchEffect,
  onBeforeMount,
  onMounted,
  onBeforeUpdate,
  onUpdated,
  onBeforeUnmount,
  onUnmounted
} from 'vue'

export default {
  name: 'HomeView',
  setup() {

    // 第一个beforeCrete
    console.log('我是beforeCrete')

    // 第二个Creted
    let name = ref('lqz')
    console.log('Creted')
    // axios.get().then(res => {
    //   name.value = res.data.name
    // })

    // 直接启动定时器
    let t = setInterval(() => {
          console.log('lqz')
        }, 3000
    )
    // 第三个:onBeforeMount
    onBeforeMount(() => {
      console.log('挂载了')
    })

    onBeforeUnmount(() => {
      clearInterval(t)
      t = null

    })


    return {}


  },


}


</script>

torefs

<template>
  <div class="home">
    <h1>首页</h1>
    {{ name }}------>{{ age }}
  </div>
</template>

<script>
import {ref, reactive, computed, watch, watchEffect, toRefs} from "vue";
import axios from "axios";

export default {
  name: "HomeView",
  setup() {
    let data = reactive({
      name: "XXX",
      age: 18
    })
    return {
      ...toRefs(data)
    }
  }
}
// 对象的解压赋值
let data = {"name": "XXX", "age": 18}
let dict = {...data, hobby: "篮球"}
console.log(dict) // {name: 'XXX', age: 18, hobby: '篮球'}
</script>

setup写法

# 以后vue3推荐,把setup函数的代码,直接写在script中
<script setup>
定义变量
写函数
不用return,在html中直接使用
</script>

# 使用组件,直接导入,不需要配置,直接用即可
import HelloWorld from "../components/HelloWorld.vue";
在html中直接用:<HelloWorld msg="NB"></HelloWorld>

# 自定义属性,在子组件中接收
    <script setup>
    defineProps({
      msg: {
        type: String,
        required: true
      }
    })
    </script>