2022全面升级!Vue3 + TS 仿知乎专栏企业级项目完结

2022全面升级!Vue3 + TS 仿知乎专栏企业级项目
download : https://www.sisuoit.com/3301.html
<p>1.使用vue-cli创建Vue3.0项目(js版本)官方文件:https://cli.vuejs.org/zh/guide/creating-a-project.html # vue-create比如,随着人工智能的不断发展,机器学习变得越来越重要,很多人都开始学习机器学习。本文介绍了机器学习的基本内容。# #检查@vue/cli的版本,确保@vue/cli的版本高于4.5.0。vue版本# #安装或升级您的@vue/clinpm安装-g @vue/cli# #创建vue创建vue _测试# #开始cd vue _测试npm运行服务二、常用的组合API1.设置了解:Vue3.0中新增的一个配置项,其值是一个函数。设置是所有组合API的“表演舞台”。数据、方法等。在组件中使用的应该在设置中配置。设置函数的两个返回值:如果返回一个对象,则该对象中的属性和方法可以直接在模板中使用。(重点!)如果返回渲染函数,您可以自定义渲染内容。(理解)注意:尽量不要和Vue2.x配置混用。设置中的属性和方法可在Vue2.x配置中访问(数据、方法、计算...).但是您无法访问Vue2.x配置(数据、方法、计算...)在设置中。如果有重名,安装程序优先。Setup不能是异步函数,因为返回值不再是返回的对象,而是承诺,模板看不到返回对象中的属性。(后面也可以返回一个Promise实例,但是需要悬疑和异步组件的配合。)某人的信息姓名:{ {姓名}}年龄:{ {年龄}}——sayHello(由Vue3配置)导出默认值{名称:“应用程序”,//这里只是对设置的一个测试。我们暂且不考虑响应性的问题。setup(){//数据Let = '张三'假设年龄= 18岁设a = 200//方法函数sayHello(){Alert(`我的名字是${name},今年${age}岁。你好!`)}//返回一个对象(常用)返回{姓名,年龄,说你好,}}}1.1安装时需要注意两点安装程序的执行时间在创建之前执行一次,这是未定义的。设置参数Props:值是一个对象,它包含:从组件外部传递过来的,由内部组件声明接收的属性。Attr:值是一个对象,它包含:从组件外部传递过来但没有在props配置中声明的属性,相当于这个。$attrs。Slots:接收到的slot内容相当于这个。$老虎机。Emit:分发自定义事件的函数,相当于这个。$emit。上下文:上下文对象2.参考函数1.功能:定义一个响应数据。2.语法:const xxx = ref(initValue)创建一个包含响应数据的引用对象(简称ref对象)。JS: xxx.value中的操作数据正在读取模板中的数据:。不需要值,直接:{{ xxx }}3.备注:接收的数据可以是基本类型或对象类型。类型的基本数据:响应还是由Object.defineProperty()的get和set来完成。4.vue3如何通过ref属性获取元素?我是DIV导入{ref,onMounted}导出默认值{setup(){let box = ref(null);onMounted(()=>{console.log(box.value)});返回{box}}}5.Vue3的父组件调用子组件的方法//父组件父页面试验导入{定义一个组件,裁判,}来自‘vue’;导出默认定义组件({setup(){const son ref = ref(null);const handleClick = () => {son ref . value . song();}return { sonRef,handleClick,}}})//子组件子页面导入{定义组件}来自‘vue’;导出默认定义组件({setup(){const song =()= > alert(' hello world ');返回{宋,//不忘回报}}})某人的信息姓名:{ {姓名}}年龄:{ {年龄}}作业类型:{{job.type}}薪资:{{job.salary}}修改人们的信息从“vue”导入{ref}导出默认值{名称:“应用程序”,setup(){//数据Let = ref('张三')设年龄= ref(18)let job = ref({类型:“前端工程师”,薪水:“30K”})//方法函数changeInfo(){// name.value = '李四'// age.value = 48console.log(作业.值)// job.value.type = 'UI designer '// job.value.salary = '60K '// console.log(姓名,年龄)}//返回一个对象(常用)返回{姓名,年龄,工作,changeInfo}}}3.反应函数函数:定义对象类型的响应数据(不要将其用于基本类型,使用ref函数)语法:const Proxy object = reactive(源对象)接收一个对象(或数组)并返回一个代理对象(Proxy的实例对象,简称代理对象)。reactive定义的响应式数据是“深度”的。基于内部ES6的代理实现通过代理对象操作源对象的内部数据。某人的信息姓名:{{person.name}}年龄:{{person.age}}作业类型:{{person.job.type}}薪资:{{person.job.salary}}爱好:{{person.hobby}}测试数据c: {{person.job.a.b.c}}修改人们的信息从“vue”导入{reactive}导出默认值{名称:“应用程序”,setup(){//数据让人=被动({姓名:'张三',年龄:18,工作:{类型:“前端工程师”,工资:' 30K ',答:{乙:{丙:666}}},爱好:['抽烟','喝酒','烫发']})//方法函数changeInfo(){Person.name = '李四'人.年龄= 48Person.job.type = 'UI designer 'person.job.salary = '60K 'person . job . a b . c = 999Person.hobby[0] = '学习'}//返回一个对象(常用)返回{人,changeInfo}}}4.VUE 3.0中的回应原则4.1 vue 2 . x的响应1.实施原则:类型:通过Object.defineProperty()拦截属性的读取和修改(数据劫持)。数组类型:通过重写一系列更新数组的方法来实现拦截。(改变数组的方法是包装好的)。Object.defineProperty(data,' count ',{get () {},set () {}})2.存在的问题:添加或删除属性,界面不会更新。通过下标直接修改数组,界面不会自动更新。仿真Vue2中响应的实现//源数据let person = {姓名:'张三',年龄:18岁}Object.defineProperty(p,' name ',{可配置:真,当有人读名字时调用Get(){ //函数返回人员姓名},Set(value){ //当有人修改名称时调用console . log(‘有人修改了name属性,我发现了。我要更新界面了!)person.name =值}})Object.defineProperty(p,' age ',{Get(){ //当有人读取年龄时调用返回person.age},Set(value){ //当有人修改年龄时调用console . log(‘有人修改了年龄属性,我发现了。我要更新界面了!)人.年龄=价值}})4.2响应4.2 Vue3.01.实施原则:通过代理:拦截对象中任意属性的变化,包括读写属性值、添加属性、删除属性等。通过反射:对源对象的属性进行操作。MDN文档中描述的代理和反射:代理:https://developer.mozilla.org...反射:https://developer.mozilla.org...2.模拟Vue3中的响应//源数据let person = {姓名:'张三',年龄:18岁}const p =新代理(person,{//当有人读取p的一个属性时调用。get(目标,属性名){Console.log(`有人读取了P `上的${ propName }属性)返回Reflect.get(目标,属性名)},//当有人修改或将属性追加到p时调用。set(目标,属性名,值){Console.log(`有人修改了p上的${propName}属性,我要更新界面了!`)Reflect.set(目标,属性名,值)},//当有人删除p的一个属性时调用。deleteProperty(target,propName){Console.log(`有人删除了p上的${propName}属性,我要更新界面了!`)返回Reflect.deleteProperty(目标,属性名)}})5.电抗与基准电压的关系1.从定义数据的角度进行比较:Ref用于定义:基本类型数据。Reactive用于定义:对象(或数组)类型数据。注意:ref也可以用来定义对象(或数组)类型数据,其内部会通过reactive自动转换为代理对象。2.从原理角度比较:响应(数据劫持)是通过Object.defineProperty()的get和set实现的。Reactive通过使用代理实现responsive(数据劫持),通过Reflect操作源对象内部的数据。3.从使用角度比较:引用定义的数据:。值是操作数据所必需的,但是。读取数据时,模板中的直接读取不需要值。反应式定义数据:运行数据和读取数据:不需要。价值。7.计算属性和监控7.1.计算函数与Vue2.x中computed的配置功能一致写作方法某人的信息姓氏:名称:全名:{{person.fullName}}全名:从“vue”导入{反应式,计算式}导出默认值{名称:'演示',setup(){//数据让人=被动({名字:'张',姓氏:“三”})//计算属性-速记(不考虑计算属性的修改)/* person . full name = computed(()= > {返回person . first name+'-'+person . last name}) *///计算属性——全写(考虑读写)person.fullName = computed({get(){返回person . first name+'-'+person . last name},设置(值){const nameArr = value.split('-')person.firstName = nameArr[0]person.lastName = nameArr[1]}})//返回一个对象(常用)返回{人}}}7.2.手表功能1.与Vue2.x中的手表配置功能一致2.两个小“坑”:在监控reactive定义的响应式数据时:oldValue无法正确获取,强行开启深度监控(深度配置失败)。当监控由reactive: deep配置定义的响应数据中的属性时,该配置有效。3.写作方法当前总和为:{{sum}}点+1当前信息是:{{msg}}修改信息姓名:{{person.name}}年龄:{{person.age}}薪资:{{person.job.j1.salary}}K修改名称成长年龄涨薪从“vue”导入{ref,reactive,watch}导出默认值{名称:'演示',setup(){//数据让sum = ref(0)Let msg = ref ('Hello ')让人=被动({名字:“小叮当~”,年龄:18,工作:{j1:{工资:20英镑}}})//情况1:监控ref定义的响应数据手表(总和,(新值,旧值)=>{Console.log('sum changed ',newValue,oldValue)},{immediate:true})//情况2:监控ref定义的多个响应数据手表([sum,msg],(newValue,oldValue)=>{Console.log('sum或msg已更改',新值,旧值)},{immediate:true})/*案例3:监控由reactive定义的响应数据的所有属性。1.注意:此处无法正确获取旧值。2.注意:深度监控是强制开启的(深度配置无效)*/手表(人,(新值,旧值)=>{Console.log('人员已更改',新值,旧值)},{deep:false}) //此处的深度配置无效。//情况4:监控reactive定义的响应数据中的一个属性。手表(()=>person.name,(newValue,oldValue)=>{Console.log('人名已更改',新值,旧值)})//情况五:监控reactive定义的一个响应式数据中的一些属性。watch([()=>person.name,()=>person.age],(newValue,oldValue)=>{Console.log('姓名或年龄已更改',newValue,oldValue)})//特殊情况手表(()=>person.job,(newValue,oldValue)=>{Console.log('人员的工作已更改',新值,旧值)},{deep:true})//在这里,深度配置是有效的,因为它监视由反应性元素定义的对象中的一个属性。//返回一个对象(常用)返回{总和,味精,人}}}7.3.watchEffect功能1.watch的套路是:既要指明被监控的属性,又要指明被监控的回调。2.watchEffect的套路是:不需要指明要监控哪个属性,监控的回调中使用了哪个属性,那么就可以监控哪个属性。3.watchEffect有点像computed:但是computed注重的是计算值(回调函数的返回值),所以需要写返回值。WatchEffect更注重过程(回调函数的函数体),所以不需要写返回值。总和:{{sum}}点+1当前信息:{{msg}}修改姓名:{{person.name}}年龄:{{person.age}}薪资:{{person.job.j1.salary}}K修改名称成长年龄涨薪从“vue”导入{ref,reactive,watch,watchEffect}导出默认值{名称:'演示',setup(){//数据让sum = ref(0)Let msg = ref ('Hello ')让人=被动({姓名:'张三',年龄:18,工作:{j1:{工资:20英镑}}})//监控/* watch(sum,(newValue,oldValue)=>{console . log(' sum的值已更改',newValue,oldValue)},{immediate:true}) */watchEffect(()=>{常数x1 = sum.valueconst x2 = person.job.j1.salaryConsole.log(“执行了watcheffect指定的回调”)})//返回一个对象(常用)返回{总和,味精,人}}}8.生存期生命周期图1.在Vue3.0中可以继续使用Vue2.x中的生命周期钩子,但是其中两个已经被重命名了:BeforeDestroy被重命名为beforeUnmount。已销毁被重命名为已卸载。2.Vue3.0还以Composition API的形式提供了生命周期钩子,与Vue2.x中钩子的对应关系如下:beforeCreate === >设置()已创建======= >安装程序()beforeMount ===> onBeforeMount已安装======= >已安装beforeUpdate ===> onBeforeUpdate更新======= >未更新before unmount = = > onBeforeUnmount未安装===== >未安装当前总和为:{{sum}}点+1从“vue”导入{ref,onBeforeMount,onMounted,onBeforeUpdate,onUpdated,onBeforeUnmount,onUnmounted}导出默认值{名称:'演示',setup(){console.log(' - setup -')//数据让sum = ref(0)//使用复合API形式的生命周期挂钩onBeforeMount(()=>{console.log(' - onBeforeMount -')})onMounted(()=>{console.log(' - onMounted -')})onBeforeUpdate(()=>{console.log(' - onBeforeUpdate -')})未更新(()=>{console.log(' - onUpdated -')})onBeforeUnmount(()=>{console.log(' - onBeforeUnmount -')})未安装(()=>{console.log(' - onUnmounted -')})//返回一个对象(常用)返回{sum}},//以配置项的形式使用生命周期挂钩//#区域创建之前(){console.log(' - beforeCreate -')},已创建(){console.log(' - created -')},beforeMount() {console.log(' - beforeMount -')},已安装(){console.log(' - mounted -')},更新之前(){console.log(' -更新前-')},已更新(){console.log(' -已更新-')},卸载之前(){console.log(' - beforeUnmount -')},卸载(){console.log(' -已卸载-')},//#结束区域}9.自定义挂钩功能1.钩子是什么?-本质是一个函数,封装了setup函数中使用的Composition API。2.类似于vue2.x中的mixin3.自定义钩子的优点:复用代码,使设置中的逻辑更加清晰易懂。4.演示. vue当前总和为:{{sum}}点+1在当前点击时,鼠标的坐标是:x: {{point.x}},y: {{point.y}}从“vue”导入{ref}从'导入使用点'../hooks/usePoint导出默认值{名称:'演示',setup(){//数据让sum = ref(0)设point = usePoint()//返回一个对象(常用)返回{sum,point}}}5、hooks/usePoint.js从“vue”导入{reactive,onMounted,onBeforeUnmount}导出默认函数(){//鼠标“打点”的相关数据let point = reactive({x:0,y:0})//与鼠标“打点”相关的方法函数保存点(事件){point . x = event . paxxpoint.y =事件.页面console.log(event.pageX,event.pageY)}//实现鼠标“打点”相关的生命周期钩子onMounted(()=>{window.addEventListener('click ',保存点)})onBeforeUnmount(()=>{window . removeeventlistener(' click ',保存点)})返回点}10.托雷夫1.角色:创建一个ref对象,其值指向另一个对象中的一个属性。2.语法:const name = toRef(person,' name ')3.应用:当响应对象中的一个属性只供外部使用时。4.扩展:torefs的功能和toRef一样,但是可以批量创建多个Ref对象。语法:toRefs(person){{person}}姓名:{ {姓名}}年龄:{ {年龄}}薪资:{{job.j1.salary}}K修改名字~年龄增长~升上人生巅峰。从“vue”导入{ref,reactive,toRef,toRef }导出默认值{名称:'演示',setup(){//数据让人=被动({姓名:'张三',年龄:18,工作:{j1:{工资:20英镑}}})// const name1 = person.name// console.log('*** ',name1)// const name2 = toRef(person,' name ')// console.log(' ... '),名称2)const x = toRefs(人)console.log('***** ',x)//返回一个对象(常用)返回{人,// name:toRef(person,' name '),// age:toRef(person,' age '),//薪金:toRef(person.job.j1,'薪金'),...斗牛士(人)}}}三。其他成分API1.浅层无功和浅层参考1.shallowReactive:只处理对象最外层属性的响应(浅层响应)。2.shallowRef:只处理基本数据类型的响应,不处理对象的响应。3.什么时候用?如果有一个对象数据,结构是深的,但当它发生变化时,只是外层属性的变化= = ===> shallowReactive。如果有一个对象数据,后续函数不会修改对象中的属性,而是创建一个新的对象来替换===> shallowRef。的当前x.y值为:{{x.y}}单击我替换x点我x.y++{{person}}姓名:{ {姓名}}年龄:{ {年龄}}薪资:{{job.j1.salary}}K修改名称成长年龄涨薪从“vue”导入{ref,reactive,toRef,toRef,shallowReactive,shallowRef}导出默认值{名称:'演示',setup(){//数据//let person = shallow reactive({//只考虑第一层数据的响应。让人=被动({姓名:'张三',年龄:18,工作:{j1:{工资:20英镑}}})设x = shallowRef({y:0})console.log('***** ',x)//返回一个对象(常用)返回{x,人,...斗牛士(人)}}}2.只读和浅只读1.readonly:将响应数据设为只读(深度只读)。2.shallowReadonly:将响应数据设为只读(浅只读)。3.应用场景:不希望数据被修改的时候。当前总和为-:{{sum}}点我++吧姓名:{ {姓名}}年龄:{ {年龄}}薪资:{{job.j1.salary}}K修改名称成长年龄涨薪从“vue”导入{ref,reactive,toRefs,readonly,shallowReadonly}导出默认值{名称:'演示',setup(){//数据让sum = ref(0)让人=被动({姓名:'张三',年龄:18,工作:{j1:{工资:20英镑}}})person = readonly(person)//person = shallow readonly(person)// sum = readonly(总和)// sum = shallowReadonly(sum)//返回一个对象(常用)返回{总和,...斗牛士(人)}}}3.托拉和马克劳1、托拉:功能:将reactive生成的一个响应对象变成一个正常对象。使用场景:用于读取响应对象对应的普通对象。对这个普通对象的所有操作都不会导致页面更新。2、markRaw:角色:标记一个对象,使其永远不再是响应对象。应用场景:有些值不应该设置为响应式,比如复杂的第三方类库。当呈现具有不可变数据源的大型列表时,跳过响应转换可以提高性能。当前总和为:{{sum}}点我++吧姓名:{ {姓名}}年龄:{ {年龄}}薪资:{{job.j1.salary}}K汽车信息:{{person.car}}修改名称成长年龄涨薪输出原人物。给人加个车。更改汽车的名称改变价格从“vue”导入{ref,reactive,toRefs,toRaw,markRaw}导出默认值{名称:'演示',setup(){//数据让sum = ref(0)让人=被动({姓名:'张三',年龄:18,工作:{j1:{工资:20英镑}}})函数showRawPerson(){const p = toRaw(人)p.age++控制台. log(p)}函数addCar(){汽车= {名称:'奔驰',价格:40}person.car = markRaw(汽车)}函数changePrice(){person.car.price++console.log(person.car.price)}//返回一个对象(常用)返回{总和,人,...toRefs(人),showRawPerson,addCar,改变价格}}}4.customRef1.功能:创建自定义ref,并显式控制其依赖跟踪和更新触发器。2.达到防抖效果:

{{ keyWord }}从“vue”导入{ref,customRef}导出默认值{名称:“应用程序”,setup() {//自定义一个名为:myRef的ref函数myRef(值,延迟){让计时器return customRef((track,trigger)=>{返回{get(){Console.log(`有人从这个容器myRef中读取了数据,我给了他${value} `)Track() //通知Vue跟踪值的变化(提前和get商量,让他觉得这个值有用)返回值},set(newValue){Console.log(`有人将容器myRef中的数据更改为:$ {newvalue } `)清除超时(定时器)timer = setTimeout(()=>{值=新值Trigger() //通知Vue重新解析模板。},延迟)},}})}// let keyWord = ref('hello') //使用Vue提供的refLet keyword = myref ('hello ',500)//使用程序员定义的ref返回{keyWord}}}5.提供和注射流程图1.功能:实现祖先和后代组件之间的通信。2.例程:父组件有一个提供选项来提供数据,子组件有一个注入选项来开始使用数据。3.具体写法:祖先组件:setup(){......Car = reactive ({name:'奔驰',价格:' 40万' })提供(“汽车”,汽车)......}在后代组件中:设置(道具、上下文){......const car = inject(“汽车”)返回{汽车}......}6.响应数据的判断Is:检查一个值是否是ref对象。IsReactive:检查对象是否是由Reactive创建的响应代理。Readonly:检查对象是否是由readonly创建的只读代理。IsProxy:检查对象是否是由reactive或readonly方法创建的代理。setup(){汽车=无功({名称:'奔驰',价格:' 40W'})让sum = ref(0)让car2 = readonly(汽车)console.log(isRef(sum))console.log(isReactive(car))console.log(isReadonly(car2))console.log(isProxy(car))console.log(isProxy(sum))

返回{...toRefs(汽车)}}四。新组件1.碎片1.在Vue2中:组件必须有一个根标签。2.在Vue3中:组件可以没有根标签,一个片段虚拟元素中会包含多个标签。3.好处:减少标签级别和内存占用。2.传送什么是瞬间移动?-Teleport是一种可以将我们组件的html结构移动到指定位置的技术。我是一个弹出窗口。关闭弹出窗口3.焦虑1.在等待异步组件的同时呈现一些额外的内容,让应用程序有更好的用户体验。2.使用步骤:异步引入组件从“vue”导入{defineAsyncComponent}const Child = defineeasynccomponent(()= > import('。/components/Child.vue '))用暂记包装组件,并配置默认和回退。

我是一个应用组件装货.....动词 (verb的缩写)其他人1.全球API转移1.Vue 2.x有很多全局API和配置。例如,注册全局组件、注册全局指令等。//注册全局组件Vue.component('MyButton ',{数据:()=> ({计数:0}),模板:“点击了{{ count }}次。”})//注册全局指令Vue.directive('focus ',{inserted: el => el.focus()}2.这些API在Vue3.0中进行了调整:将全局API,即Vue.xxx,调整到应用实例(app)。2.x全局API (vue) 3.x实例API (app)vue . config . xxxx app . config . xxxxvue . config . production已删除提示组件应用程序指令vue . misinapp . mixinvue . use app . usevue . prototypeapp . config . global properties2.其他变化1.数据选项应该始终声明为函数。过多的类名更改:。回车,。v-离开到{不透明度:0;}。v-离开,。v-enter-to {不透明度:1;}Vue3.x写作。v-enter-from,。v-离开到{不透明度:0;}。v-离开-离开,。v-enter-to {不透明度:1;}3.去掉keyCode作为v-on的修饰符,同时不再支持config.keyCodes。4.删除v-on.native修饰符父组件中的绑定事件在子组件中声明自定义事件。导出默认值{发出:['close']}5.拆下过滤器。Filter虽然这个看起来很方便,但是需要一个自定义的语法来打破花括号里的表达式“只是JavaScript”的假设,这不仅有学习成本,还有实现成本!建议用方法调用或计算属性替换筛选器。</p>