Vue2JS + Vue3JS 入门学习

学习目标:

  • 一周掌握 Vue2js + Vue3js

学习内容:

Object.defineProperty

参数:(对象名,key, 配置项)

两种给对象添加属性的方式

直接添加

在这里插入图片描述

结论: 三个属性都可以遍历

借助 defineProperty

Object.defineProperty(person,'age',{
    value:18
})

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PNlz8pxt-1653806579426)(imgs/image-20220121152844436.png)]

结果: age 颜色较浅。说明 age 属性不会参与遍历

Object.defineProperty(person,'age',{
    value:18,
    enumerable:true // 控制属性是否可以枚举。默认为false
})

虽然age可以遍历了。但是age属性不能修改值。需要再添加一个配置项:writable:true 控制属性是否可以修改。configurable:true 控制属性是否可以被删除

get 和 set方法

1、get方法

介绍:当有人读取 person 的 age 属性时,会触发调用get函数,其返回值就是访问到的 age 属性值

Object.defineProperty(person,'age',{
   get:function(){
       return 12
   }
})

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0RB1yuGX-1653806579427)(imgs/image-20220121154129394.png)]

2、set方法

介绍:当修改person的age属性值,set函数就会被调用,且接收到要新修改的值

			let number = 12
			
			var person = {
				name:'ss'
			}
			
			Object.defineProperty(person,'age',{
				get(){
					return number
				},
				set(newVal){
					number = newVal
				}
			})

通过 Object.defineProperty的set和get方法 将 person的age属性和number变量做了双向关联

数据代理

概念

数据代理:通过一个对象代理对另一个对象的读写操作

举例

let obj_a = {x:100}
let obj_b = {y:200}

// obj_a 对象代理对 obj_b 对象的操作
Object.defineProperty(obj_a,'y',{
    get(){
        return obj_b.y
    },
    set(newVal){
        obj_b.y = newVal
    }
})

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XZIeHvPr-1653806579427)(imgs/image-20220121155839217.png)]

Vue 中的数据代理模式:

视频地址:尚硅谷Vue2.0+Vue3.0全套教程丨vuejs从入门到精通_哔哩哔哩_bilibili

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ri4i64lo-1653806579427)(imgs/image-20220121160227854.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8KdDc8R2-1653806579428)(imgs/image-20220121161158563.png)]

Vue2 数据单向绑定原理

简易模仿vue监测数据

function Observer(obj) {
   	const keys = Object.keys(obj)
    keys.forEach((k)=>{
        Object.definePropety(this,k,{
            get() {
                return obj[k]
            },
            set(newVal) {
                // k 被改了,下一步解析模板,生成虚拟dom 
                obj[k] = newVal
            }
        })
    })
}
let data = {
    name:'',
    address:''
}
const obs = new Observer(data);

let vm = {}

vm._data = data = obs

Vue.set()方法

作用:后添加的属性,也能有响应式功能

注意:set() 方法仅可以向 data :{} 中的某一个子对象追加属性,而不能直接向 data 追加属性

// 方式一: 向data的子对象student添加sex属性并赋值
Vue.set(this.student,sex,'man')

// 方式二
this.$set(this.student,sex,'man')

监测数组变化

默认 vue 是不会给 数组元素 添加 get和set方法的,所以是不会检测到元素的 改变

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IlEpjZem-1653806579428)(imgs/image-20220121170525717.png)]

Vue监听总结

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tgXTKFbC-1653806579429)(imgs/image-20220121171641707.png)]

vue2-lifeCircle

挂载

在这里插入图片描述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jwUqVtfs-1653806579431)(imgs/image-20220121174732129.png)]

更新

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lDzU4ZOG-1653806579432)(imgs/image-20220121175437120.png)]

销毁

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wHZMDTVs-1653806579433)(imgs/image-20220121182543762.png)]

总结

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PvU7k6I1-1653806579434)(imgs/image-20220121183426492.png)]

原型和原型链

原型

每个函数function都有一个prototype,即显示原型属性

每个实例对象都有一个__proto__,即隐式原型属性

对象实例的隐式原型的值 == 对应构造函数的显示原型的值

函数的prototype属性:在定义函数时自动添加的。默认值是一个空Object对象

对象的__proto__属性:创建对象时自动添加的。默认值为构造函数的prototype属性值 其是显示原型的引用

B站视频尚硅谷JavaScript高级教程(javascript实战进阶)_哔哩哔哩_bilibili

可以直接操作 显示原型,但不能直接操作 隐式原型【es6之前】

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WYZCgB3u-1653806579434)(imgs/image-20220121194652513.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IW6AfNLC-1653806579435)(imgs/image-20220121200510569.png)]

原型链 / 隐式原型链

访问一个对象的属性/方法流程优先级:

  • 先在 自身属性 中查找
  • 再沿着 隐式原型链 查找
  • 返回undefined

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fwiSBmR4-1653806579435)(imgs/image-20220121200157430.png)]

Vue.prototype

一个重要的内置关系:VueComponent.prototype._proto__ === Vue.prototype

const component1 = Vue.extend({})

new Vue({
    
})

console.log(component1.prototype._proto__ === Vue.prototype)// true

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Lv7WzvLp-1653806579436)(imgs/image-20220121204515191.png)]

为什么要有这个关系?: 目的是让组件实例对象vc可以访问到Vue原型上的属性、方法。

mixin 混入整合

minxin.js

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-j8hMLSrL-1653806579436)(imgs/image-20220121205215537.png
)]

局部混合 mixins:['xxx']

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JyhJNLRQ-1653806579437)(imgs/image-20220121205152338.png)]

全局混合 Vue.mixin(xxx)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8GGxJJ62-1653806579437)(imgs/image-20220121205301480.png)]

插件

插件本质是一个对象,需要有 install 方法

功能:用于增强 Vue

编写插件

plugin.js

export default {
    install(Vue){
        ...
    }
}

引入插件 Vue.use()

main.js

import xx from xxx
Vue.use(xx)

常见应用:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JOljMJqK-1653806579437)(imgs/image-20220121210106885.png)]

前端存储方案

cookie

在Http请求发送 set-cookie HTTP头作为响应头一部分

cookie构成:通过 name=value 形式存储

失效时间:默认浏览器关闭失效(可自定义失效时间)

安全标志:设置安全标志后,只有是SSL连接才会发送到服务器

作用:主用于保存登录信息

存储大小:4KB否则被截掉 每个站点个数一般不超过20个

http通信:每次与服务端交互,都会携带在HTTP头。所以如果cookie臃肿会出现性能问题

sessionStorage

1)sessionStorage是Storage类型的一个对象,拥有clear(),getItem(name),key(index),removeItem(name),setItem(name,value)方法
2)sessionStorage对象存储特定于某个会话的数据,也就是该数据只保持到浏览器关闭
3)将数据保存在session对象中。所谓session,是指用户在浏览某个网站时,从进入网站到浏览器关闭所经过的这段时间,也就是用户浏览这个网站所花费的时间。session对象可以用来保存在这段时间内所要求保存的任何数据
4)sessionStorage为临时保存

localStorage

1)localStorage也是Storage类型的一个对象
2)在HTML5中localStorage作为持久保存在客户端数据的方案取代了globalStorage(globalStorage必须指定域名)
3)localStorage会永久存储会话数据,除非removeItem,否则会话数据一直存在
4)将数据保存在客户端本地的硬件设备(通常指硬盘,也可以是其他硬件设备)中,即使浏览器被关闭了,该数据仍然存在,下次打开浏览器访问网站时仍然可以继续使用
5)localStorage为永久保存

  1. 存储空间

    cookie 为4KB;LocalStrage和SessionStorage为5MB

  2. 相关API

    仅支持存储字符串类型数据 【复杂类型需要使用JSON对象的Stringfy和parse进行转化处理】

    在这里插入图片描述

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-d0JPuTOJ-1653806579438)(imgs/image-20220308094009151.png)]

  3. 作用域不同:

    不同浏览器:无法共享localStorage和sessionStorage信息

    相同浏览器-不同页面:仅可共享 localStorage [页面属于相同域名和端口]

  4. 安全性问题:

    webStorage 不会随着 Http Header 发送到服务端,不会担心截获/伪造问题,所以安全性相对于cookie高一些

localStorage

特点:浏览器关闭后,仍不消失

在这里插入图片描述

SessionStorage

特点:关闭浏览器后,自动清除

操作API和LocalStorage相同

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f4Lon9PU-1653806579440)(imgs/image-20220121215102044.png)]

cookie session token

cookie、session、token的区别 - www.pu - 博客园 (cnblogs.com)

全局事件总线

应用于:任意组件通信

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gUtxbDMB-1653806579440)(imgs/image-20220121222736997.png)]

在这里插入图片描述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rEjnjnmZ-1653806579443)(imgs/image-20220121223328444.png)]

消息订阅与发布

消息订阅发布机制:可以运用在任意组件之间,忽略组件层级关系,只关心:消息发布&消息订阅

作用:方便组件之间传值和事件处理

  1. 下载: npm install pubsub-js --save
  2. 使用:
    • import PubSub from 'pubsub-js' //引入第三方库
    • this.pubId = PubSub.subscribe('delete', function(msgName,data){ }); //订阅
    • PubSub.publish('delete', data) //发布消息
  3. 要在beforeDestroy中取消订阅 PubSub.unsubscribe(this.pubId)

跨域问题

跨域

浏览器端 存在 同源策略(协议、域名、端口号必须完全一致)

特点:跨域仅存在于 浏览器端

代理服务器:使用webpack配置代理服务器

原理:本身服务就跑在一个开发服务器 webpack-dev-server, 这个server附带有一个 http-proxy-middleware, 该中间件支持我们将 浏览器请求 转换为 服务器向服务器的请求

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TdUHkQVO-1653806579445)(imgs/image-20220308102003468.png)]

方式一:

module.exports = {
    devServer:{
        proxy:"http://localhost:5000"
    }
}
  • 配置简单,请求资源时直接发给前端 8080 即可
  • 不能配置多个代理,不能灵活控制请求是否走代理
  • 当请求了前端不存在的资源,请求会转发给服务器,即优先匹配前端资源

方式二:

module.exports = {
    devServer: {
        proxy:{
            '/api':{
                target:"http://localhost:5000",
                pathRewrite:{'^/api';''},
                changeOrigin:true
                /*
                ​	changeOrigin 设置为true,服务器收到请求头的host为 localhost:5000

​	changeOrigin 设置为false,host为localhost:8080

​	changeOrigin 默认为 true
                */
            },
            '/api2':{
                target:"http://localhost:6000",
                pathRewrite:{'^/api2';''}
            }
        }
    }
}
  • 可以配置多个代理,且可以灵活控制请求是否走代理
  • 配置繁琐,请求资源时必须添加前缀

反向代理:使用 nginx 开启一个代理服务器

原理:页面请求发送给nginx服务器,nginx根据配置路径动态匹配将要请求的服务器地址,最终的请求由nginx服务器发出解决跨域

尚硅谷Nginx教程由浅入深(一套打通丨初学者也可掌握)_哔哩哔哩_bilibili

  • 反向代理
  • 负载均衡
  • 动静分离
  • 高可用配置

跨域资源共享:服务端开启跨域资源共享,通过设置一个响应头告诉浏览器该请求允许跨域

路由工作方式

hash

hash值不会包含到http请求中,即hash不会带给服务器

  • 地址中你永远带着 # 不美观,所以项目上线推荐使用 history模式
  • 有些app分享地址校验严格,会标记不合法

history

const router = new VueRouter({
    mode: 'history',
    routes:[{},{}]
})

Vue3

介绍

时间:2020 9 发布

性能:

源码升级:

  • 使用 Proxy 代替 defineProperty 实现 响应式
  • 重写 Virual-DomTree-Shaking

更好支持 TypeScript

新特性

  1. composition API(组合API)
  2. 新的内置组件
    • Fragment
    • Teleport
    • Suspense
  3. 其他改变
    • 新的生命周期钩子
    • data 始终被声明为一个函数
    • 移除 keyCode ,支持作为 v-on 的修饰符

两种创建工程方式

vue-cli

需要检查 vue-cli 版本在 4.5.0 以上

# 查看版本
vue --Version
# 安装升级
npm install -g @vue/cli

# 创建工程
vue create xx

现阶段 vue脚手架 创建的工程,是仍然采用 webpack 做构建工具。

  1. 创建工程时可以选择使用 vue2 还是 vue3

  2. 创建工程时可以选择 TypeScript,之后项目中可以使用 TypeScript开发

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uAZawscS-1653806579446)(imgs/image-20220122123715859.png)]

Vite

由于西 团队打造

  1. 新一代的前端构建工具。之前是 webpack

  2. vite 特点优势

    • 开发环境中,无需打包操作,可以快速 冷启动【即执行 npm run serve , 后先启动,后按需编译】

    • 比 webpack 更快速实现 热重载 【即一改代码,马上跟新

    • 真正的按需编译,不再等待整个应用编译完成

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A0JbD6yG-1653806579446)(imgs/image-20220122115344644.png)]

  3. 可以使用 vite 直接创建工程。当然也会采用 vite做为构建工具

    # 创建工程
    npm init vite-app <project-name>
    # 安装依赖[即生成 node-modules 文件夹]
    npm install
    # 运行
    npm run dev
    
  4. 创建的工程结构和 vue-cli 一样。区别在于没有采用 webpack 作为构建工具。

Hubilderx

HubilderX 现在只提供 vite 项目模板

工程结构变化

这里采用的是 vue3 + webpack + js

main.js

工厂函数直接调用即可创建对象,无需new创建对象

app比vue2中的vm更“轻”【即没有那么多属性、方法】

// 引入的不是 Vue构造函数;而是一个工厂函数
// 工厂函数特点是直接调用即可创建对象,无需new创建对象
import {createApp} from 'vue' // 引入 createApp 工厂函数
import App from './App.vue'

/* vue2写法
    new Vue({
        render:h=>h(App)
    }).$mount('#app')
*/

// 创建应用实例对象app.app比vue2中的vm更“轻”【即没有那么多属性、方法】
const app = createApp(App)
app.mount('#app')// 挂载

App.vue [可以没有根元素]

  1. vue 3 中的 template 可以没有根级元素
  2. 其他部分无变化
<template>
	<img/>
	<HelloWorld/>
</template>
...
...

Fragment 组件

vue2中,组件必须有一个根标签

vue3中,组件可以没有根标签,内部会将多个标签包含在一个 Fragment 虚拟元素中

Fragment 好处:减少内存占用

setup 函数

  1. 理解:Vue3 中一个新的配置项,是一个函数

  2. 干什么:setup 是所有 compostion API 的表演舞台

  3. 怎么用:组件中用到的数据、方法等,均要配置到setup

    vue3 向下兼容,所以 data、method 目前均仍可使用 【但开发中不建议出现任何vue2的代码】

    export default {
        name:'',
        
        // 新的配置项
        setup(){
            // 1、对象
            let name = 'zzl'
           
            // 2、方法
            function sayHello(){}
            
            // 3、返回【所有需要响应式的数据/方法都需要return出去】
            return {name,sayHello}
        }
    }
    
  4. setup函数有两种返回值

    • 若返回对象,则对象中的属性、方法,在模板中均可直接使用 【常用】
    • 若返回一个函数,则可以自定义渲染内容[了解]
  5. 注意

    • 开发中,不建议 setup 和 data、method混用。即vue3不建议再编写vue2的代码了
      • vue2配置 [data,method,computed…] 中可以访问到setup中的属性和方法
      • 但在 setup 中不能访问到vue2配置 [data,method,computed…]
      • 如果有重名,setup 优先
    • setup 不能是一个 async 函数,因为 async 修饰后函数返回值不再是 return 的对象,而是promise,渲染模板看不到 return 对象中的属性。

ref 函数 == reference引用意思 [基本类型-做响应式]

作用:定义一个响应式数据

1、语法:const name = ref('zzl'):创建一个包含响应式数据的引用对象(reference对象,简称ref对象)

2、js操作数据[需要value]:JS 中操作响应式数据 name.value

3、界面渲染数据[不要value]:从模板中读取数据,不需要value,直接{{name}}

4、接受类型:基本数据类型、对象类型

  • 基本数据类型的数据:响应式是依靠 Object.defineProperty()的 get 和 set 方法完成的 [即同Vue2]
  • 对象类型的数据:内部使用 vue3 提供第一个新函数-reactive函数 [vue3]

reactive 函数 [对象类型-做响应式]

作用:定义一个对象类型的响应式数据(基本类型使用ref函数)

1、语法:const proxy代理对象 = reactive(源对象) 接受一个对象(或数组),返回一个代理对象(Proxy的实例对象,简称proxy对象)

2、操作 和 渲染 数据,都不需要 .value

3、reactive 定义的响应式数据是 ”深层次的“

底层:内部基于 ES6 的 Proxy 实现,通过代理对象proxy,操作元对象内部数据进行操作


toRefs 函数 – 偷个懒,渲染时不想写对象名

1、toRef 函数

我没打算将整个对象交给响应式,我只需要name属性做响应式

作用:创建一个 ref 对象,其 value 值指向另一个对象中的某个属性

语法:const name = toRef(person,'name') // 一个 ref 对象name 指向 person的name属性

应用:将响应式对象中的某个属性单独提供给外部使用, template中可以不用 {{person.name}},换成 {{name}}

2、toRefs 函数

作用:toRefs可以批量将一个 reactive对象 转变为多个 ref对象,语法toRefs(person)

应用:const person_refs = toRefs(person) // 一个对象,内部包含多个 ref对象 属性

3、常见编码形式

<template>
	{{show}}
	{{companys}}
	{{user}}
	{{tmp}}
</template>

<script>
setup() {
 // 统一将本组件用到的 响应式数据集 包在一个data中
    const data = reactive({
      companys:[
        {
          name:'xiaomi',
          id:1
        },
        {
          name:'HuaWei',
          id:2
        }
      ],
      user:{
        id:100,
        name:'zzl',
        age:18
      },
      show:true
    })
// 统一写一个 methods 响应式对象
    const methods = reactive({
        getProducts() {
            
        },
        getUserList() {
            
        }
    })
	
    return {
        ...toRefs(data),
        ...toRefs(methods)
    }
  }
}
</script>

响应式原理

vue2

实现原理:

  • 对象类型:通过 Object.defineProperty()对属性的读取,修改进行拦截(数据劫持)

  • 数组类型:通过重写更新数组的一系列方法来实现拦截,(对数组的变更方法进行了包裹)

存在问题:

  • 直接 新增、删除属性,界面不会更新
  • 直接 通过下标修改数组,界面不会自动更新

上述两个问题,vue2都给了解决方案

vue3

实现原理:

  • 通过 Proxy 代理拦截对象中任意属性的变化,包括:属性值的读写、属性的添加、删除等
  • 通过 Reflect 反射:对源对象的属性进行操作
// proxy 代理
new Proxy(data,{
    // 拦截读取属性
    get(target,prop) {
        return Reflect.get(target,prop)// 读取源对象
    },
    // 拦截设置属性或添加新属性
    set(target,prop,value) {
        return Reflect.set(target,prop,value)// 操作源对象
    },
    // 拦截删除属性
    deleteProperty(target,prop) {
        return Reflect.deleteProperty(target,prop)// 操作源对象
    }
})

reactive 对比 ref

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JEtOHNF4-1653806579447)(imgs/image-20220122170947232.png)]

开发中大量使用 reactive,基本不使用 ref。

开发中会用一个 大对象 将用到的基本数据类型的数据包裹起来,使用 reactive。即对象嵌套

setup注意点 – this指向

1、setup 执行时机:在 beforeCreate 之前执行一次

2、this: setup 中的 this 是 undefined

3、setup 的参数

  • props: 父组件传递来的值
  • context: 上下文对象。 attrs , slots, emit

computed 函数–简写形式

import {computed} from 'vue'

setup() {
    // 简写【单向】
   person.fullName = computed((=>{
         return Person.firstName + '-' + person.lastName
   }))
    
    // 完整【双向】
   person.fullName  = computed({
        get(){
            return Person.firstName + '-' + person.lastName
        },
        set(value) {
            const nameArr = value.split('-')
            Person.firstName = nameArr[0]
            Person.lastName = nameArr[1]
        }
    })
}

Watch 函数- 各种监视情况

import {watch} from 'vue'

setup() {
    let sum = ref(0)
    // 监视 ref 所定义的一个响应式数据 sum
    watch(sum,(newVal,oldVal)=>{
        ...
})

	// 监视多个 ref 所定义的数据 sum msg
	watch([sum,msg],(newVal,oldVal)=>{
        ... sum或msg变化了
    })
        
    // 监视 reactive 定义的数据 person. 这里不能拿到oldvalue
        // 默认强制开启了深度监视(deep配置无效)
     watch(person,(newVal)=>{ })
     
     // 常用----------------------------------------
     // 监视 reactive定义的一个响应式数据中的 某个属性!! 【用的多一点】
     watch(()=>person.name,(newVal,oldVal)=>{})
     // 常用----------------------------------------
        
     // 监视多个属性!!
     watch([()=>person.age,()=>person.name],(newVal,oldVal)=>{ })
        
     // 监视 reactive定义的对象中的 某个对象属性[这里默认不开启深度监视]
     watch(()=>person.job,(newVal)=>{ },{deep:true})
}

let person = ref({
    name:
    age:
})

//方式一 监视 ref 定义的对象的属性变化 [默认强制开启deep]
watch(person.value,(newVal,oldVal)={})

// 方式二:需要手动开启深度监视
watch(person,(newVal,oldVal)=>{},{deep:true})

watchEffect 函数–佛系的watch

watch: 既要指明监视的属性,也要指明监视的回调函数

watchEffect: 仅仅需要指明回调函数回调中用到哪些属性,就监视哪些属性

watchEffect 有点像 computed,都是有点监视数据变化的作用。但

  • computed 注重对是计算出来的值,即必须要写返回值
  • watchEffect 注重的是逻辑处理过程,即不需要返回值
import {watchEffect} from 'vue'

watchEffect(()=>{
    const myname = Person.name // 使用了Person.name
})

vue3-lifecircle

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dEbgzSlF-1653806579447)(imgs/image-20220122201447079.png)]

hook 函数

本质是一个函数,把 setup 函数中使用的 compositionAPI 进行了封装

1、类似于 vue2 中的 mixin

2、目的:复用代码,分离功能代码,提高维护度

甚至,日后大型项目,可以单独独立出一个hooks文件夹,编写各种业务js文件。开发中可以引入共享

setup() {
    // 拿到响应式数据
    const person_data = usePerson() // 需要定义一个变量,接受一下响应式数据
    const company_data = useCompany()
    
    // 返回
    return {
    	person_data,
        company_data
    }
}

// 独立出 person 业务模块 
function usePerson() {
    // 定义
    const person = reactive({
        name:'',
        age:
    })
    // 返回
    return person
}
                            
// 独立出 company 业务模块
function useCompany() {
    // 定义
	const company = reactive(()=>{
        name:'',
        address:''
    })
    // 返回
    return company
}   

compositionAPI 优势

options API -> VUE2

  • 优点:小型项目开发高效
  • 缺点:公司大型项目代码量大,造成维护性差

composition API -> VUE3

  • 即适合小型项目的快速开发,向下兼容VUE2优势
  • 满足大型项目代码量大的需求,维护性提高

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Gfgrhn30-1653806579448)(imgs/image-20220122211849600.png)]

Teleport 组件–类似 模态框 的效果

把某个HTML代码领出来,类似 模态框 的效果

<Teleport to="body">
	
</Teleport>

全局API转移-- app.xxx

  1. vue2 中许多全局API和配置

    // 注册全局组件
    Vue.component()
    
  2. vue3 对这些API做了转移,调整到了 app 实例上

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7Yrcmad8-1653806579448)(imgs/image-20220122223815278.png)

emits 选项

  1. 移除 v-on.native 修饰符,需要在子组件中使用 emits 配置项声明自定义事件名

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-F2R6DyKc-1653806579448)(imgs/image-20220122224558831.png)]

其他

移除掉了 filter 过滤器,建议使用 computedmethod 去实现过滤器

打包部署

方式一:

每次 npm run build 手动将 dist 文件夹传到 server,再配置 nginx

方式二:

使用 github actions 实现 ci/cd 过程

Github Actions:

作用:可以让我们在 giuhub 仓库中 创建 自定义的软件开发生命周期工作流程

【全网首发】Vue3.0光速上手「持续更新中」_哔哩哔哩_bilibili

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xevWn5gG-1653806579449)(imgs/image-20220123151833581.png)]

1、配置 workflow

下面配置,在我们 push 代码后,github会自动打包我们应用进行部署

需要在项目根目录创建层级目录 .github/workflows/publish.yml

name: 任务打包应用上传服务器
on:
	push:
		branches:
			- master
#任务详情
jobs:
	build:
	# 指定自动打包时运行的虚拟机环境
	runs-on: ubuntu-latest
	#步骤
	steps:
		- name: 迁出源码到虚拟机
			uses: actions/checkout@master
		
		- name: 安装node
			uses: actions/setup-node@v1
			with:
				node-version:14.0.0
		- name: 安装依赖
			run: npm run build
		- name: 打包项目
			run: npm run build
		- name: 上传到 server
			uses: easingthemes/ssh-deploy@v2.1.1
			env:
				#私钥[让虚拟机模拟自己机器和server连接]
				SSH_PRIVATE_KEY:
				${{secrets.PRIVATE_KEY}}
				#scp参数
				ARGS:"-avzr --delete"
				#源目录
				SOURCE:"dist"
				#服务器IP
				REMOTE_HOST:""
				#用户
				REMOTE_USER:"root"
				#server目标目录地址
				TARGET:"/root/xxx"

2、去github当前仓库中配置 私钥选项
在这里插入图片描述

**3、**查看发布过程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vPesWp8e-1653806579450)(imgs/image-20220123153442927.png)]

4、在 server 配置 NGINX

  • 进入 nginx 安装目录下

  • 配置 nginx.conf 文件,将配置内容分割出去

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZDpFG2bV-1653806579450)(imgs/image-20220123153801765.png)]

  • 进入分割的配置文件夹 sites-enabled -> 为我们的新网站创建一个配置文件->编写简单的配置内容
server {
    # 项目端口
    listen 8080;
    # 服务器IP
    server_name 47.58.365.36;
    location / {
        # 项目打包后的文件夹
        root /root/vue-in-action/dist/;
        # 默认入口文件
        index index.html index.htm;
    }
}
  • 重启NGINX,生效配置

    # 重启nginx
    nginx -s reload
    

5、浏览器查看网站


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值