vue3+ts

198 阅读6分钟

Vue3快速上手

1.认识vue3

Vue.js 是什么 是一套用于构建用户界面的渐进式框架。 Vue 被设计为可以自底向上逐层应用 Vue 的核心库只关注视图层 单页应用

2.创建vue3项目

1) 使用vue-cli创建

1.安装vue-cli3

npm install -g @vue/cli
vue create my-project
cd  my-project
npm install
npm run dev

注:vue版本最好在4.5.0以上

2) 使用vite创建

npm init vite-app  my-project
cd  my-project
npm install
npm run dev

3.组合API(Composition API)

  • setup

  1. 理解:vue3.0中的一个新的配置项,值为一个函数

  2. setup是所有Composition API (组合API)入口函数

  3. 组件中所用到的:数据、方法等,军要配置在setup中

  4. setup函数有2种返回值:

    1. 若返回一个对象,则对象中的属性、方法,在模板中均可以直接使用(重点)

    2. 若返回一个渲染函数:则自定义渲染内容

  5. 2个注意点

    1. 尽量不要与vue2.x配置混用、

    2. setup不能是一个async函数:因为async函数的返回值不再是return回的对象,而是promise,模板看不到return对象中的属性数据

参数

setup 函数,接收两个参数: propscontext

props

理解:值为对象,包含:组件外部传递过来,且组件内部声明接收了的属性

setup 函数中的第一个参数是 props

  • setup 函数中的 props 是响应式的,当传入新的 prop 时,它将被更新
  • 因为 props 是响应式的,你不能使用 ES6 解构,它会消除 prop 的响应性。
  • 如果需要解构 prop,可以在 setup 函数中使用 toRefs函数来完成此操作
import { toRefs } from 'vue'

setup(props) {
  const { title } = toRefs(props)

  console.log(title.value)
}

context

理解:上下文对象

传递给 setup 函数的第二个参数是 context

context 是一个普通的 JavaScript 对象,它暴露组件的三个 property:attrs,slots,emit

attrs:值为对象,包含组件外部传递过来,但在没有props配置中声明的属性,相当于 this.$attrs

slots:插槽内容,相当于 this.$slots

emit:分发自定义事件的函数,this.$emit

export default {
  setup(props, context) {
    // Attribute (非响应式对象)
    console.log(context.attrs)

    // 插槽 (非响应式对象)
    console.log(context.slots)

    // 触发事件 (方法)
    console.log(context.emit)
  }
}

context 是一个普通的 JavaScript 对象,也就是说,它不是响应式的,这意味着你可以安全地对 context 使用 ES6 解构。

export default {
  setup(props, { attrs, slots, emit }) {
    ...
  }
}

访问组件的 property

执行 setup 时,组件实例尚未被创建。因此,你只能访问以下 property:

  • props
  • attrs
  • slots
  • emit

换句话说,你将无法访问以下组件选项:

  • data
  • computed
  • methods

结合模板使用

如果 setup 返回一个对象,那么该对象的 property 以及传递给 setup 的 props 参数中的 property 就都可以在模板中访问到.

从 setup 返回的 [refs]在模板中访问时是被自动浅解包的,因此不应在模板中使用 .value

使用 this

在 setup() 内部,this 不是该活跃实例的引用,因为 setup() 是在解析其它组件选项之前被调用的

@ To Me

  1. setup是在beforeCreate生命周期回调之前就执行了(组件还未创建),而且只执行一次
  2. setup在执行的时候,当前的组件还没有创建出来,也就意味着,组件实例对象this根本不能用
  3. this是undefined,所以不能用this来访问data/computed/methods
  4. setup中的返回值是一个对象,内部的属性和方法是给html模板使用的
  5. 在vue3中尽量不要混合使用data和setup 及 methods和setup
  6. setup不能是一个async函数:因为async函数的返回值不再是return回的对象,而是promise,模板看不到return对象中的属性数据

响应式API

  • ref

ref用法—实现响应式数据

接受一个内部值并返回一个响应式且可变的 ref 对象。ref 对象具有指向内部值的单个 property .value

const count = ref(0)
console.log(count.value) // 0

count.value++
console.log(count.value) // 1

* ref另一种用法——获取元素

获取单个元素

指定ref元素: <p ref="txtRef">文本</p> setup中创建ref属性:

setup() {
    // 默认是空的,页面加载完毕,说明组件已经存在了
    const txtRef = ref<HTMLElement | null>(null);
    onMounted(() => {
      nextTick(() => {
        console.log(txtRef.value);
        if(txtRef.value){
            txtRef.value.style.color = 'red';
         }
      })
    });

    return {
      txtRef,
    }
 }

获取多个元素

指定ref元素: <li v-for="(i, idx) in 3" :key="idx" :ref="setLiRef">列表</li>

创建ref元素数组:

setup(props, context) {

    const liRefs = [];

    const setLiRef = (el) => {
      if (el) {
        liRefs.push(el);
      }
    }
    
    onMounted(){
      nextTick(() => {
        console.log("li", liRefs);
        liRefs.forEach((item, index) => {
          console.log("li元素---", item);
        });
      });
    }
    
    return {
        setLiRef
    }
}

@ To Me

  1. 是 Vue3 的 composition API 中 2 个最重要的响应式 API(ref和reactive)
  2. ref 用来处理基本类型数据, reactive 用来处理对象(递归深度响应式)
  3. 如果用 ref 对象/数组, 内部会自动将对象/数组转换为 reactive 的代理对象
  4. ref中如果放入的是一个对象,那么是经过了reactive的处理,形成了一个Proxy类型的对象
  5. ref 内部: 通过给 value 属性添加 getter/setter 来实现对数据的劫持
  6. ref 的数据操作: 在 js 中要.value, 在模板中不需要(内部解析模板时会自动添加.value)
  7. ref获取元素
  • reactive

返回对象的响应式副本

响应式数据

作用:定义多个数据的响应式,即定义一个对象类型的响应式数据(基本类型不要用它要用ref函数)

语法:const proxy = reactive(obj)接收一个普通对象(或数组),返回一个普通对象(或数组)的响应式代理器对象(proxy对象)

reactive定义的响应式数据响应式转换是“深层的”:会影响对象内部所有嵌套的属性,在基于 ES2015 Proxy的实现中,返回的 proxy 是等于原始对象的。建议只使用响应式 proxy,避免依赖原始对象。

内部基于 ES5 的 Proxy实现,通过代理对象操作源对象内部数据都是响应的

@ To Me

  1. 是 Vue3 的 composition API 中 2 个最重要的响应式 API(ref和reactive)
  2. reactive将普通对象通过代理变成响应式数据
  3. reactive 内部: 通过使用 Proxy 来实现对对象内部所有数据的劫持, 并通过 Reflect 操作对象内部数据
  • ref 与 reactive 对比

从定义数据角度对比:

  1. ref用来定义:本数据类型
  2. reactive用来定义:象(或数组)类型的数据
  3. 备注:ref也可用来定义象(或数组)类型数据它内部会自动reactive转为代理对象

从原理角度对比:

  1. ref通过Object.defineProperty()的getset来实现响应式(数据劫持)
  2. reactive通过Proxy来实现响应式(数据劫持),并通过Reflect操作源对象内部的数据

从使用角度对比:

  1. ref定义的数据:操作数据需要.value,读取数据时模板中不需.value
  2. reactive定义的数据:操作数据与读取数据,均不需要.value