vue3

安装

  • 下载脚手架  npm install -g @vue/cli  
  • 创建项目  vue create vue3-test 
  • 项目根目录创建  vue.config.js 并进行配置
    module.exports = {
      lintOnSave: false, // 关闭语法检查避免折磨
    }

     

常用的 Composition (组合式) API

setup函数

  • 可以把所有的组合式API放到  setup 函数中去
  • 组件中使用的数据、方法等都可以配置在  setup 函数中
  •  setup 函数如果返回一个对象,则对象中的属性、方法都可以在模板中使用
<template>
  <h1>我是APP组件</h1>
  <p>{{name}} --- {{age}}</p>
  <button @click="sayName">btn</button>
</template>

<script>
export default {
  name: 'App',
  setup() {
    // 数据
    let name = 'zs'
    let age = 18
    // 方法
    function sayName() {
      alert(`我叫${name}, 今年${age}岁`)
    }
    return {
      name,
      age,
      sayName,
    }
  }
}
</script>
  •  setup 如果返回一个渲染函数,则可以自定义渲染内容
  •  setup 函数内部  this 是  undefined 
  •  setup 函数不能是一个  async 函数,因为  async 函数会将返回值包装成一个  promise 
  •  setup 是在  beforeCreate 之前执行的
  •  setup 接收2个参数  props 和  context 上下文对象
  •  props 值为对象,组件外部传递过来的且组件内部声明接收了的属性
  •  context 上下文对象,其中有3个属性。 attrs 值为对象,组件外部传递过来的数据没有接收,相当于  this.$attrs 。 slots 收到的插槽内容,相当于 this.$slots 。 emit 分发自定义事件的函数,相当于  this.$emit 

ref函数

  •  ref 函数主要的作用是给 基本类型数据 添加响应式功能
  •  ref 函数的返回值是一个 RefImpl 对象 (reference implement 引用实现对象),通过该对象的  value 属性可以取到值,在模块中使用数据不用写  value 属性取值, vue 会自动帮我们调用  value  取值
  •  ref 函数内部通过  Object.definePropty 函数实现响应式功能
<template>
  <h1>我是APP组件</h1>
  <p>{{name}} --- {{age}}</p>
  <button @click="changeInfo">修改人的信息</button>
</template>

<script>
import {ref} from 'vue'
export default {
  name: 'App',
  setup() {
    // 数据
    let name = ref('zs') // 通过ref函数添加响应功能
    let age = ref(18)
    // 方法
    function changeInfo() {
      name.value = 'ls'
      age.value = 66
      console.log(name, age)
    }
    return {
      name,
      age,
      changeInfo,
    }
  }
}
</script>
  • 也可以传递对象给  ref 函数, ref 函数内部通过  reactive 函数实现响应式
<template>
  <h1>我是APP组件</h1>
  <p>{{name}} --- {{age}}</p>
  <p>{{job.type}} --- {{job.salary}}</p>
  <button @click="changeInfo">修改人的信息</button>
</template>

<script>
import {ref} from 'vue'
export default {
  name: 'App',
  setup() {
    // 数据
    let name = ref('zs')
    let age = ref(18)
    let job = ref({ // ref 函数也可以给对象类型数据添加响应式
      type: '前端',
      salary: '3000块'
    })
    // 方法
    function changeInfo() {
      name.value = 'ls'
      age.value = 66
      job.value.type = 'web前端'
      job.value.salary = '3100块'
    }
    return {
      name,
      age,
      job,
      changeInfo,
    }
  }
}
</script>

reactive函数

  • 将对象变成响应式数据,内部通过 ES6 的  proxy 实现的
  • reactive 函数将对象添加为响应式数据,在使用的过程中不需要  .value 来取值
<template>
  <h1>我是APP组件</h1>
  <p>{{name}} --- {{age}}</p>
  <p>{{job.type}} --- {{job.salary}}</p>
  <button @click="changeInfo">修改人的信息</button>
</template>

<script>
import {ref, reactive} from 'vue'
export default {
  name: 'App',
  setup() {
    // 数据
    let name = ref('zs')
    let age = ref(18)
    let job = reactive({ // reactive定义的响应式数据可以直接使用(无必通过 .value 取值)
      type: '前端',
      salary: '3000块'
    })
    // 方法
    function changeInfo() {
      name.value = 'ls'
      age.value = 66
      job.type = 'web前端'
      job.salary = '3200块'
    }
    return {
      name,
      age,
      job,
      changeInfo,
    }
  }
}
</script>
  •  ref 用来定义基本类型的数据,定义复杂类型的数据内部借助了  reactive 。 reactive 只能定义复杂类型的数据
  •  ref 通过  Object.defineProperty() 的  get 和  set 来实现响应式。  reactive 通过 Proxy 来实现响应式,并通过 Reflect 操作源对象内部的数据
  •  ref 操作数据需要  .value ,模板使用数据则不用  .value 。 reactive 操作数据和读取均不用  .value 

computed 函数

  • 与  vue2 中的计算属性配置一样,可以接收一个回调函数(仅使用计算属性的 get 方法),也可以接收一个配置对象(内含 get / set 方法)
<template>
  <div>姓:<input type="text" v-model="person.firstName"></div>
  <div>名:<input type="text" v-model="person.lastName"></div>
  <span>全名:{{fullName}}</span>
  <div>全名:<input type="text" v-model="fullName"></div>
</template>

<script>
import {reactive, computed, } from 'vue'
export default {
  name: 'Demo',
  setup() {
    // 数据
    let person = reactive({
      firstName: '',
      lastName: ''
    })
    // 计算属性 (简写没有考虑计算属性的set)
    // let fullName = computed(() => {
    //   return person.firstName + '-' + person.lastName
    // })
    // 计算属性
    let fullName = computed({ 
      get() {
        return person.firstName + '-' + person.lastName
      },
      set(newValue) {
        const [firstName, lastName] = newValue.split('-')
        person.firstName = firstName
        person.lastName = lastName
      }
    })
    return {
      person,
      fullName,
    }
  }
}
</script>

watch函数

  • 监听一个 ref 所定义的数据
<template>
  <h2>当前求和为:{{sum}}</h2>
  <button @click="sum++">自增</button>
</template>

<script>
import {ref, watch, } from "vue";
export default {
  name: 'Demo',
  setup() {
    let sum = ref(0)
    // 监听
    watch(sum, (newValue, oldValue) => {
      console.log(`sum的值发生了改变以前的值是${oldValue} 现在的值是${newValue}`);
    })
    return {
      sum
    }
  }
}
</script>
  • 当  watch 的第一个参数发生变化后,会自动执行第二个参数的回调函数
  • 监听多个  ref 所定义的数据
<template>
  <h2>当前求和为:{{sum}}</h2>
  <button @click="sum++">自增</button>
  <h2>当前信息为 {{msg}}</h2>
  <button @click="msg+= '!'">修改信息</button>
</template>

<script>
import {ref, watch, } from "vue";
export default {
  name: 'Demo',
  setup() {
    let sum = ref(0)
    let msg = ref('一个消息')
    // 监听多个ref定义的数据
    watch([sum, msg], (newValue, oldValue) => {
      console.log(`以前的数据`, oldValue) //以前的数据 [sum, msg]
      console.log(`现在的数据`, newValue)
    }, {
      immediate: true, // 立即执行一次监听
    })
    return {
      sum,
      msg,
    }
  }
}
</script>
  •  watch 函数的第三个参数可以配置  immediate: true 表示立即执行一次监听
  • 使用  watch 监听  reactive 定义的数据
<template>
  <div>{{person.name}} --- {{person.age}} ---- {{person.job.j1.salary}}</div>
  <div>
    <button @click="person.name+='~'">修改姓名</button>
    <button @click="person.age++">增加年龄</button>
    <button @click="person.job.j1.salary++">增加工资</button>
  </div>
</template>

<script>
import {reactive, watch} from 'vue'
export default {
  name: 'Demo',
  setup() {
    let person = reactive({
      name: '张三',
      age: 18,
      job: {
        j1: {
          salary: 666
        }
      }
    })
    // 监视reactive所定义的数据
    watch(person, (newValue, oldValue) => {
      console.log(`以前的数据`, oldValue); // 无法正确获取oldValue
      console.log(`现在的数据`, newValue);
    }, {
      deep: false, // 配置深度监听无效(默认是深度监听)
    })
    return {
      person
    }
  }
}
</script>
  • 这块有2个问题,无法正确获取  oldValue 以前的旧值,配置深度监听无效(默认是开启深度监听)
  • 使用  watch 监听  reactive 定义的数据中的某一个属性的变化
<template>
  <div>{{person.name}} --- {{person.age}} ---- {{person.job.j1.salary}}</div>
  <div>
    <button @click="person.name+='~'">修改姓名</button>
    <button @click="person.age++">增加年龄</button>
    <button @click="person.job.j1.salary++">增加工资</button>
  </div>
</template>

<script>
import {reactive, watch} from 'vue'
export default {
  name: 'Demo',
  setup() {
    let person = reactive({
      name: '张三',
      age: 18,
      job: {
        j1: {
          salary: 666
        }
      }
    })
    // 监视reactive所定义的数据
    watch(() => person.age, (newValue, oldValue) => {
      console.log(`以前的年龄是`, oldValue)
      console.log(`现在的年龄是`, newValue)
    }, {
      deep: false, // 配置深度监听无效(默认是深度监听)
    })
    return {
      person
    }
  }
}
</script>
  • 监听 reactive 定义的数据中的某一个属性变化时, watch 函数的第一个参数需要是函数并返回监听的内容
  • 监听  reactive 定义的数据中的某一些属性的变化
<template>
  <div>{{person.name}} --- {{person.age}} ---- {{person.job.j1.salary}}</div>
  <div>
    <button @click="person.name+='~'">修改姓名</button>
    <button @click="person.age++">增加年龄</button>
    <button @click="person.job.j1.salary++">增加工资</button>
  </div>
</template>

<script>
import {reactive, watch} from 'vue'
export default {
  name: 'Demo',
  setup() {
    let person = reactive({
      name: '张三',
      age: 18,
      job: {
        j1: {
          salary: 666
        }
      }
    })
    // 监视reactive所定义的数据
    watch([() => person.age, () => person.name], (newValue, oldValue) => {
      console.log(`以前的年龄和姓名是`, oldValue)
      console.log(`现在的年龄和姓名是`, newValue)
    }, {
      deep: false, // 配置深度监听无效(默认是深度监听)
    })
    return {
      person
    }
  }
}
</script>
  • 将多个内容写在数组中

watchEffect 函数

  • 监听的是回调函数中用到了哪些属性,如果回调中的属性发生了变化自动执行回调
<template>
  <div>{{sum}}</div>
  <button @click="sum++">自增</button>
</template>

<script>
import {ref, watchEffect, } from 'vue'
export default {
  name: 'Demo',
  setup() {
    let sum = ref(0)
    watchEffect(() => {
      // 使用到了 ref 函数定义的 sum 变量
      const x1 = sum.value; // 该sum变量发生改变立即执行该回调
      console.log('watchEffect所指定的回调执行了', x1);
    })
    return {
      sum,
    }
  }
}
</script>
  • 立即执行传入的一个函数,同时响应式追踪其依赖,并在其依赖变更时重新运行该函数
posted @ 2021-12-27 16:01  霸哥yyds  阅读(73)  评论(0)    收藏  举报