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
-
理解:vue3.0中的一个新的配置项,值为一个函数
-
setup是所有
Composition API (组合API)入口函数 -
组件中所用到的:数据、方法等,军要配置在setup中
-
setup函数有2种返回值:
-
若返回一个对象,则对象中的属性、方法,在模板中均可以直接使用(重点)
-
若返回一个渲染函数:则自定义渲染内容
-
-
2个注意点
-
尽量不要与vue2.x配置混用、
-
setup不能是一个async函数:因为async函数的返回值不再是return回的对象,而是
promise,模板看不到return对象中的属性数据
-
参数
setup 函数,接收两个参数: props 和 context
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:
propsattrsslotsemit
换句话说,你将无法访问以下组件选项:
datacomputedmethods
结合模板使用
如果 setup 返回一个对象,那么该对象的 property 以及传递给 setup 的 props 参数中的 property 就都可以在模板中访问到.
从 setup 返回的 [refs]在模板中访问时是被自动浅解包的,因此不应在模板中使用 .value
使用 this
在 setup() 内部,this 不是该活跃实例的引用,因为 setup() 是在解析其它组件选项之前被调用的
@ To Me
- setup是在
beforeCreate生命周期回调之前就执行了(组件还未创建),而且只执行一次 - setup在执行的时候,当前的组件还没有创建出来,也就意味着,组件实例对象
this根本不能用 - this是undefined,所以不能用this来访问data/computed/methods
- setup中的返回值是一个对象,内部的属性和方法是给html模板使用的
- 在vue3中尽量不要混合使用data和setup 及 methods和setup
- 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
- 是 Vue3 的 composition API 中 2 个最重要的响应式 API(ref和reactive)
ref用来处理基本类型数据,reactive用来处理对象(递归深度响应式)- 如果用 ref 对象/数组, 内部会自动将对象/数组转换为 reactive 的代理对象
- ref中如果放入的是一个对象,那么是经过了reactive的处理,形成了一个Proxy类型的对象
- ref 内部: 通过给
value 属性添加 getter/setter 来实现对数据的劫持 - ref 的数据操作: 在 js 中要.value, 在模板中不需要(内部解析模板时会自动添加.value)
- ref获取元素
-
reactive
返回对象的响应式副本
响应式数据
作用:定义多个数据的响应式,即定义一个对象类型的响应式数据(基本类型不要用它要用ref函数)
语法:const proxy = reactive(obj)接收一个普通对象(或数组),返回一个普通对象(或数组)的响应式代理器对象(proxy对象)
reactive定义的响应式数据响应式转换是“深层的”:会影响对象内部所有嵌套的属性,在基于 ES2015 Proxy的实现中,返回的 proxy 是不等于原始对象的。建议只使用响应式 proxy,避免依赖原始对象。
内部基于 ES5 的 Proxy实现,通过代理对象操作源对象内部数据都是响应的
@ To Me
- 是 Vue3 的 composition API 中 2 个最重要的响应式 API(ref和reactive)
- reactive将普通对象通过代理变成响应式数据
- reactive 内部: 通过使用 Proxy 来实现对对象内部所有数据的劫持, 并通过 Reflect 操作对象内部数据
-
ref 与 reactive 对比
从定义数据角度对比:
- ref用来定义:
本数据类型 - reactive用来定义:
象(或数组)类型的数据 - 备注:ref也可用来定义
象(或数组)类型数据它内部会自动reactive转为代理对象
从原理角度对比:
- ref通过
Object.defineProperty()的get与set来实现响应式(数据劫持) - reactive通过
Proxy来实现响应式(数据劫持),并通过Reflect操作源对象内部的数据
从使用角度对比:
- ref定义的数据:操作数据
需要.value,读取数据时模板中不需.value - reactive定义的数据:操作数据与读取数据,
均不需要.value