什么是MVVM: MVVM 是 Model-View-ViewModel 的缩写。
Model代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑。
View 代表UI 组件,它负责将数据模型转化成UI 展现出来。
ViewModel 监听模型数据的改变和控制视图行为、处理用户交互,简单理解就是一个同步View 和 Model的对象,连接Model和View。
数据会绑定到viewModel层并自动将数据渲染到页面中,视图变化的时候会通知viewModel层更新数据
在MVVM架构下,View 和 Model 之间并没有直接的联系,而是通过ViewModel进行交互,Model 和 ViewModel 之间的交互是双向的, 因此View 数据的变化会同步到Model中,而Model 数据的变化也会立即反应到View 上。
ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起来,而View 和 Model 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理。 核心:数据驱动、组件化思想 单页面优缺点: 优点:Vue 的目标是通过尽可能简单地 API 实现响应的数据绑定和组合的视图组件,核心是一个响应的数据绑定系统。MVVM、数据驱动、组件化、轻量、简洁、高效、快速、模块友好。
缺点:不支持低版本的浏览器,最低只支持到IE9;不利于SEO的优化(如果要支持SEO,建议通过服务端来进行渲染组件);第一次加载首页耗时相对长一些;不可以使用浏览器的导航按钮需要自行实现前进、后退。
模板语法: 1.文本:Message:{{msg}} 2.原始HTML 3.Attribute:
4.JavaScript:{{ message.split('').reverse().join('') }} class与style绑定: 1.2.3.<div v-bind:style="{color:activeColor, fontSize:fontSize+'px'}> 4.
v-if:
v-show:
v-if vs v-show: v-if会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁、重建。且是惰性的,如果初始渲染条件为假,则什么也不做,直到条件第一次变真。 v-show:无论条件为什么,元素都会被渲染,只是简单地基于css变化。 v-if与v-for一同使用时,v-for有更高优先级。v-if会被应用于每个v-for循环中。
计算属性 var vm=new Vue({ el: '#example', data: { message: 'Hello' }, computed: { // 计算属性的 getter reversedMessage: function () { // this 指向 vm 实例 return this.message.split('').reverse().join('') } } })
侦听器: var vm=new Vue({ el: '#demo', data: { firstName: 'Foo', lastName: 'Bar', fullName: 'Foo Bar' }, watch: { firstName: function (val) { this.fullName=val + ' ' + this.lastName }, lastName: function (val) { this.fullName=this.firstName + ' ' + val } } })
例子:
就地更新策略:如果数据项的顺序改变,Vue将不会移动DOM元素来匹配数据项的顺序,而是就地更新每个元素。并且确保它们在每个索引位置正确渲染。 key:使用 key 来给每个节点做一个唯一标识,Diff 算法就可以正确地识别此节点,找到正确的位置区插入新的节点 所以一句话,key 的作用主要是为了高效的更新虚拟 DOM
内联处理器:Say hi 需要在内联语句处理器中访问原始事件的DOM事件,可以使用特殊变量$event Submit methods: { warn: function (message, event) { // 现在我们可以访问原生事件对象 if (event) { event.preventDefault() } alert(message) } } 事件修饰符:
...
修饰符:
插槽 具名插槽:
A paragraph for the main content.
And another one.
动态组件保持状态:keep-alive
异步组件:。Vue 只有在这个组件需要被渲染的时候才会触发该工厂函数,且会把结果缓存起来供未来重渲染。 new Vue({ // ... components: { 'my-component': ()=> import('./my-async-component') } })
方法调用: 1)父组件调用子组件方法
子组件
2)子组件调用父组件: 父组件:
子组件:
通信: 1)父传子 父组件:prop单向数据流,父级prop的更新会向下流动到子组件中,反过来不行。这样会防止从子组件意外变更父级组件的状态。
子组件:
2)子传父 父组件:
自定义组件的v-model:一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件,但是像单选框、复选框等类型的输入控件可能会将 value attribute 用于不同的目的。model 选项可以用来避免这样的冲突 Vue.component('base-checkbox', { model: { prop: 'checked', event: 'change' }, props: { checked: Boolean }, template: <input type="checkbox" v-bind:checked="checked" v-on:change="$emit('change', $event.target.checked)" > }) 将原生事件绑定至组件: 1. 2.$listener 3. .sync
生命周期:beforeCreate, created, beforeMount, mounted, beforeUpdate, updated, beforeDestroy, destroyed 父子组件生命周期: 1.父组件:beforeCreate->created->beforeMount 2.子组件:->beforeCreate->created->beforeMount->mounted 3.父组件: ->mounted->beforeDestroy 4.子组件:->beforeDestroy->Destroyed 5.父组件:->Destroyed 过渡、动画: 当插入或删除包含在 transition 组件中的元素时,Vue 将会做以下处理: 自动嗅探目标元素是否应用了 CSS 过渡或动画,如果是,在恰当的时机添加/删除 CSS 类名。 如果过渡组件提供了 JavaScript 钩子函数,这些钩子函数将在恰当的时机被调用。 如果没有找到 JavaScript 钩子并且也没有检测到 CSS 过渡/动画,DOM 操作 (插入/删除) 在下一帧中立即执行。(注意:此指浏览器逐帧动画机制,和 Vue 的 nextTick 概念不同)
混入:混入 (mixin) 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。一个混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项。
Vue.directive('focus', { inserted: function(el){ el.focus() } }) 钩子函数: bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。 inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。 update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。 componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。 unbind:只调用一次,指令与元素解绑时调用。
Vue.directive('demo', { bind: function (el, binding, vnode) { var s=JSON.stringify el.innerHTML='name: ' + s(binding.name) + '
' + 'value: ' + s(binding.value) + '
' + 'expression: ' + s(binding.expression) + '
' + 'argument: ' + s(binding.arg) + '
' + 'modifiers: ' + s(binding.modifiers) + '
' + 'vnode keys: ' + Object.keys(vnode).join(', ') } })
new Vue({ el: '#hook-arguments-example', data: { message: 'hello!' } }) 过滤器 {{ message | capitalize }}
filters: { capitalize: function (value) { if (!value) return '' value=value.toString() return value.charAt(0).toUpperCase() + value.slice(1) } }
Vue.filter('capitalize', function (value) { if (!value) return '' value=value.toString() return value.charAt(0).toUpperCase() + value.slice(1) })
new Vue({ // ... })
两个核心API:h.js, patch(app, vnode)
vdom:虚拟dom,用JS模拟DOM,因为DOM操作昂贵,将DOM对比操作放在JS层,提高效率 diff:linux的基础命令,vdom中使用时为了更快找出需更新的节点。 实现:patch(container, vnode) patch(vnode, newVnode) 核心逻辑:createElement,updateChildren 解析模板 模板本质是字符串,有逻辑,如v-if,v-for。与html很像,但是有区别,html无逻辑,最终要转换为html来显示 render函数: vm._c其实相当于snaddom中的h函数。render函数执行后,返回vnode。 1)with函数 2)类似vdom的h函数 updateComponent: updateComponent中实现vdom的patch,页面首次渲染执行updateComponent,data中每次修改属性,执行updateComponent。 数据响应式原理: 修改data属性后,vue立刻监听到,data属性被代理到vm上
State: state: { count: 0 },
this.$store.state.count
import { mapState } from 'vuex' ...mapState({})
Getter:就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
getters: { doneTodos: state=> { return state.todos.filter(todo=> todo.done) } }
Mutations: Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。
这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数
mutations: { increment (state) { // 变更状态 state.count++ } }
Actions: Action 类似于 mutation,不同在于: Action 提交的是 mutation,而不是直接变更状态。 Action 可以包含任意异步操作。 actions: { increment (context) { context.commit('increment') } } Modules: Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割
动态路由匹配 { path: '/user/:id', component: User } this.$route.params 嵌套路由:借助router-view
编程式导航: router.push() router.replace(location,onComplete?,onAbort?)替换掉当前history的记录 router.go(n):在history记录向前或向后几步 命名路由: const router=new VueRouter({ routes: [ { path: '/user/:userId', name: 'user', component: User } ] })
链接到命名路由: User router.push({ name: 'user', params: { userId: 123 }}) 命名视图:
{ path: '/settings', // 你也可以在顶级路由配置命名视图
component: UserSettings, children: [{ path: 'emails', component: UserEmailsSubscriptions },
{ path: 'profile', components: { default: UserProfile, helper: UserProfilePreview } }] } 重定向和别名: 1)
重定向:{ path: '/a', redirect: '/b' } 2)别名:/a 的别名是 /b,意味着,当用户访问 /b 时,URL 会保持为 /b,但是路由匹配则为 /a,就像用户访问 /a 一样。 { path: '/a', component: A, alias: '/b' } 路由组件传参:使用props将组件和路由解耦 1)布尔模式:{ path: '/user/:id', component: User, props: true } 2)对象模式:{ path: '/promotion/from-newsletter', component: Promotion, props: { newsletterPopup: false } } 3)函数模式:{ path: '/search', component: SearchUser, props: (route)=> ({ query: route.query.q }) } 路由模式: 1)默认hash模式(带#),使用url的hash来模拟一个完整的url,于是当url改变时,页面不会重新加载。 2)history模式:优美,利用history.pushState API完成URL跳转,而无需重新加载页面:mode: 'history'
导航守卫:
1)全局前置守卫:
router.beforeEach((to, from, next)=>{})
2)全局解析守卫:
router.beforeResolve
3)全局后置钩子:
router.afterEach((to, from)=>{})
4)路由独享的守卫:beforeEnter: (to, from, next)=>{}
5)组件内的守卫:beforeRouterEnter(to,from,next){}, beforeRouteUpdate(to,from,next){}, beforeRouteLeave(to,from,next){} 路由元信息:=:定义路由的时候可以配置meta字段,通过遍历$route.matched来检查路由记录中的meta字段。 过渡动效: 数据获取: 1)导航完成后获取:先完成导航,然后再接下来的组件生命周期苟子仲获取数据。 2)导航完成之前获取:导航完成前,在路由进入的守卫中获取数据,在数据成功后执行。 滚动行为:只有在history模式才能使用。 scrollBehavior (to, from, savedPosition) { // return 期望滚动到哪个的位置 return { x: 0, y: 0 } } 路由懒加载 const Foo=()=> import('./Foo.vue') const router=new VueRouter({ routes: [ { path: '/foo', component: Foo } ] })
特点:
// 添加响应拦截器 axios.interceptors.response.use(function (response) { // 对响应数据做点什么 return response; }, function (error) { // 对响应错误做点什么 return Promise.reject(error); });
删除拦截器 const myInterceptor=axios.interceptors.request.use(function () {/.../}); axios.interceptors.request.eject(myInterceptor); VUE SSR
Vite
组合式API Teleport 触发组件选项createRenderer 单文件组件组合式API 单文件组件状态驱动的CSS变量
Global API模板指令 组件 渲染函数 生命周期 其它 断开与目标 VM 的连接,地址:'javadebug', transport: '共享内存'
我们说到虚拟化,大多数人会想到VMware,VMware(威睿) 是全球桌面到数据中心虚拟化解决方案的领导厂商。今天就来介绍一下VMware的两大产品Workstation和EXSi,看看从我们的个人电脑到企业的服务器虚拟化是怎么实现的。
VMware Workstation是一款功能强大的桌面虚拟计算机软件,通过VMware Workstation这款软件我们可以在单一的实体电脑桌面上创建出虚拟机。虚拟机是独立运行于主机的,虚拟机的关机退出不会影响到你的主机操作系统,它可以运行自己的操作系统,安装一些应用程序,并可以通过网络来共享虚拟机。这样我们就可以在一台电脑上同时运行不同的操作系统了,方便我们进行学习,测试,开发等等。
Vmware Workstation安装
1.官网下载最新的Vmware Workstation Pro 15.5。这里我们在Windows操作系统下安装。
https://www.vmware.com/products/workstation-pro/workstation-pro-evaluation.html
2.下载完成后双击运行,弹出界面点击“下一步”。
3.我接受许可协议中的条款打勾,点击“下一步”。
4.选择安装位置,根据需求勾选增强型键盘驱动程序,点击“下一步”。
5.根据自身情况选择是否检查更新和加入体验,点击“下一步”。
6.默认创建桌面开始菜单快捷方式,点击“下一步”。
7.准备就绪,点击“安装”。
8.安装过程。
9.安装完成,点击“许可证”。
10.输入许可证密钥AV102-05Y9H-M89MQ-5ZN79-MZHR4。
11.VMware Workstation安装完成。我们就可以创建虚拟机安装不同的操作系统了。
创建虚拟机
1. 打开VMwear Workstation选择创建新的虚拟机。
2. 典型安装默认会将主流的配置应用在虚拟机的操作系统上。自定义安装可以针对性的把一些资源加强,把不需要的资源移除,避免资源的浪费。这里选择自定义安装。
3. 默认下一步。
4. 选择稍后安装操作系统。
5. 这里选择之后要安装的操作系统,比如安装选择linux下的CentOS。
6. 为这台虚拟机起个名称,并指定虚拟机安装位置。
7.根据自己的实际需求来分配处理器。在使用过程中CPU不够的话是可以再增加的。
8. 内存也是要根据实际情况进行分配。
9.网络连接类型的选择,网络连接类型一共有桥接、NAT、仅主机和不联网四种。桥接、NAT能够满足虚拟机连接到外网。
桥接与NAT模式访问互联网过程,如下图所示。
这里选择网络地址转换模式。
10.选择I/O控制器类型,默认推荐。
11. 选择磁盘类型,默认推荐。
12.创建新虚拟机磁盘。
13.选择磁盘大小,后面可以随时增加,建议不要勾选立即分配所有磁盘,否则虚拟机会将20G直接分配给CentOS,会导致宿主机所剩硬盘容量减少。勾选将虚拟磁盘拆分成多个文件,这样可以使虚拟机方便用储存设备拷贝复制。
14.创建磁盘的名称,默认即可。
15. 点击自定义硬件。
选择声卡、打印机等不需要的硬件然后移除。
16. 点击完成后,这样一台虚拟机就创建完成了。接下来就可以安装操作系统了。
安装操作系统
1. 编辑虚拟机设置。
2.选择CD/DVD,再选择使用ISO映像文件,浏览找到下载好的镜像文件后确定。
最后开启虚拟机安装操作系统就行了。安装CentOS参考。
企业服务器如果要虚拟化也是安装VMware Workstation吗?这里要介绍VMware的另一款产品ESXi用于企业服务器虚拟化。VMware服务器虚拟化产品VMware ESXi Server从本质上来说与VMware Workstation相同都是一款虚拟化软件。但是ESXi简化了VMware Workstation与主机之间的操作系统层,直接运行于裸机,其虚拟化管理就更加精简,故ESxi的性能更好,安全性更高。ESXi是用于创建和运行虚拟机及虚拟设备的虚拟化平台。ESXi是虚拟化的基础,在虚拟化实施的第一步就是要安装配置ESXi,然后在ESXi server中创建虚拟机。
Vmware ESXi安装
1. 官网下载最新的Vmware ESXi 6.7。
https://my.vmware.com/web/vmware/details?downloadGroup=ESXI67U3&productId=742&rPId=39684
2. Vmware ESXi其实就可以理解为一个IOS操作系统,所以跟安装Windows操作系统一样,你可以把它刻成光盘或U盘进行安装,服务器也可以通过远程挂载进行安装。启动后出现以下画面,选择第一项进行安装。
3.开始加载ESXi引导盘。
4. 加载系统信息,验证硬件驱动。
5. 进入ESXi欢迎界面,按回车键继续。
6.按F11接受许可协议继续。
7. 系统会自动检查可用的存储设备,然后选择安装的磁盘位置,回车继续。
8. 选择安装过程中的键盘模式,默认美式键盘。
9. 设置root管理员密码。
10.按F11开始安装。
11.VMware ESXi 6.7安装中。
12. 等待安装完成后,按回车重启。
重启以后,服务器就已经安装了ESXi系统,ESXi是全文本的界面,我们平时基本很少需要在这台服务器上进行操作,相关的操作都可以通过浏览器或客户端远程访问进行,所以我们需要先对ESXi服务器的网络进行一些配置。
1. 重启完成后系统界面如下,按F2 进入系统配置界面。
2.输入root管理员账号密码回车登陆。
3. 选择Configure Management Network进行网络管理配置。
4. 选择配置IPv4。
5.配置IP地址按回车。
6.IP地址配置完成。
这样我们就可以通过浏览器远程登陆访问EXSi服务器了。
1. 打开浏览器输入EXSi服务器IP,输入用户名密码。
2.登陆成功后,先分配许可证。
3.分配许可证。
4.创建虚拟机。
5.选择创建新虚拟机。
6. 选择名称和客户机操作系统。比如安装选择linux下的CentOS。
7.选择存储。
8.自定义设置。根据实际情况进行CPU、内存、硬盘分配。
9.一台虚拟机创建完成。
10.最后和VMware Workstation挂载安装操作系统就可以了。
本文安装虚拟机主要用于新手初次接触情况下安装,本虚拟机主要用于系统安装以及中间键的安装以及使用,对于学习系统实施和系统运维过程有很大帮助。
下载地址:https://www.vmware.com/cn/products/workstation-pro.html
下载安装后如图:(我自己下的是workstation 16 pro,根据自己需要下载)
2.安装完成后点击创建新的虚拟机
选择自定义高级后点击下一步(好像两者并没有区别,都试过)
直接下一步:
点稍后安装光盘映像前提是我们光盘影响还没有提前下载好:
点击下一步后选择liunx(L)
虚拟机名称以及安装目录自己可以改成想要的:
虚拟机核数这里一般选择默认值1:
虚拟机内存选择8g,够用(选择16g的话到后期可能会因为虚拟机内存问题导致虚拟机打不开)
选择NAT网络连接与主机共享网络(但后面打开虚拟机时候会遇到网络连接不上则可以在命令行处输入:sudo dhclient ens33 (用连接网络命令))
下一步:
选择磁盘内存,一般20G就够我们平常模拟安装用:
点击完成后,随后进行下一步光盘映像下载:
下载地址:http://ftp.sjtu.edu.cn/centos/7/isos/x86_64/
记住自己下载路径:
路劲放到虚拟机里选用就好,然后点击确定后开始启动:
启动遇到问题(因为自己装的比较多,内存不够降到4g,一般第一次装8g是可以启动的)
到此正在安装会比较慢。过程可能会重启
记得配置里面勾选图形化,否则会是命令行界面
随后有提示用户名密码
最后出来即安装成功
?
*请认真填写需求信息,我们会在24小时内与您取得联系。