1.vue是什么?
vue是一套构建用户界面的渐进式框架,核心库只关注视图层。vue和react相同点: 1.都使用 virtual DOM; 2.提供了响应式(reactive); 3.组件化(composable)的视图组件; 4.都支持native方案; 5.都支持SSR服务端渲染; 6.都支持props进行父子组件通信;不同之处就是: 1.数据绑定方面,vue实现了数据的双向数据绑定,react数据流动是单向的。 2.virtual dom不一样,vue会跟踪每一个组件的依赖关系,不需要重新渲染整个组件树。而react,每当应用的状态 被改变时,全部组件都会重新渲染,所以react需要 shouldComponentUpdate这个生命周期函数来进行控制。 3.state对象在react应用中不可变,需要使用 setState 方法更新状态; vue中,state对象不是必须的,数据由data属性在vue对象中管理; 4.组件写法不一样,react推荐JSX; vue推荐webpack+vue-loader的单文件组件格式;vue.js核心特点-响应的数据绑定vue中实现组件引入流程: 第一步使用 import导入需要引入的组件文件;第二步使用components注册组件;第三步在需要引入组件的文件中加上组件标签。单文件组件: js, css, html存在一个文件中,称为单文件组件。虚拟DOM: 运行的js速度很快,大量操作DOM就会很慢,在更新数据后会重新渲染页面,这样造成在没有改变数据的地方也重新 渲染了DOM节点,就造成了资源浪费。 利用在内存中生成与真实DOM与之对应的数据结构,这个在内存中生成的结构称之为虚拟DOM。 当数据发生变化时,能够计算出重新渲染组件的最小代价并应用到DOM操作上。MVVM: M-model数据模型, V-view视图模板, VM-view-model视图模型 vue的MVVM实例-双向数据绑定。当数据发生改变会自动更新视图,利用Object.defineProperty中的setter/getter 代理数据,监控对数据的操作。声明式渲染与命令式渲染区别: 声明式渲染:只需要声明在哪里,做什么,无需关心如何实现。 命令式渲染:需要具体代码表达在哪里,做什么,如何实践。
1.1. MVVM响应式
2.x的响应式: 1.响应式需要做到在修改数据的时候对dom的自动更改; 2.需要在set里面自动绑定一个dom元素 3.get,set操作是通过 Object.defineProperty() 完成; eg: let data = { msg: 'hello' } // 模拟实例; let vm = {}; // 数据劫持 Object.defineProperty(vm, 'msg', { enumerable: true, //可枚举 configurable: true, //可配置 //获取到值 get(){ return data.msg; }, //当设置值 set(nv){ if(nv ===data.msg){ return } data.msg = nv //数据更改,更新DOM的值 document.querySelector('#app').textContent = data.msg; } }) vm.msg = 'hello world'; console.log(vm.msg);3.x的响应式 1.通过proxy进行对象代理 2.直接监听对象,而非2.x的属性 //模拟data let data = { msg: 'hello', count: 0, } //模拟实例 //Proxy 对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义(eg属性查找,赋值,枚举...) let vm = new Proxy(data, { get(target, key){ return target[key]; }, set(target, key, nv){ if(target[key] === nv){ return } target[key] = nv; document.querySelector('#app').textContent = target[key] } }) //测试 vm.msg = 'hello world'; console.log(vm.msg);发布订阅者模式:即假设存在一个信号中心,某个任务执行完,就向信号中心发布publish一个信号,其他任务可以向信号中心订阅subscribe这个信号,从而知道自己什么时候可以开始执行。eg: let vm = new Vue() vm.$on('dataChange',()=>{ console.log('datachage'); }) vm.$emit('dataChange'); 兄弟组件的通信过程: 使用eventBus.js,及发布订阅者模式。观察者模式:由具体目标调度,比如当事件出发,Dep就会去调用观察者的方法,所以观察者模式的订阅者与发布者之间是存在依赖的。eg: 观察者(订阅者)-- Watcherupdate(): 当事件发生时,具体要做的事情目标(发布者) -- Depsubs 数组: 存储所有的观察者addSub(): 添加观察者notify(): 当事件发生,调用所有观察者的 update()方法没有事件中心。
2.node.js和npm
npm的package.json文件详解参考链接:https://github.com/ericdum/mujiang.info/issues/6/淘宝镜像:npm install -g cnpm --registry=https://registry.npmmirror.com然后就可以使用cnpm命令安装模块了cnpm intall [name]
3.vue安装
使用 npm install vue -g 或者 cnpm install vue -g 安装vue.js使用 npm install webpack -g 安装 webpack 模板安装vue-cli2.x脚手架:使用 npm install vue-cli -g 安装vue-cli2.x脚手架 使用 npm install -g vue-router 创建 vue-cli2创建项目 vue init webpack 项目名安装vue-cli3.x脚手架: 先卸载旧版本2.x: npm uninstall vue-cli -g 卸载3.x版本: npm uninstall @vue/cli -g 安装新版本: npm install @vue/cli -g 指定版本号 npm install @vue/cli@3.12.1 不指定版本号会默认安装最新的版本 新建项目: vue create 项目名 运行项目: npm run serve 项目中新建 vue.config.js 文件,更改端口号1000 module.exports = { //扩展配置 configureWebpack: { devServer:{ port: 10000, open: true, //自动启动浏览器 } } }vue项目结构:1.build:构建脚本目录2.config: 项目配置 dev.env.js =>开发换届变量 index.js =>项目配置文件 prod.env.js =>生产环境变量3.package.json: npm包配置文件,定义了项目的npm脚本,依赖包等信息
4.vue实例
1.EL元素节点2.Data数据3.Methods方法集合4.computed计算属性 注意:如果没有给计算属性显示的返回一个值,默认会返回undefined。 由于计算属性在使用时只是一个常量值,不是一个函数,无法传参。 为什么要使用计算属性?(因为缓存) 只有计算属性引用的响应式属性发生改变时才会重新计算,如果引用的属性没有改变,则调用上一次缓存值。 而methods里的函数在每次调用时都要执行,每次值都是最新的。 5.watch 监听属性 6.生命周期
注意:在created中可以对data数据进行操作,这个时候可以进行ajax请求将返回的数据赋值给data。
在mounted中对挂载的dom进行操作。
在使用vue-router时需要使用
如果需要做其他操作,可以在activated中处理。
7.vue指令
v-model双向绑定数据
v-for循环
v-show显示与隐藏
v-if显示与隐藏(dom元素的删除添加)
v-else
v-else-if
v-bind
v-on事件
v-text读取文本不能读取html标签
v-html读取html标签
v-class类名(三种绑定方法 1.对象型 '{red: isRed}') 2.三目型 'isRed?"red":"blue"' 3.数组型 '[{red: "isRed"},{blue: "isBlue"}]'
v-style样式
v-once进入页面时,只渲染一次,不再进行渲染
v-cloak防闪烁
v-pre把标签内部的元素原位输出
5.v-model
v-model可以实现表单元素和数据的双向绑定。v-model是一个语法糖,包含两个操作,即v-bind绑定一个value属性,v-on指令给当前元素绑定input事件。如: 等价于 v-model和radio属性结合: 在input元素中,radio单选按钮属性,name属性用于 对提交到服务器后的表单数据进行标识。 将name属性设置为不同的值,可对两个选择按钮进行同时选择;将name属性设置为相同的值,就能实现互斥选择。常见的表单数据绑定: input=text文本框 input=radio单选按钮 input=checkbox复选框 input=select下拉框修饰符: lazy修饰符:v-model默认是在input事件中同步输入框的数据,只有改变输入框的数据,data中的数据就会立即改变。 lazy修饰符可以让数据在失去焦点或者回车时才会更新。 number修饰符:默认情况下,在输入框中无论输入字母还是数字,都会被当做字符串类型进行处理。number修饰符可以让输入框中的内容 自动转成数字类型。 trim修饰符:可过滤掉输入内容左右两侧的空格。
6.vue组件
组件系统,提供了一种抽象,可使用独立可复用的小组件来构建大型应用,任意类型的应用界面都可以抽象为一个组件树。组件需注册后才可使用,注册分为全局注册和局部注册两种方式。全局注册: 使用 Vue.component() 方法,先传入一个自定义组件的名字,然后传入这个组件的配置。 Vue.component('button-counter', { //组件内容
7.vue-router
路由中有三个基本概念: route, routes, router。 route:指的是一条路由,是单数。 routes: 是一组路由,即把每一条路由组合起来,形成一个数组。 router:是一个机制,相当于管理者,它来管理路由。客户端路由有两种实现方式:基于hash和基于 html5 history api。页面实现路由: 在vue模板中,使用 router-link 和 router-view 来对应点击和显示部分。 配置路由: const routes = [{path:'/home',component:Home},...] Vue.use(VueRouter) const router = new VueRouter({ routes }) export default router动态路由: 动态部分以 : 开头。如: const routers = [ {path:'/user/:userId', component:user} ] 如果想获取动态路由中的参数,需使用 this.$route.params.userId this.$route 匹配的是routes中处于活跃的路由。vue3.0项目常用依赖配置-安装路由,例如: //安装依赖 npm install vue-router@next --save // src文件夹下创建 router 文件夹,router文件夹下创建 index.js文件 // 配置router,进入index.js文件 import { createRouter, createWebHashHistory, createWebHistory } from 'vue-router' // 定义路由组件 import HelloWorld from '../components/HelloWorld.vue' // 定义路由配置 const routes = [{path;'/',redirect:'/HelloWorld'},{path:'/HelloWorld',name:'HelloWorld',component:HelloWorld}] // 创建路由实例 const router = createRouter({ //采用hash模式 history: createWebHashHistory(), //采用history模式 history: createWebHistory(), routes }) export default router;编程式导航:即通过调用JavaScript形式的API实现导航的方式。如:普通网页的location.href。 this.$router.push('hash地址') this.$router.go(n) router.push()方法的参数规则: router.push('/home') //字符串-路径名称 router.push({path:'/home'}) //对象 router.push({name:'hello',params:{msg:'world'}}) //命名的路由-传递参数 router.push({path:'/about',query:{msg:'hello'}}) //带查询参数,变成 /about?msg=hello声明式导航:即通过点击链接实现导航的方式。 路由分为前端路由+后端路由,路由的本质就是对应关系。后端路由概念:根据不同的用户url请求,返回不同的内容。后端路由本质:url请求地址与服务器资源之间的对应关系。SPA(single page application): 1.后端渲染(存在性能问题)2.ajax前端渲染 3.SPA实现原理:基于url地址的hash(hash的变化会导致浏览器记录访问历史的变化,但是hash的变化不会触发新的url请求) 前端路由概念:根据不同的用户事件,显示不同的页面内容。前端路由本质:用户事件与事件处理函数之间的对应关系。 vue-router包含的功能有:支持HTML5历史模式或hash模式;支持嵌套路由;支持路由参数;支持编程式参数;支持命名路由。 路由重定向:通过路由规则的redirect属性,指定一个新的路由地址,设置路由的重定向。 注意: alias 别名的作用,类似于重定向的效果。 alias给组件取一个别名,利用这个别名去访问页面。 redirect和alias区别: redirect:观察url的变化,redirect是直接改变了url的值,把url变成了真实的path路径。 alias:url路径没有发生变化,这种情况更友好,让用户知道自己访问的路径,只是改变了
8.vuex状态管理
vuex:一个专为vue.js应用程序开发的状态管理模式。 使用vuex注意事项:1.应用层级的状态应该集中到单个store对象中。2.提交mutation是更改状态的唯一方法,并且这个过程是同步的。 3.异步逻辑都应该封装到action里面。vuex的五个核心概念: state, getters, mutatioins, actions, modules。state: state是唯一的数据源,只要通过import导入vuex,然后通过vue.use(vuex),就可以通过this.$store拿到vuex的对象,state就是 在vuex里面定义的属性。基本数据。 在computed中,使用 mapState 辅助函数可获取state里面的属性。如: computed: { ...mapState({}) }getters: 通过getters可派生一些新的状态。从基本数据派生的数据。 mapGetters辅助函数可将store中的getters映射到局部计算属性。如: computed: { ...mapGetters(['countDouble','countTest']) } // 如果想将一个getter属性另取一个名字,可使用对象形式,如: mapGetters({ double: 'countDobule' })mutations: 更改vuex的store中的状态的唯一方法就是提交mutation。同步操作。提交更改数据的方法。 mapMutations辅助函数,可以在组件中使用 this.$store.commit('xx') 提交mutation。 或者使用 mapMutations辅助函数将组件中的 methods映射为 store.commit 调用 actions: action提交的是mutation,而不是直接变更状态。异步操作。像一个装饰器,包裹mutations。 action函数接受一个与store实例具有相同方法和属性的context对象。因此可以调用 context.commit提交一个mutation, 或者通过 context.state 和 context.getters 来获取state 和 getters。 action 通过 store.dispatch 方法触发,如: store.dispatch('increment') mapActions辅助函数将组件的methods映射为 store.dispatch调用。 this.$store.dispatch('xx')modules:可将vuex的store对象分割成模块modules。模块化Vuex。如: const moduleA = {state:{},...} const moduleB = {state:{...},...} const store = new Vuex.Store({ modules: { a: moduleA, b: moduleB } }) //使用 this.$store.state.a //moduleA的状态 使用vue-cli脚手架创建项目后,运行 npm install vuex 命令安装vuex。安装完成后,在项目中创建 store文件夹,创建index.js//index.js //引入vue,vuex import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export const store = new Vuex.Store({ state: { items: [{num:1,name:'xx'}] }, getters: { numChange(state){ return state.items.forEach(item=>item.num+=10) } }, mutations: { // mutations中的方法需要使用 commit 配合回调实现。 numTurn(state){ state.items.forEach(item=>{ item.num+=2 }) }, increment(){ } }, actions: { increment(context){ context.commit('increment') } } })//在其他组件内部使用methods:{ handleClick(){ this.$store.commit('numTurn') }}//main.js import store from './store/index' new Vue({ ..., store, })
9.vue-cli
vue-cli脚手架安装: 1.先检查是否安装了node, 使用命令 node -v 2.使用 npm install -g vue-cli //-g的意思是全局安装。 3.使用 vue -V 可查看版本卸载vue-cli: vue cli包名称由 vue-cli变为了 @vue/cli。如果想升级vue-cli3且已全局安装了旧版本vue-cli,需要先通过 npm uninstall vue-cli -g 或者 yarn global remove vue-cli卸载它。初始化项目: 创建项目: vue create vue-project启动项目: cd vue-project npm install npm run servevue-cli搭建项目,项目文件配置介绍: node_modules: 安装依赖代码库 src: 存放源码 static:存放第三方静态资源 package.json: { "name":"项目名称", ... "scripts": { ... //执行命令,配置脚本 }, "dependencies":{},//项目依赖 "devDependencies":{},//编译需要的依赖 } index.html,main.js,App.vue: 入口文件vue是MVVM框架,是以数据驱动的,不操作DOM,通过将DOM和数据绑定,利用Object.defineProperty中的setter,getter代理数据,监控对数据的变化,当数据改变时更新DOM。vue项目构建有两种方式,构建大型应用应使用命令行工具构建,另一种是直接通过