Vue3.0学习笔记(一)

一.Vue介绍

1.什么是Vue

Vue是一套用于构建用户界面的前端框架

  • 构建用户界面:往html中填充数据,方便。
  • 框架:一套现成的解决方案,程序员只能遵守框架的规范,去编写自己的业务能力。

学习vue就是学习vue框架中规定的用法

2.vue的特性

(1).数据驱动视图

在使用vue的页面中,vue会监听数据的变化,从而自动重新渲染页面的结构
数据驱动视图

  • 好处:不需要再在代码中频繁地去操作dom
(2).双向数据绑定

简单来说,就是当数据发生变化时,相应的视图会进行更新,当视图更新时,数据也会跟着变化
双向数据绑定

  • 好处:开发者不再需要用手动操作DOM元素,来获取表单元素的最新值。

注意:Vue的两个特性的底层原理是MVVM(Mode数据源、View视图、ViewModel即Vue的实例)

二.vue3.0的基本使用

创建方法:

1.使用命令行工具vue-cli 创建

Vue 提供了一个官方的 CLI,为单页面应用 (SPA) 快速搭建繁杂的脚手架。
对于 Vue 3,你应该使用 npm 上可用的 Vue CLI v4.5 作为 @vue/cli,可以用以下命令查看@vue/cli版本:

vue --version

使用以下命令安装或者升级你的@vue/cli

npm install -g @vue/cli

创建一个新的项目projectName

vue create projectName

传送到项目目录下:

cd projectName

启动项目:

npm run serve

2.使用 vite 创建

Vite 是一个 web 开发构建工具,由于其原生 ES 模块导入方式,可以实现闪电般的冷服务器启动。
以下命令创建名为projectName的工程:

# npm 6.x版本
$ npm init vite@latest projectName --template vue

# npm 7+版本,需要加上额外的双短横线
$ npm init vite@latest projecName -- --template vue

然后进入工程目录:

cd projecName

然后安装依赖:

npm install

然后运行项目

npm run dev

三.组合式 API

1.setup组件选项

新的 setup 选项在组件创建之前执行,一旦 props 被解析,就将作为组合式 API 的入口

  • 组件中所用到的:数据、方法等等,均要配置在setup中。
  • setup函数的两种返回值:
  1. 若返回一个对象,则对象中的属性、方法, 在模板中均可以直接使用。(重点关注!)
  2. 若返回一个渲染函数:则可以自定义渲染内容。(了解)

需要注意的点:

  1. setup执行的时机
  • 在beforeCreate之前执行一次,this是undefined。
  1. setup的两个参数
  • props:值为对象,包含:组件外部传递过来,且组件内部声明接收了的属性。
  • context:上下文对象
    • attrs: 值为对象,包含:组件外部传递过来,但没有在props配置中声明的属性, 相当于 this.$attrs
    • slots: 收到的插槽内容, 相当于 this.$slots
    • emit: 分发自定义事件的函数, 相当于 this.$emit

四.响应性API

1.带 ref 的响应式变量

ref 函数可以使任何响应式变量在任何地方起作用
使用前需要引入,创建一个包含响应式数据的引用对象(reference对象,简称ref对象)。语法:

import { ref } from 'vue'

const xxx = ref(initValue)

ref 接收参数并将其包裹在一个带有 value property 的对象中返回,然后可以使用该 property 访问或更改响应式变量的值,例:

<template>
  <h1>一数字</h1>
  <h2>大小:{{num}}</h2>
  <button @click="changeInfo">加一</button>
</template>

<script>
import {ref} from 'vue'
export default {
  setup(){
    let num=ref(0)

    function changeInfo(){
      num.value++
    }

    return{
      num,
      changeInfo
    }
  }
}
</script>

例子中点击按钮响应式改变数值的大小
注意:

  • 模板中读取数据: 不需要.value,直接:<div>{{xxx}}</div>
  • 接收的数据可以是:基本类型、也可以是对象类型。
  • 基本类型的数据:响应式依然是靠Object.defineProperty()getset完成的。
  • 对象类型的数据:内部 “ 求助 ” 了Vue3.0中的一个新函数—— reactive函数。

将值封装在一个对象中,看似没有必要,但为了保持 JavaScript 中不同数据类型的行为统一,这是必须的。

2.reactive函数

与ref()类似,但reactive函数定义的是一个对象类型的响应式数据(基本类型不要用它,要用ref函数)
语法:const 代理对象= reactive(源对象)
接收一个对象(或数组),返回一个代理对象(Proxy的实例对象,简称proxy对象)
注意:

  • reactive定义的响应式数据是“深层次的”。
  • reactive 将解包所有深层的 refs,同时维持 ref 的响应性。

例:

const count = ref(1)
const obj = reactive({ count })

// ref 会被解包
console.log(obj.count === count.value) // true

// 它会更新 `obj.count`
count.value++
console.log(count.value) // 2
console.log(obj.count) // 2

// 它也会更新 `count` ref
obj.count++
console.log(obj.count) // 3
console.log(count.value) // 3

3.reactive与ref的对比

  • 从定义数据角度对比:
    • ref用来定义:基本类型数据
    • reactive用来定义:对象(或数组)类型数据
    • 备注:ref也可以用来定义对象(或数组)类型数据, 它内部会自动通过reactive转为代理对象。
  • 从原理角度对比:
    • ref通过Object.defineProperty()getset来实现响应式(数据劫持)。
    • reactive通过使用Proxy来实现响应式(数据劫持), 并通过Reflect操作源对象内部的数据。
  • 从使用角度对比:
    • ref定义的数据:操作数据需要.value,读取数据时模板中直接读取不需要.value
    • reactive定义的数据:操作数据与读取数据:均不需要.value

4.computed

接受一个 getter 函数,并根据 getter 的返回值返回一个不可变的响应式ref对象。或者,接受一个具有 getset函数的对象,用来创建可写的 ref 对象。
例:

<template>
前部分:<input type="text" v-model="abc.head">
<br>
后部分:<input type="text" v-model="abc.tail">
<br>
结果: 
<input type="text" v-model="abc.result">
</template>

<script>
import {reactive,computed} from 'vue'

export default {
  name: 'App',
  setup(){
    let abc=reactive({
      head:'qian',
      tail:'hou'
    })

  //计算属性,完整的写法(考虑了读和写)
  //传入一个具有 get 和 set 函数的对象
  abc.result=computed({
    get(){
      return abc.head+'-'+abc.tail
    },
    set(value){
      const abcArr = value.split('-')
      abc.head=abcArr[0]
      abc.tail=abcArr[1]
    }
  })
    return{
      abc
    }
  }
}
</script>

在例子中,两个输入与结果的输入输出绑定,修改两个输入的值会修改结果的值。而修改结果的值也会同步两个输入的值。

5.watch函数

watch 需要侦听特定的数据源,并在回调函数中执行副作用。
语法:

watch(WatcherSource, Callback, [WatchOptions])

共有三个参数:

  • WatcherSource: 用于指定要侦听的响应式变量。WatcherSource可传入ref响应式数据,reactive响应式对象要写成函数的形式。
  • Callback: 执行的回调函数,可依次接收当前值newValue,先前值oldValue作为入参。
  • WatchOptions:支持 deep、immediate。当需要对响应式对象进行深度监听时,设置deep: true;默认情况下watch是惰性的,当我们设置immediate: true时,watch会在初始化时立即执行回调函数。

使用场景:

  1. 监听单个数据
<template>
  <h2>当前和为:{{sum}}</h2>
  <button @click="sum++">点击值+1</button>
</template>
<script>
import {ref,watch} from 'vue'

export default {
  name: 'App',
  setup(){
    let sum=ref(0)

    //情况一:监视ref所定义的响应式数据
    watch(sum,(newValue,oldValue)=>{
      console.log('sum的值改变了',newValue,oldValue)
    })
    
    return{
      sum
    }
  }
}
</script>
  1. 监听多个数据源
<template>
  <h2>当前和为:{{sum}}</h2>
  <button @click="sum++">点击值+1</button>
  <h2>{{msg}}</h2>
  <button @click="msg+='!'">修改</button>
</template>

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

export default {
  name: 'App',
  setup(){
    let sum=ref(0)
    let msg=ref("Hello world!")

    //情况二:监视ref所定义的响应式数据
    watch([sum,msg],(newValue,oldValue)=>{
      console.log('sum的值改变了',newValue,oldValue)
    },{immediate:true})
    //immediate:true的作用是初始化时执行回调

    return{
      sum,
      msg
    }
  }
}
</script>
  1. 监听reactive对象
<template>
  <h2>当前和为:{{sum}}</h2>
  <button @click="sum++">点击值+1</button>
  <hr>
  <h2>{{msg}}</h2>
  <button @click="msg+='!'">修改</button>
  <hr>
  <h2>姓名:{{person.name}}</h2>
  <h2>年龄:{{person.age}}</h2>
  <button @click="person.name+='~'">修改姓名</button>
  <button @click="person.age++">年龄增长</button>
</template>

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

export default {
  name: 'App',
  setup(){
    let sum=ref(0)
    let msg=ref("Hello world!")
    let person=reactive({
      name:'张三',
      age:18
    })

    //情况三:监视reactive对象
    watch(person,(newValue,oldValue)=>{
      //注意此处无法正确获取oldValue的值,oldVlaue的值和newValue的值一样
      console.log('个人信息的值改变了',newValue,oldValue)
    },{immediate:true})
    return{
      sum,
      msg,
      person
    }
  }
}
</script>
  1. 监视reactive对象中的某一个属性
    监视某个属性要用用一个函数的返回值,如:()=>
    //情况四:监视reactive对象中的某一个属性
    watch(()=>person.age,(newValue,oldValue)=>{
      console.log('个人年龄的值改变了',newValue,oldValue)
    })

注意:当要监视reactive中的某些属性时用到数组,如:[()=>person.age,()=>person.name]

  1. 监视ref创建的对象

共有两种方法:

  • 根据ref对象的定义,用xxx.value
  • 在参数使用deep:true
<template>
  <h2>姓名:{{person.name}}</h2>
  <h2>年龄:{{person.age}}</h2>
  <button @click="person.name+='~'">修改姓名</button>
  <button @click="person.age++">年龄增长</button>
</template>

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

export default {
  name: 'App',
  setup(){
    let msg=ref("Hello world!")
    let person=ref({
      name:'张三',
      age:18
    })

 	//方法一
    watch(person.value,(newValue,oldValue)=>{
      console.log('个人信息的值改变了',newValue,oldValue)
    })    
	//方法二
    watch(person,(newValue,oldValue)=>{
      console.log('个人信息的值改变了',newValue,oldValue)
    },{deep:true})
    
    return{
      person
    }
  }
}
</script>
  1. watch()函数总结
    两个小坑:
  • 监视reactive定义的响应式数据时:oldValue无法正确获取、强制开启了深度监视(deep配置失效)。
  • 监视reactive定义的响应式数据中某个属性时:deep配置有效。

6.watchEffect函数

立即执行传入的一个函数,同时响应式追踪其依赖,并在其依赖变更时重新运行该函数。即不用指明监视哪个属性,监视的回调中用到哪个属性,那就监视哪个属性。例:

const count = ref(0)

watchEffect(() => console.log(count.value))
// -> logs 0

setTimeout(() => {
  count.value++
  // -> logs 1
}, 100)

7.watchEffect与computed的对比

  • computed注重的计算出来的值(回调函数的返回值),所以必须要写返回值。
  • watchEffect更注重的是过程(回调函数的函数体),所以不用写返回值。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值