vue3.0用法及改变(基础简介)

vue3.0中将采用组合式API(compositionApi) 替换了2.0的选项式API(optionsApi)

compositionApi:基于函数组合的API(把一个个功能放在一个函数内),组件内有一个setup的钩子,在这个钩子内,用到哪个功能就调用哪个函数

也就是vue2.0中,在data里创建的变量,可能会在methed 或 watch 或其他选项里用到,一旦系统出错,需要一个个地方去排查,操作不便,而组合式API 是将所有属性变量值都放在了compositionAPI 内,每种属性变量值都放在一起

// setup 实际上就是取代了2.0内的beforeCreate 和created
// setup 相当于一个调度者,所有都可以写在这里面
// 基本用例:(非工程化用法)里面不再用data,metheds...等分开的属性函数,直接--->
<div>{{msg}}</div>
<button @click='btn'>点击</button>

setup(props,context){ // 参数1props 父子传参接收   参数2context 上下文接收
    return{
       msg:'我是消息信息...',
       btn: ()=>{
            console.log('我被点击了....');
       }
    }
}


// setup 内不可调用this. 因为它取代的是beforeCreate 和 created,所以被挂载前调用。注意:beforeCreate 这个在3.0中没有了因为用了setup
// 所以没有this. 以及setup 内不能调生命周期当中任何内容,反过来,例如methods 或其他生命周期内访问setup 内的内容是被允许的,例如:
methods:{
   getSetup(){
      console.log(this.$options.setup(),'访问setup.....')
   }
}

// 注意:如果用了setup 就尽量不要再分开去在外面用methods 等这种选项式API(虽然它能兼容)

 

// ref    让基础类型的数据具备响应式

// 在setup 内创建的变量,不像之前optionsAPI 那样,可以在页面F12 控制台通过修改属性值实现页面修改,所以fef 的作用出现了,例:(非工程化用法)
setup(props,context){
    const {ref} = vue     // 从vue 中引入
    let msg = ref('我是消息信息') // 用ref包裹后就成了响应式

    return{msg}
}

// 在optionsAPI 中实现响应式是通过代理原理,这里compositionAPI 用ref 也是通过代理的原理,通过 proxy({value:'我是消息信息'})
//因为 ref 的底层原理是proxy ,是一个对象,所以在setup 内使用修改的时候不能直接 '=' 号赋值,需要通过msg.value = '我是新的消息信息'
// 在页面展示时,底层会转换,所以在template 中的html 代码中不需要.value 获取展示

 

// reactice (让引用类型也就是对象或数组的数据具备响应式)

// 例:(非工程化基本用法)
<div>{{obj.name}}</div>

setup(props,context){
   const { reactive} = vue   // 从 vue中引入
   let obj = reactive({name:'tom',age:'10'});
   
   return{obj}
}

// 同理,reactive 的底层原理也是proxy     proxy({name:'tom',age:'10'})
// 在setup 内使用修改的时候,直接  obj.name = '李四'  

 

// readonly (只读,不希望被修改)

// 例:(非工程化基本用法)
setup(props,context){
   const {readonly} = vue    // 引入
   let obj = readonly({name:'tom',age:'10'})

   return {obj}
}

 

// toRefs   (响应式结构)

// 如果用之前的const {name,age}=obj   这种方式结构不具备响应式
// 原理也是proxy 代理   proxy({name:'tom',age:'10'})  然后解析成  name:proxy({value:'tom'})    age:proxy({value:'10'})   由此最终成了响应式
// 例:(非工程化用法)
setup(props,context){
   const {reactive,toRefs} = vue   // 引入
   let obj = reactive({name:'tom',age:'10'});
   const {name,age} = toRefs(obj)

   return{name,age}
}

 

// toRef (对于可有可无的值,或者不确定是否有的值设定)

// 例:(非工程化基本用法)
setup(props,context){
    const { reactive,toRefs,toRef} = vue   // 引入
    let obj = reactive({name:'tom',age:'10'});
    let {name,age} = toRefs(obj)
    let sex = toRef(obj,'sex')   // 不确定sex 值是否有,如果没有默认undefined
   
    return{name,age,sex}   // 如果不用toRef 设置,直接强行在toRefs 内取值会报错
}

 

// setup 的参数context 上下文传递

// context有三个属性:
// 1. attrs:可以拿到no-poros的值(例如样式style)
// 2. slots:可通过 slots.default() 拿到插槽的元素标签及获取相应属性(是个数组)
// 3. emit:使用自定义事件(子传父事件)

//例:基本用法(非工程化用法)
// 针对slots 参数 vue中底层有个h 函数,const {h} = vue; return ()=> h('div',{style:'color:#fff'},[slots.default()])    这样可以动态创建一个div 插槽,绑定什么属性,放什么东西

setup(props,context){
    const {attrs,slots,emit} = context
}

// emit 的基本用法(非工程化用法)
setup(props,context){
     const {emit} = context   // 引入
     function btnClick(){
         const data = {name:'tom',age:'10'}
         emit('父组件方法名',data)      // 替代的2.0中子组件触发父组件传参,this.$emit()方法
     }

     return {btnClick}
}

 

// 计算属性 computed
// 例:(非工程化用法)
setup(props,context){
     const {ref,computed} = vue   // 引入
     let num1 = ref(10);
     let num2 = computed(() => {
          return num1.value * 10
     })
     const add = () => {
           num1.value+=10;
     }

     return{num1,num2,add}
}

// 注意:computed 本身有get 和set 两种方法,所以也可以这么写
get:() => {
    return num1.value *10;
}
set: (res) => {
    num1.value = res/10
}

 

// 侦听器 watch
// 例:
setup(props,context){
    const {ref,watch} = vue   // 引入
    let data = ref('')
    watch(data,(currentValue,preValue) => {   })  // data:侦听的属性,currentValue:之前的值,preValue:变化后的值
    let data2 = ref('')
    // 侦听多个值的情况
    watch([data,data2],([currentData,currentData2],[preData1,preData2]) => {   })

    return {data,data2}
}

// 侦听引用类型值:
let obj = reactive([name:'tom',age:'10'])
watch(() => obj.name,(current,pre) => {    })

 

// watchEffect (和watch 一样都用于侦听)
// 相比watch 它有以下3个特点:
// 1. 没有惰性(比如一开始的时候watch是不侦听的,只有在改变了值的时候才会触发watch 侦听,这个指的就是watch 的惰性)
// 2. 更加抽象(watch 更加具体,具体到侦听哪一个属性,象watchEffect 可以侦听所有的属性,在内部都可以拿到这个值的变化)
// 3. 不能访问先前值(watch 里可以拿到之前的值和现在的值,watchEffect 里不能拿到之前的值)

// 另外:watchEffect 也是可以配置的(例如是否要有惰性,是否要深度侦听),只不过watch 是1对1配置,watchEffect是1对多
setup(props,context){
   const {watchEffect} = vue
   let data = ref('')
   let slte = ref('')
   watchEffect(() => {   },{immediate:true})

   return {data,slte}
}

 

// provide(数据发射出去) 和 inject(接收数据)
// 用于解决父组件数据,子孙组件使用接收的单项数据流问题
// 可以解决2.0版的父子,子孙,兄弟间的组件数据传输,只能获取不能修改(数据在哪就在哪修改)

// 父组件
setup(){
    const {ref,reactive,provide,readonly} = vue
    let info = ref('小明')
    let obj = reactive({name:'哈哈',sex:'女'})

   provide('brand',info)  // 发射(订阅),相当于 provide('brand',readonly(info))表示发射出的值外部只能用不能改  
}

// 子组件
setup(){
    const {inject} = vue
    const bname = inject('brand','默认值')  // 这里默认值的作用是,如果没有brand发射过来的时候,显示默认值

    return{bname}
}


// 如果想要修改发射过来的值

// 父组件(发射一个方法)
const changeInfo = (params)=>{
    info.value = params
}

provide('changeInfo',changeInfo)


// 子组件(调用这个方法)
const changeInfo = inject('changeInfo')
const changeName=() => {
    changeInfo('小红')
}

return{changeName}

 

// 3.0中生命周期钩子的新写法
// 新的用setup,取消了berforeCreate 和created 两个钩子,剩下的对比之前前面都加个 on 
//例:
setup(){
    const {ref,onBeforeMount} =  vue
    let msg = ref('小明')
    onBeforeMount(() => {
       console.log(msg,'打印msg....')
    })

    return{msg}
}


// 钩子onRenderTracked:每次渲染后重新收集响应式依赖
// 钩子onRenderTriggered:每次触发页面重新渲染时自动执行

// 另外,setup 有个简写方式<script setup></script>
// 在这种情况下可以不用 return ,不用setup default,直接从vue 引入开始写就行(底层已经处理统一导出处理)
// 相关setup(val){},也就是setup小括号里的传参值,可以通过useContext 获取(useContext 从vue 中引入使用即可)

 

// 获取Dom

<div ref='info'>文本内容</div>
<input ref='inpts' />

setup(){
   cosnt {onMounted,ref} = vue

   let info = ref(null)
   let inpts = ref(null)
   onMounted(() => {
      console.log(info.value,'打印info 值,获取dom.....')
      console.log(inpts.value,'打印inpts 值,获取dom...')
   })
 
   return{info,inpts}
}

 

posted on 2022-05-07 17:21  一名小学生呀  阅读(553)  评论(0编辑  收藏  举报

导航