创建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>