文章目录
Vue3
项目构建工具
Vite
npm init vite-app 项目名称
cd vite_vue3|项目名称
npm install (or `yarn`)
npm run dev (or `yarn dev`)
步骤:
在/*创建应用实例对象-app(类似于之前的vm)*/
`vue2`中创建应用实例的方法是:
new Vue({
render:h =>h(App)
}).$mount('#app')
/**而在vue3之中是以一种工厂模式创建应用实例对象**/
createApp(App).mount('#app')
合成API
-
理解:vue3的一个新的配置项,所要用到的数据,方法等等都要配置在这里面
-
setup函数有两个返回值:
若返回一个对象,则对象中的属性,方法,在模板中均可使用
若返回一个渲染函数:则可以自定义渲染的内容
export default(){
name:'APP',
setup(){
let name = 'xxx'
let people = {
sex:'男'
}
function a(){
alert(1)
}
return{
name,
a//返回数据和方法等等
}
}
}
/但是此时的属性不是一个响应式的数据,
ps 1. let name = ref('xxx') 则 name变成了refimpl的实例对象
将数据用ref包裹之后,数据就变成的响应式的数据
如果要修改name的值的话就用 name.value = 'zhangsan'
原理:Reflmpl{....value} 使用get和set
2.如果是属性是一个对象类型,是将ref()中传入的对象变成一个代理对象Proxy
注意: ref用于处理基本数据类型和对象数据类型,但是处理对象数据类型的时候,也会求助reactive将其转化为proxy代理对象
reactive用于处理对象数据类型,响应式的类型是深层次
/**const 代理对象 = reactive(源对象)
将数据用ref包裹之后,数据就变成的响应式的数据
- 打印ref包裹的数据,这个value数据代理才是实现响应式的关键
-------------------------reactive和ref函数的比较
ref要通过.value修改值,而reactive直接修改
reactive不能修饰基本类型的数据,只能修饰对象类型和数组类型
在Vue2中直接添加一个对象的属性或者通过数组下标修改值,不能完成响应式而reactive解决了这个问题
vue3的响应式原理
const p:代理目标对象 = new Proxy(person:源数据对象,{
//读取某个属性的时候会调用
get(target,propName){
return Reflect.get(target,propName)|target[propName]
},
//修改目标对象上的某个属性的时候或者新增某个属性的时候
set(target,propName.value){
target[propName]= value
},
deleteProperty(target,propName){
//删除某个属性的时候会调用
return (Boolean) delete target[propName]
}
}),
setup的两个注意点
-
setup的执行的时机
在beforeCreated之前执行一次。this是undefined
-
setup的参数
第一个参数是props:自定义属性,配置项中必须声明props配置项
第二个参数是:
计算属性 和监视:computed,watch
- 在vue3之中,想要用到计算属性的话,需要单独的引入
import {computed } from 'vue'
🌰如果要计算一个fullname:
let fullname = computed(()=>{ //在setup中this指向undefined,所以箭头函数还是普通函数都可以
return xxxx
})
/***完整配置
如果考虑修改计算属性,如v-modle绑定 v-modle = fullname
computed({
get(){
return xxx
}
set(value){
对计算属性依赖的每一个属性进行修改,不然读取的时候还是原值
}
})
-
在vue3中,watch可以是一个函数
watch(name:要监视的属性,(newV,oldV)=>{回调函数},{监视的配置项})//不用接受返回值,体现了watch是一种行为 ps:要监视多个属性的话,直接写多个上述函数 或者 watch([name,age],(new:变化新值的数组,old:变化旧值的数组)=>{}) ---------------------------------------- watch:监视reactive所定义的一个响应式数据(对象类型),无法准确获得oldvalue,强制开启了深度监视 ------ 如果要监视reactive定义的对象数据中的某一个值 列子: let people = reactive({ name:'xx', age:18, firend:{ name:'xxx', age:20 } }) 想要监视name,不能watch(people.name,()=>{},{}) 因为people是reactive定义的,但是people.name不是.`can only be a getter/effect function, a ref, a reactive object, or an array of these types.` 应该传入 ()=>people.name ---deep 无效和有效的两种情况 如果直接监视 reactive定义的对象属性如上述的people,deep默认强制开启 但是如果监视reactive定义的对象中的一个对象属性如firend,则deep可以选择 如果直接监视 ref定义的对象属性如上述的,deep可以
hook函数
-
代码的封装,功能的复用,最大优势是可以将钩子以及一些vue函数独立出去,更为灵活
----template <template> <div @click="a.log">{{a.name}}</div> </template> <script> import { ref, reactive, watch } from 'vue' import clickDiv from './hook.js' export default { name: 'HelloWorld', setup(props) { let a = clickDiv() return { a } } } </script> /**多个钩子,更为灵活的使用*/ -----hook.js import { ref, reactive, watch } from 'vue' export default function () { let people = reactive({ name: '张峰', age: 18 }) let name = ref('zhangfeng') function log() { console.log(name) people.name = 'zhangrong' } watch(people, (newValue, old) => { console.log(newValue) console.log(old) }) return { people, name, log, } }
ref和reactive等等
-
概念
ref
跟reactive
都是响应系统的核心方法,作为整个系统的入口可以将
ref
看成reactive
的一个变形版本,这是由于reactive
内部采用 Proxy 来实现,而Proxy
只接受对象作为入参,这才有了ref
来解决值类型的数据响应,如果传入ref
的是一个对象,内部也会调用reactive
方法进行深层响应转换
-
-
ref的结构:let name = ref(‘zhangfeng’), 而name.value是响应式数据
-
reactive的结构
let people = reactive({
name: ‘张峰’,
age: 18
})
toref
的使用:在template中,html结构需要用到上诉Reactive定义的people的name对象,则使用people.name,但是当在html结构之中此类属性使用频繁之后,需要加太多people修饰
ref、toRef、toRefs这三项在js中操作的时候都需要跟上‘.value’,页面当中正常使用无需‘.value’
如let people = ref({
name:"zhangfeng",
age:20
}) 则是toRef(people.value:第一个参数需要操作的对象,"name":第二个参数需要操作的属性)
如let people = reactive({
name:"zhangfeng",
age:20
}) 则是toRef(people,"name")
1.错误的处理
setup(){
....
return{
name:people.name/**这样就失去了响应式的功能,因为只是把简单的字符串赋值给一个对象的属性,而在vue3之中实现响应式要吗是refimpl对象要么是proxy**/
}
}
2.正确的处理方式
setup(){
....
return{
name:toRef(people.name)
}
}
3.toRefs
setup(){
....
return{
...toRefs(people)
}
}
权限控制readonly和shallowreadonly
let people = ref({
name:"zhangfeng",
age:20
})
people = readonly(people)//数据不能修改,
people = shallowreadonly(people:响应式数据)对象的第一层数据不能修改
ps:这是从根本上限制了数据的修改,而不仅仅是页面层次