Vue3学习笔记

目录

一、Vue3的创建

二、组合式API

1.setup

2.reactive 和 ref(推荐) 函数

3、computed计算属性

4、watch监视属性

4.1 基本使用

4.2 额外属性 (初始化调用、深度监听)

4.3 精准监听

5、生命周期函数 

6、父子通信(父传子props)

6.1 非响应式数据传递 

6.2 响应式数据传递 (动态更新)

7、父子通信(子传父emit)

8、模板引用

 8.1、defineExpose( )

9、provide和inject

9.1、 底层组件怎么修改顶层组件数据?

10、defineOptions

11、defineModel


一、Vue3的创建

Vue2选项式API-----------Vue3组合式API(更易封装复用)

前提:需要有node.js版本16.0以上

在对应目录下cmd输入:npm init vue@latest  创建

在项目目录底下npm install 安装依赖,不安装会显示找不到vite

vscode里的插件,vue2时安装的是Vetur,Vue3可以安装volar

目录介绍:

二、组合式API

1.setup

因为setup的执行时间非常早,所以是查询不到this的(显示undefind)

练手小案例:

// 在setup里面创建一个数组和一个函数,在浏览器展示出来

<script>
export default {
  // 数组 和 函数 在setup的最后需要return输出才能被获取到
  setup() {

    const ceshi1 = '测试setup能否直接被获取到';
    const ceshi2 = () => {
      console.log(ceshi1);
    }

    return { ceshi1, ceshi2 };
  }
}
</script>

<template lang="">
  <div>
    <div>{{ceshi1}}</div>
    <button @click="ceshi2">按钮</button>
  </div>
</template>

但是上面这样写数据少的时候还好,数据一多要return的也就越多,这时候可以用setup的语法糖

// 在script 后添加setup ,这样里面的setup数据就可以直接调用了,也不需要setup(){ }

<script setup>

  // 数组 和 函数 在setup的最后需要return输出才能被获取到

    const ceshi1 = '测试setup能否直接被获取到';
    const ceshi2 = () => {
      console.log(ceshi1);
    }

</script>

 

2.reactive 和 ref(推荐) 函数

在vue中默认的数据不是响应式的,这时候可以使用 reactive 或 ref 

reactive( ) -》接收一个对象类型的数据,返回响应式的数据

步骤:1、import 导入

           2、调用方法进行转换,而后返回响应式数据

// 不添加reactive时count非响应式,点击按钮无法变更数字
<script setup>

 const state = {
   count:100
 }

 const setCount = ()=>{
  state.count++
 }

</script>

<template lang="">
  <div>

    <div>{{state.count}}</div>
    <button @click="setCount">按钮</button>

  </div>
</template>

//------添加后,可以变更数字----------

<script setup>
 import { reactive } from 'vue';

 const state = reactive({
   count:100
 })

const setCount = ()=>{
  state.count++
}
</script>

ref( ) -》可以接收简单类型对象类型数据,转换成响应式数据

步骤:1、import 导入

           2、调用方法进行转换,而后返回响应式数据

脚本区域要加.value
脚本区域要加.value,非脚本区域直接使用

// 简单类型---------------------

import { ref } from 'vue';
const state2 = ref(0);
const setCount2 = ()=>{
  // 在后台需要修改ref包裹的count2里的数据,得修改count2里的value
  state2.value++;
}
</script>

<template lang="">
  <div>
    <div>{{state2}}</div>
    <button @click="setCount2">按钮</button>
  </div>
</template>

// 复杂类型------------------------

import { ref } from 'vue';
const state2 = ref({aa:10});
console.log(state2);
const setCount2 = ()=>{
  // 在后台需要修改ref包裹的count2里的数据,得修改count2里的value
  state2.value.aa++;
}
</script>

<template lang="">
  <div>
    <div>{{state2.aa}}</div>
    <button @click="setCount2">按钮</button>
  </div>
</template>

3、computed计算属性

步骤:1、import 导入

           2、在需要计算的地方调用

// 要求,把数组[1,2,3,4,5,6,7]筛选出比2大的数形成新数组
// 注意:1、别忘记导入
//       2、在需要计算的地方使用computed()计算属性

<script setup>
import { computed,ref } from 'vue';
var list = ref([1, 2, 3, 4, 5, 6, 7]);
// 生成一个计算属性,过滤出>2的数
var newList = computed(()=>{
  return list.value.filter((num)=>{
    return num >2;
  })
})
</script>

<template lang="">
  <div>
    
    <div>原数组:{{list}}}</div>
    <div>新数组:{{newList}}</div>

  </div>
</template>

过滤器filter()的使用

JS filter()方法 介绍和使用_filter js_马井堂的博客-CSDN博客

4、watch监视属性

4.1 基本使用

监听单个数据
监听多个数据

小案例,通过按钮修改num1和name1,并监听 

<script setup>
import { ref, watch } from 'vue';
const num1 = ref(0);
const name1 = ref('张三');

const newNum1 = () => {
  num1.value++
}
const newName1= ()=>{
  name1.value='李四';
}

watch([num1,name1], ([newNum1,newName1], [oldNum1,oldName1])=> {
  console.log([newNum1,newName1], [oldNum1,oldName1]);
})
// 如果想一起监听并展示也可以向下面这样,把[newNum1,newName1]整合成一个newArr,后面的同理
// watch([num1,name1], (newArr, oldArr)=> {
//   console.log(newArr, oldArr);
// })
</script>

<template lang="">
  <div>
    <!-- 要求:监听num1和name1的变化 -->
    <div>{{num1}}</div>
    <button @click="newNum1">+1</button>
    <div>{{name1}}</div>
    <button @click="newName1">改名字</button>

  </div>
</template>

4.2 额外属性 (初始化调用、深度监听)

watch(沃取)里面还有两个属性,immediate、deep(默认都是false状态)

// 想要使用很简单,在箭头函数外面新添一个{}写就行
watch([num1,name1], ([newNum1,newName1], [oldNum1,oldName1])=> {
  console.log([newNum1,newName1], [oldNum1,oldName1]);
},{
  immediate:true; //<------true时,在初始化时会自动调用一次
  deep:true       //<------true时,开启深度监听,不开时只能监听到第一层,开启后能监听多层
})

4.3 精准监听

<script setup>
import { ref, watch } from 'vue';

const userInfo = ref({
  age:12,
  age2:25,
  name:'520'
})

const setUserInfo= ()=>{
  userInfo.value.age++
}

// 注意这里,精准监听的固定写法,把监视对象换成了箭头函数()=>userInfo.value.age,即userInfo里的age,后面不变
// 而且精准监听不用开deep(深度监听)
watch(()=>userInfo.value.age,(newValue,oldValue)=>{
  console.log(newValue);
})
</script>

<template lang="">
  <div>

    <div>{{userInfo}}</div>
    <button @click="setUserInfo">改数字</button>

  </div>
</template>

5、生命周期函数 

import { onBeforeMount,onMounted } from 'vue';
  // 生命周期钩子的使用
  // 全部都可以在setup里执行,像beforeMounted、Mounted这些
  // 直接写成函数的形式,可以创建多个生命周期钩子,按顺序从上到下执行
  const getList = ()=>{
    setInterval(() => {
      console.log('我是setup里的两秒定时器');
    }, 2000);
  } 
  getList()
  // 想要在挂载前后生成东西可以这么写
  onBeforeMount(() => {
    console.log('根据顺序,onBeforeMount必须在onMounted前面')
  }),
  onMounted(() => {
    console.log('我是Mounted,在Vue3中我写成onMounted')
  })
  onMounted(() => {
    console.log('我是Mounted2号,在使用我之前要import导入')
  })
</script>

6、父子通信(父传子props)

在父组件中导入子组件,给子组件绑定属性,子组件defineProps接收传递过来的参数,子组件使用传递过来的参数

6.1 非响应式数据传递 

// -------父组件中------------
<script setup>
// 导入子组件
import HelloWorld from './components/HelloWorld.vue';
</script>

<template lang="">
  <div>
    <div>我是app.vue</div>
    //调用子组件,并给子组件传递参数pro
    <HelloWorld pro="父子成功传参啦"></HelloWorld>
  </div>
</template>


// --------子组件中-------------
<script setup>
// 因为是在setup中,无法直接调用props,所以使用defineProps“编译器宏”
// const props = defineProps({ 传递参数名:类型 });
  const props = defineProps({
    pro:String
  });
</script>

<template>
  <div>
    // 使用传递过来的参数pro
    <div >我是子组件HelloWorld.vue-{{pro}}</div>
  </div>
</template>

6.2 响应式数据传递 (动态更新)

// --------父组件-------------
<script setup>
// 导入ref
import { ref } from 'vue';

const money = ref(100);
const newMoney = ()=>{
  money.value += 10;
}

</script>

<template lang="">
  <div>
    <div>
      老爹的余额{{money}}
      <button @click='newMoney'>赚钱</button>
    </div>
  </div>
</template>

// -------子组件-----------------
<script setup>
  const props = defineProps({
    // 类型的首字母要大写,传递多个参数时这样写:
    pro:String,
    money:Number
  });
</script>

<template>
  <div>
    <div>父组件赚了{{ money }}块</div>
  </div>
</template>

7、父子通信(子传父emit)

1、子组件内部通过emit方法触发事件(编译器宏获取)

2、父组件中,在子组件标签里通过@绑定事件监听

// -----------父组件---------------
<script setup>
import { ref } from 'vue';
import HelloWorld from './components/HelloWorld.vue';
const money = ref(100);

const changeFn =(Moneys)=>{
  money.value = Moneys;
}
</script>

<template lang="">
  <div>
    <div>我是app.vue</div>
    <HelloWorld @changeMoney='changeFn'></HelloWorld>
  </div>
</template>

// -------------子组件---------------------
<script setup>
  const emit = defineEmits(['changeMoney'])
  const buy = ()=>{
    emit('changeMoney',15)
  }
</script>

<template>
  <div>
    <div class='zi'>
      <button @click="buy">投资后</button>
    </div>
  </div>
</template>


// 1、通过编译器宏defineEmits定义emit(括号里写要触发的事件名称)
// 2、编写触发事件的方法,和要传递的内容【别忘了在template里写谁触发的事件】
// 3、在父组件里的子组件标签里添加@自定义事件,绑定一个函数
// 4、编写这个函数的方法,并接收子组件传过来的形参

8、模板引用

通过ref标识获取Dom对象或者组件实例对象

<script setup>
import { onMounted,ref } from 'vue';
// 1、调用ref函数生成一个ref对象
const inp = ref(null);

// 3、编写方法
onMounted(()=>{
    console.log(inp.vlaue);
    // inp是绑定在输入框上的,这里是指挂载完毕后给输入框获取焦点
    inp.value.focus()
})
// clickFn是绑定在按钮上的,这里是指点击按钮后,给inp输入框获取焦点
const clickFn=()=>{
    inp.value.focus()
}
</script>

<template>
    <div>
        // 2、通过ref表示绑定对象到标签上
        <input ref="inp" type="text">
        <button @click="clickFn">输入聚焦</button>
    </div>
</template>

Vue.js 使用Vue:如何在按钮点击时调用.focus()|极客笔记

 8.1、defineExpose( )

// 父组件
<script setup>
import { ref } from 'vue';
import Student from '@/components/Student.vue'

const std = ref(null);
const getStd = ()=>{
  console.log(std.value);
}
</script>
<template lang="">
  <div>
    <Student ref="std"></Student>
    <button @click='getStd'>获取Student组件数据</button>
  </div>
</template>

// 子组件
<script setup>
const shuxing1 = 999
// 如果不defineExpose进行暴露,则父组件是得不到数据的
defineExpose({
    shuxing1
})
</script>

<template>
    <div>
        用于测试的student
    </div>
</template>

9、provide和inject

顶层组件任意的底层组件传递数据或方法(跨层组件通信),爷爷给孙子曾孙子传递数据

使用的时候别忘了在对应组件里导入!!!!!

import { provide } from 'vue';

import { inject } from 'vue';

底层里的message是自定义名

 

 

9.1、 底层组件怎么修改顶层组件数据?

谁的数据谁来维护,底层组件不能直接修改顶层的数据

解决方法:跨层级传递函数=> 给子孙后代传递可以修改数据的方法

// ---------顶层组件----------------
<script setup>
import school from './components/school.vue';
import { provide,ref } from 'vue';
// 首先定义一个响应式的hello1
const hello1 = ref(100)
// 利用provide传递给底层组件,传递的数值是hello1对象本身
provide('hello1', hello1)
// 给底层组件编写方法changeHello1,让他可以修改hello1的数据
provide('changeHello1', (newHello) => {
    hello1.value = newHello
})
</script>

<template>
    <div class="top1">
        我是顶层组件
        <school></school>
    </div>
</template>

// ---------底层组件------------------
<script setup>
import { inject } from 'vue';
// 1、创建一个hello2,利用inject来接收顶层组件的hello1
const hello2 = inject('hello1')
console.log(hello2);

// 4、创建changeHello1 用来接收顶层组件传过来的changeHello1修改数据的方法
const changeHello1 = inject('changeHello1')
// 5、当按钮被点击时,changeHello1调用了顶层组件中changeHello1 里的方法,
// 把(1200)给到了hello1.value里,从而修改了数值,需要注意方法的控制器是顶层组件持有的
const clickFn = ()=>{
    changeHello1(1200)
}
</script>

<template>
    <div class="top3">
        // 2、使用hello2
        我是底层组件--{{ hello2 }}
        // 3、创建一个点击事件用于修改顶层组件传过来的数据
        <button @click="clickFn">更新父组件传递的数据</button>
    </div>
</template>

 

10、defineOptions

11、defineModel

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值