vue3.0 项目创建
使用vue-cli创建
1.查看@vue/cli的版本,确保@vue/cli版本在4.5.0以上
vue --version
2.安装或者升级你的@vue-cli
3.创建
vue create vueproject
4.启动
cd vueproject
npm run serve
使用vite创建
vite要求Node.js版本在16.0以上
npm init vite hello-vue3 -- --template vue //生成模板页面
npm init vite my-vue-app //可以选择是Vue还是React以及选择JS语言还是TS语言
启动项目:npm run dev
hello-vue3和my-vue-app是我们的项目名称,可以随意进行修改,template vue是创建一个vue模板。
- vite是新一代的前端工具
- 优势如下:
- 开发环境中,无需打包,可快速的冷启动
- 轻量快速的热加载
setup
setup的设计是为了使用组合式API,组合API的入口点就是setup函数,组件中所有用到的数据、方法等,均要配置在setup中。
- setup函数有两种返回值
- 1.若返回一个对象,则对象中的数据、方法、在模板中均可直接使用
- 2.若返回一个渲染函数,则可以自定义渲染内容
// 返回一个对象
<template>
<div>
<h1>{{title}}---{{a}}</h1>
<p>{{msg}}</p>
<button @click="fn">打印this当前组件</button>
<button @click="fm">改变响应式数据</button>
</div>
</template>
<script>
// 引入ref工具,setup函数内部的变量可以设计为响应式数据,就必须使用官方的hook
import { ref } from "vue"
export default {
setup() {
let a=13;
let msg=ref('响应式数据');
function fn(){
console.log(this);
}
let fm=()=>{
msg.value=msg.value+'已经改变了';
}
return {title:'App组件首页',fn,a,msg,fm}
}
}
</script>
<style lang="scss">
</style>
- vue3中setup函数的理解
-
- setup函数返回的对象的成员可以在模板中使用也可以在组件的API中使用,但是这个函数中不能使用组件API中的东西。
-
- setup函数中可以声明标识符(变量和函数)然后返回出去供组件使用。这个函数内部的变量和函数是局部的
-
- setup函数内部的变量不是响应式的,setup在组件加载期间只会运行1次,所以这个函数中的返回的对象中的数据不是响应式的,模板标签只会取第1次运行的变量的值,后面改了数据页面不会更新
-
- setup函数内部的变量可以设计为响应式数据,就必须使用官方的hook,也就是ref和reactive等工具
-
- 这个函数内部可以使用组件的所有属性和功能,data,methods,computed,watch和生命周期函数等
-
- 当setup返回的对象中的数据和data中的数据同名了,setup优先级更高
-
- 这个函数内部不要使用this来操作组件数据,setup位于created 和beforeCreated之前,用于代替created 和beforeCreated,但是在setup函数里不能访问到this。
-
-
setup函数可以设计成 script标签中写这个同名单词的属性 然后使整个标签环境都为setup函数环境,就可以不用将所有的数据用对象返回(脚手架实现的一个语法糖)
-
-
<script setup>
import { ref,reactive } from "vue"
import son from './components/Son.vue'
let a=13;
let title='Tara';
let obj=ref({age:33,name:'hyomin'});
let arr=ref([{name:'jzx',age:26}]);
let fg=()=>{
obj.value={age:33,name:'jessica jung'}
arr.value[0].age=18;
};
let obj2=reactive({title:'with love J',singer:{name:'jessica',son:['小除号']},music:['fly']});
let fm=()=>{
obj2.singer.son[0]='BLANC&ECLARE'
}
</script>
<template>
<div>
<h1>{{title}}---{{a}}</h1>
<p>{{obj.name}}----{{obj.age}}</p>
<p>{{arr[0].name}}------{{arr[0].age}}</p>
<p>{{obj2.title}}---{{obj2.music[0]}}</p>
<p>{{obj2.singer.name}}----{{obj2.singer.son[0]}}</p>
<button @click='fg'>修改人物</button>
<button @click='fm'>小除号</button>
<son></son>
</div>
</template>
<style scoped>
</style>
ps:1.setup不能是一个async函数,因为返回值不再是return的对象,而是Promise,模板看不到return对象中的属性。
2.尽量不要和Vue2.x配置混用,Vue2.x配置(data,methods,computed等)中可以访问setup中的属性,方法。但在setup中不能访问到Vue2.x配置(data,methods,computed等)
//页面中会显示一个h1标签,标签的内容是"vue3返回渲染函数"
<script>
import {h} from 'vue'
export default {
setup() {
// 返回一个渲染函数
// h相当于document.CreateElement()
return ()=>{return h("h1","vue3返回渲染函数")}
}
}
</script>
ref函数
- ref函数作用:定义一个响应式的数据
- 语法:let xxx = ref("value")
- 创建一个包含响应式的数据的引用对象(reference对象)
- js中setup函数操作数据:xxx.value
- 模板中读取数据不需要.value,直接
<div>{{xxx}}</div>
- 注意
- 接收的数据类型可以是基本数据类型也可以是引用数据类型
- 基本类型的数据:响应式依然是靠Object.defineProperty()的get和set完成的
- 对象类型的数据:内部借用了Vue3.0的一个新的函数----reactive函数
ref响应式设计就是它监听了value的改变,劫持value属性的setter和getter
ref一般用于基本数据或者引用数据嵌套层级不深的数据(深层级嵌套的引用数据需要一层一层遍历劫持其数据)
<script setup>
import { ref,reactive } from "vue"
let a=13;
let title='Tara';
let obj=ref({age:33,name:'hyomin'});
let arr=ref([{name:'jzx',age:26}]);
// arr不是数组,arr是ref返回的引用对象(reference对象)
let fg=()=>{
obj.value={age:33,name:'jessica jung'}
arr.value[0].age=18;
};
</script>
<template>
<div>
<h1>{{title}}---{{a}}</h1>
<p>{{obj.name}}----{{obj.age}}</p>
<p>{{arr[0].name}}------{{arr[0].age}}</p>
<p>{{obj2.title}}---{{obj2.music[0]}}</p>
<p>{{obj2.singer.name}}----{{obj2.singer.son[0]}}</p>
<button @click='fg'>修改人物</button>
</div>
</template>
<style scoped>
reactive函数
- 作用:定义一个对象类型的响应式数据
- 语法:let xxx = reactive(被代理的对象),],接收一个对象(或数组),返回一个代理器对象(proxy对象)
- reactive定义的响应式数据是深层次嵌套的引用数据
- 内部基于ES6的Proxy实现,通过代理对象内部的数据都是响应式的
- js和模板都不需要.value
<script setup>
import { ref,reactive } from "vue"
import son from './components/Son.vue'
let a=13;
let title='Tara';
let obj2=reactive({title:'with love J',singer:{name:'jessica',son:['小除号']},music:['fly']});
// obj2是 reactive(被代理的数据对象)返回的一个代理器对象(proxy对象)
// reactive也是响应式设计和ref一样,但是底层采用的ES6的Proxy代理了整个引用数据,实现响应式设计
let fm=()=>{
obj2.singer.son[0]='BLANC&ECLARE'
}
</script>
<template>
<div>
<h1>{{title}}---{{a}}</h1>
<p>{{obj2.title}}---{{obj2.music[0]}}</p>
<p>{{obj2.singer.name}}----{{obj2.singer.son[0]}}</p>
<button @click='fm'>小除号</button>
</div>
</template>
<style scoped>
</style>
reactive也是响应式设计和ref一样,但是底层采用的ES6的Proxy代理了整个引用数据,实现响应式设计
Vue3.0中的响应式原理
-
vue2.0的响应式实现原理
- 对象类型:通过Object.definedProperty()对属性的读取、修改进行拦截(数据劫持)
- 数组类型:通过重写更新数据的一系列方法来实现拦截。(对数组的方法进行了包裹)
-
存在问题:
- 新增属性,删除属性都不会刷新界面
- 直接通过下标修改数组,界面不会自动更新
-
vue3.0的响应式实现原理
- 通过Proxy(代理):拦截对象中任意属性的变化,包括:属性的读写,属性的添加,属性的删除等
- 通过Reflect(反射):对被代理对象的属性进行操作