vue3基本使用

1、组合式API

下面是来区别vue2和vue3的区别代码 需求 实现盒子显示与隐藏
在这里插入图片描述
在这里插入图片描述

1let {ref} from "vue
2、setup()
3let show=ref(true)
4、show.value
5function isOka
6const hide=()=>{}
7return

在这里插入图片描述
拆分setup 适用于代码量较多的情况 优点 分散定义,组合使用

<script>
function useShow() {
      let show = ref(true);
     const isHide = () => (show.value = false)
     const isShow = () => (show.value = true)
  return {show,isHide,isShow}
  }
import { ref } from "vue";
export default {
  setup() {
    const {show,isHide,isShow} = useShow()
    return { show, isShow, isHide };
  },
};
</script>

2、setup

  1. 一个组件选项,在创建组件之前执行,一旦 props 被解析,并作为组合式 API 的入口点
  2. setup中不能使用不能使用this、this执行undefined
  3. setup函数在beforecreated钩子函数前执行
  4. setup函数只会在初始化的时候执行一次
1、setup函数在beforecreated钩子函数前执行
  beforeCreate() {
    console.log("beforeCreate");
  },
  setup() {
    console.log("setup");
  },

此时setup中的this还不是组件实例,此时this是undefined
在这里插入图片描述

2、第1个参数为props。
  • 第1个参数为props。props为一个对象,内部包含了父组件传递过来的所有prop数据
  • 第2个参数为一个对象context。context对象包含了attrs,slots, emit属性,
  • 如果在data()中也定义了同名的数据,则以setup()中为准。

3、生命周期钩子

在这里插入图片描述

  1. setup 是围绕 beforeCreate 和 created 生命周期钩子运行的,所以不需要显式地定义它们。换句话说,在这些钩子中编写的任何代码都应该直接在 setup 函数中编写。
  2. 可以通过在生命周期钩子前面加上 “on” 来访问组件的生命周期钩子。前提需要引入
export default {
  setup() {
    // mounted
    onMounted(() => {
      console.log('Component is mounted!')
    })
  }
}

4、响应式ref函数

1、不使用ref函数
<template>
  <div>{{ num }}</div>
  <button @click="addNum">1</button>
</template>
 
<script>
export default {
  setup() {
      let num=1,
      addNum=()=>{
          num++
          console.log(num);
      }
      return {num,addNum}
  },
};
</script>

点击加1后发现 视图上并没有发生改变 也就是说setup函数中返回的数据并不是响应式的
在这里插入图片描述

5、使用ref函数

1、简单数据类型
<script>
import {ref} from 'vue'
export default {
  setup() {
      let num=ref(1),
      addNum=()=>{
          num.value++
          console.log(num);
      }
      return {num,addNum}
  },
};
</script>

在这里插入图片描述

2、复杂数据类型
<template>
  <div>
    {{ obj.a }}
    <button @click="addNum">1</button>
  </div>
</template>
 
<script>
import {ref} from 'vue'
export default {
  setup() {
      const obj = ref({a:1}) 
      const addNum = ()=>obj.value.a++
      return {obj,addNum}
  },
};
</script>

使用步骤:

  1. 从vue框架中导入ref函数
  2. 使用ref函数并传入数据(简单数据类型或复杂数据类型)
  3. 在setup函数中把ref函数调用完毕的返回值以对象的形式返回出去


  • ref 会返回一个可变的响应式对象,该对象作为一个响应式的引用维护着它内部的值,这就是 ref 名称的来源。
  • 该对象只包含一个名为 value 的 property 注意:在setup函数中需要加.value,在template模板中不需要加value

5、ref引用

在vue2中获取 DOM元素和 子组件的引用直接绑定ref 通过$refs.ref绑定属性名获取引用

在vue3中 直接绑定ref 是获取不到的

<template>
  <div ref="box"></div>
</template>
 
<script>
import { ref, onMounted } from "vue";
export default {
  setup() {
    const box = ref(null);
    onMounted(() => {
      console.log(box.value);
    });
    return { box };
  },
};
</script>
 注意获取dom要在onMounted钩子函数中 获取,或者添加一个点击事件

6、reactive函数

我们使用ref函数进行定义响应式数据每次使用都要加.value,reactive就是用来省去加.value,但是只能定义复杂数据类型的数据

<template>
  <div>
    {{ obj.a }}
    <button @click="addNum">1</button>
  </div>
</template>
 
<script>
import {reactive} from 'vue'
export default {
  setup() {
      const obj = reactive({a:1}) 
      const addNum = ()=>obj.a++
      return {obj,addNum}
  },
};
</script>

7、toRefs函数

定义完响应式数据后,我们每次都要在模板中 通过对象.的形式进行渲染数据,但是如果为了解决这种麻烦 可以通过toRefs函数进行解构
模板中就可以直接使用a了 toRefs与reactive配套使用。

<template>
  <div>
    {{ a }}
    <button @click="addNum">1</button>
  </div>
</template>
 
<script>
import {reactive,  toRefs} from 'vue'
export default {
  setup() {
      const obj = reactive({a:1}) 
      let {a} = toRefs(obj)
      const addNum = ()=>obj.a++
      return {a,addNum}
  },
};
</script>

**从上面看就是给a 进行解构 但是为什么不直接…obj呢 **

  setup() {
      const obj = reactive({a:1}) 
    //   let {a} = toRefs(obj)
      const addNum = ()=>{obj.a++, console.log(obj.a);}
      return {...obj,addNum}
  },

答案是不能的 原因就是使用…a后 数据并没有保留响应式的特点

  • 当从组合式函数返回响应式对象时,toRefs 非常有用
  • 这样消费组件就可以在不丢失响应性的情况下对返回的对象进行分解/扩散

8、如何取舍ref和reactive

我们现在有两种定义响应式数据的方式到底该用哪个呢,

  • 优先使用ref函数 因为ref 函数 可以处理简单数据类型 也可以处理复杂数据类型 ,常用于简单数据类型定义响应式数据
  • ref特点: 在代码中获取或修改值时,需要补上.value 但是 template模板中不需要
<template>
  <div ref="box"></div>
</template>
 
<script>
import { ref, onMounted } from "vue";
export default {
  setup() {
    const box = ref(null);
    onMounted(() => {
      console.log(box.value);
    });
    return { box };
  },
};
</script>
  • reactive 常用与定义复杂数据类型作为响应式数据
  • reactive 特点 在代码中获取或修改值是不需要加.value , 如果明确知道对象中有什么属性就用reactive
<template>
  <div>
    {{ obj.a }}
    <button @click="addNum">1</button>
  </div>
</template>
 
<script>
import {reactive} from 'vue'
export default {
  setup() {
      const obj = reactive({a:1}) 
      const addNum = ()=>obj.a++
      return {obj,addNum}
  },
};
</script>

9、computed计算属性

1、基本用法
import { computed } from 'vue'
 
const 计算属性名 = computed(() => {
  return 响应式数据相关计算
})
<template>
  <div>姓名:{{name}} 月薪:{{salary}}年薪:{{total}}</div>
</template>
 
<script>
import { computed, ref } from "vue";
export default {
  setup() {
    const name = ref("奥特曼");
    let salary = ref(10000)
    const total = computed(()=>salary.value * 12)
    return { name,salary,total };
  },
};
</script>
2、高级用法
<template>
  <div>
    姓名:{{ name }} 月薪:{{ salary }}年薪:{{ total }}
    <input type="text" v-model="total" />
  </div>
  <button @click="double">月薪double</button>
</template>
 
<script>
import { computed, ref } from "vue";
export default {
  setup() {
    const name = ref("奥特曼");
    let salary = ref(10000);
    const total = computed({
        set(val){
          return  salary.value=val/12
        },
        get(){
         return salary.value * 12
        }
    });
    const double = () => salary.value *= 2;
    return { name, salary, total, double };
  },
};
</script>

计算属性也可以绑定v-model

10、watch监听

语法:

watch(数据|数组|get函数,(新值,旧值)=>{回调处理逻辑}, {immediate:true|false, deep: true|false})

1、单个数据监听
<template>
  <div>{{ num }}</div>
  <button @click="addNum">1</button>
</template>
 
<script>
import {ref,watch} from 'vue'
export default {
  setup() {
      let num=ref(1),
      addNum=()=>{
          num.value++
      }
      watch(()=>{
          return num
      },(newValue)=>{
          console.log(newValue);
      })
      return {num,addNum}
  },
};
</script>
2、多个数据监听
<template>
  <div>{{ num }}||| {{num2}} </div>
  <button @click="addNum">1</button>
  <button @click="addNum2">1</button>
</template>
 
<script>
import {ref,watch} from 'vue'
export default {
  setup() {
      let num=ref(1)
      let num2=ref(2)
    const addNum=()=>num.value++
    const addNum2=()=>num2.value++
      watch([num,num2],(newValue)=>{
          console.log(newValue);
      })
      return {num,num2,addNum,addNum2}
  },
};
</script>
3、复杂数据类型监听

如果监听 复杂数据类型 在第三个参数对象中的deep:true

<template>
  姓名:{{ stu.name }},公司:{{ stu.company }}
  月薪 {{ stu.money.salary }}
  <button @click="stu.company ='CSDN'">跳槽到CSDN</button>
</template>
 
<script>
import { reactive, watch } from 'vue'
export default {
  setup() {
    const stu = reactive({
      name: '小王',
      company:'JD',
      money: {
        salary: 1800
      }
    })
    watch(stu, () => {
      // 数据变化之后的回调函数
      console.log('stu发生了变化')
    })
    return { stu }
  }
}
</script> 
4、监听复杂数据类型中的属性

写watch的时候避免使用deep引起性能的问题,第一个参数可以使用回调的方式

<template>
  姓名:{{ stu.name }},公司:{{ stu.company }}
  月薪 {{ stu.money.salary }}
  <button @click="stu.money.salary =18000">月薪上升</button>
</template>
 
<script>
import { reactive, watch } from 'vue'
export default {
  setup() {
    const stu = reactive({
      name: '小王',
      company:'CSDN',
      money: {
        salary: 1800
      }
    })
    watch(()=>{
        return stu.money.salary
    }, () => {
      // 数据变化之后的回调函数
      console.log('薪资发生变化了')
    })
    return { stu }
  }
}
</script> 
5、开启深度监听

首次监听是immediate 深度监听 deep

<template>
  姓名:{{ stu.name }},公司:{{ stu.company }}
  月薪 {{ stu.money.salary }}
  <button @click="stu.money.salary*=2">工资double</button>
  <button @click="stu.money.bonus*=2">奖金double</button>
</template>
 
<script>
import { reactive, watch } from 'vue'
export default {
  setup() {
    const stu = reactive({
      name: '小王',
      company:'JD',
      money: {
        salary: 18000,
        bonus:15000
      }
    })
    watch(() => {
      return stu.money
    }, () => {
      console.log('stu.money发生了变化')
    }, {
      deep: true //  只有为true,才能监听money下所有属性的变化
    })
    return {
      stu
    }
  }
}
</script> 

11、父子通信

1、父传子

在setup函数中有两个参数 第一个参数为props,第二个参数为context

  • props为一个对象,props接收后,内部包含了所有传递过来的prop数据
  • context包含了attrs,slots,emit属性,其中emit方法可以完成子传父

<template>
  <div>
    <Son :msg="msg"></Son>
  </div>
</template>
 
<script>
import { ref } from 'vue';
import Son from "./son.vue";
export default {
  components: {
    Son,
  },
  setup() {
      const msg = ref('奥特曼')
        return {msg}
  },
};
</script>
 
<style scoped>
</style>

<template>
  <div>子组件 {{msg}} </div>
</template>
 
<script>
export default {
    props:{
        msg:{
            type:String,
            default:''
        }
    },
    setup(props,context){
        console.log(props,context);
    }
};
</script>
 
<style scoped>
</style>
2、子传父

注意vue2中的this.$emit 不在生效 setup函数中没有this ,而在setup第二个参数中有emit方法

    setup(props,context){
        context.emit('name','奥特曼')
    }
 
//结构写法
//    setup(props,{emit}){
//       emit('name','奥特曼')
//   }

<template>
    <Son @name="name" ></Son>
</template>
 
  setup() {
      const name = (name)=>console.log(name);
        return {name}
  },  
  • 父传子:在setup中使用props数据 setup(props){ props就是父组件数据 }
  • 子传父:触发自定义事件的时候emit来自 setup(props,{emit}){ emit 就是触发事件函数
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值