1.vue双向数据绑定原理
Vue.js采用数据劫持发布者订阅模式的方式,通过object.defineproperty()来劫持setter和getter在数据变动时,发布消息给订阅者,触发相应的回调来渲染视图
1、实现一个数据监听器Observer(恶不热玩),能够对对象的所有属性进行监听,如有变动可拿到最新值并通知订阅者
2、实现一个指令解析器 Compile(康拍哦),对每个元素节点的指令进行扫描和解析,替换数据,绑定更新函数
3、实现一个 Watcher,作为连接 Observer 和 Compile 的桥梁,能够收到每个属性变动的通知,绑定相应回调函数,从而更新视图
2.vue虚拟dom,diff算法
虚拟dom 是根据模板生成一个js对象,根据这个js对象再去生成真实的dom,对复杂的文档DOM结构,提供一种方便的工具,进行最小化的DOM操作 diff算法 当data发生改变 会根据新的数据生成一个新的虚拟dom ,新的虚拟dom和旧的虚拟dom进行对比,这个对比的过程就是diff算法,会找到不同地方,只去渲染不同的地方
3.组件通信
1、父传递子如何传递
在父组件中给子组件标签上绑定一个属性, 属性上挂载需要传递的值
在子组件通过props:[“自定义属性名”]来接收数据
2、子传递父如何传递
(1)在父组件中给子组件标签绑定一个自定义事件,给这个事件挂载需要调用的方法
(2)在子组件的方法通过this.$emit(‘自定义事件名’)来调用这个方法
3、兄弟组件如何通信
(1)创建一个空的vue实例BUS
(2)通过BUS.
e
m
i
t
(
‘
事
件
名
’
)
传
到
空
的
v
u
e
实
例
中
(
3
)
通
过
B
U
S
.
emit(‘事件名’)传到空的vue实例中 (3)通过BUS.
emit(‘事件名’)传到空的vue实例中(3)通过BUS.on(‘事件名’,(参数)=>{挂载从子1传来的数据})来接收
4.vuex
1.什么是vuex?
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式
2.由五部分组成
state: 数据
actions:可以包含异步操作
mutations: 唯一可以修改state数据的场所
getters:类似于vue组件中的计算属性,对state数据进行计算(会被缓存)
modules:模块化管理store(仓库),每个模块拥有自己的state、mutation、action、getter
3.vuex有什么好处?及使用场景
好处:可以实现多组件之间的数据共享
易于开发和后期维护
提高开发效率
存储在 Vuex 中的数据都是响应式的 能够实时保持数据与页面同步
使用场景:(1)登录信息、(2)购物车、(3)复杂的组件通信
4.vuex中的mutations和actions如何调用
//调用acionts中的方法
this.$store.dispatch('actions中的函数名',需要传递的值);
//调用mutations中的方法
this.$store.commit('mutations中的函数名',需要传递的值)
5. 高级用法-之 辅助函数(语法糖)
// vuex辅助函数 让代码更加简洁
1. 有那几个辅助函数(4大金刚)
mapState,mapActions,mapMutations,mapGetters
2. 辅助函数可以把vuex中的数据和方法映射到vue组件中。达到简化操作的目的
3. 如何使用
// …es6中的展开运算符,把vuex中的mutation方法展开在我们的methods中 ,可以直接使用,避免像以下代码一样出现重复的this.$store.commit
6. 高级用法-之 数据持久化
vuex配套的持久化插件
// 1.安装 cnpm i vuex-persist --save
// 2.引入 import vuexPersist from "vuex-persist";
// 3.配置
// plugins: [
// new vuexPersist({
// storage: window.localStorage,
// }).plugin,
// ],
//配置vuex本地存储插件
5.vue-router(路由原理?路由守卫?传参?)
6.生命周期(哪几个?每一个周期特点,可以做什么)
1.每一个组件都是独立的,都有属于他自己的生命周期,创建,挂载,更新销毁就是生命周期
2.生命周期分为四个阶段
beforeCreate 前<创建>后created
beforeMount 前<挂载>后mounted
beforeUpdate 前<更新>后Updated
beforeDestroy 前<销毁>后Destroy
beforecreate (创建前):el 和 data 并未初始化,因此无法访问 methods, data, computed 等上的方法和数据。
create (创建后):实例已经创建完成,完成了 data 数据的初始化,el 没有。
beforeMount (挂载前):把 data 里面的数据和模板生成 html,完成了 el 和 data 初始化
mounted (挂载后):就是模板中的 HTML 渲染到 HTML 页面中,mounted 只会执行一次。
beforeUpdate (更新前):在数据更新之前被调用,发生在虚拟 DOM 重新渲染之前,
**update (更新后) **:在由于数据更改导致地虚拟 DOM 重新渲染时调用
beforeDestrioy (销毁前):这一步还可以用 this 来获取实例,清除掉组件中的定时器和监听的dom
destroyed (销毁后)(销毁后):在实例销毁之后调用,所以的事件监听器会被移出,所有的子实例也会被销毁
7.自定义指令,自定义过滤器
1.【全局指令】:使用 Vue.diretive()(迪瑞 体悟)来全局注册指令
2.【局部指令】组件或 Vue 构造函数中接受一个 directives 的选项。
钩子函数。指令定义函数提供了几个钩子函数(可选)
1.bind:绑定元素的时候调用
2.inserted:绑定的元素插入父节点时调用,
3.update:绑定元素的值改变的时候调用,改变之前,
4.componentupdated(康噗嫩特):绑定元素的值改变之后调用,
5.unbind:解绑元素的时候调用
钩子函数参数:el,binding
el:绑定的元素,用来操作DOM,
binding:绑定的对象信息。
name:指令的名字,value:指令的值
可以用自定义指令封装一个拖拽的盒子
Vue.directive("drag", { //指令的名称
inserted: function (el, binding) { //当被绑定的元素插入到 DOM 中时
el.style.position = "absolute";
el.style.left = binding.arg.left + "px";
el.style.top = binding.arg.top + "px";
el.onmousedown = function (e) {
var x = e.offsetX;
var y = e.offsetY;
document.onmousemove = function (eve) {
el.style.left = eve.clientX - x + "px";
el.style.top = eve.clientY - y + "px";
}
document.onmouseup = function () {
document.onmousemove = null;
document.onmouseup = null;
}
}
}
8.自定义组件
9.常用的指令,修饰符
1.指令
(1)V-for循环 (2)v-on绑定事件(3)v-model双向数据绑
(4)v-text渲染字符串(5)v-html渲染html节点及字符串
(5)v-if判断(7)v-show显示/隐藏(8)v-bind绑定属性
2.修饰符
stop 阻止事件冒泡
prevent (铺完特)阻止事件默认行为
capture (凯卜切儿)触发事件捕获
self (勺夫)当事件在元素本身,触发回调
once (玩时)只执行一次
10.vue2和vue3的区别
1、性能提升
一句话简介:更小巧,更快速;支持摇树优化;支持 Fragments 和跨组件渲染;支持自定义渲染器。
2、API 变动摇树优化
一句话介绍:除渲染函数 API 和 scoped-slot 语法之外,其余均保持不变或者将通过另外构建一个兼容包 来兼容 2.x。
模板语法的 99% 将保持不变。除了 scoped slot 语法可能会有一些微调之外变动最大的部分将是渲染函数 (render) 中的虚拟 DOM 的格式。
3、重写虚拟 DOM (Virtual DOM Rewrite)
随着虚拟 DOM 重写,减少 运行时(runtime)开销。重写将包括更有效的代码来创建虚拟节点。
11.keep-alive
包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们,它自身不会渲染一个DOM元素,也不会出现在父组件中
作为标签使用 包裹在需要缓存的组件外
大白话: 比如有一个列表和一个详情,那么用户就会经常执行打开详情=>返回列表=>打开详情…这样的话列表和详情都是一个频率很高的页面,那么就可以对列表组件使用进行缓存,这样用户每次返回列表的时候,都能从缓存中快速渲染,而不是重新渲染
12.多环境变量
环境变量,就是全局需要用到的变量,比如接口地址,项目名称等。项目又可能身处不同的环境,比如测试环境、开发环境不同,请求的接口地址不同。
环境变量文件位置于项目根目录,文件名是.env、.env.development和.env.production
13.对axios封装,(url统一管理,axios请求拦截、响应拦截,函数封装)
一、为什么要对paomise进行封装
每写一个vue文件获取api接口都要写get和post会非常的麻烦
所以要对axios进行封装。
二、封装的思路
新建一个index.js文件作为网络模块的入口文件,定义请求方法
创建一个url.js用来管理接口
新建request.js文件,封装网络请求的核心方法和网络模块需要提供的功能
封装的方法包括:请求参数,请求成功或者失败的处理,请求前请求后的处理,切换环境等。
需要提供的功能包括:具体的请求方式,上传,下载等
14.element-ui,vant-ui按需引入
element-ui按需引入
1、借助 babel-plugin-component ,引入我们需要的组件,减少项目体积
npm install babel-plugin-component -D
2、修改 babel.config.js 的内容
//babel.config.js 全文内容如下
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
],
plugins: [
[
'component',
{
libraryName: 'element-ui',
styleLibraryName: 'theme-chalk'
}
]
]
}
3.创建文件 element.js(名字自定义)
// element.js 全文内容如下,按自己需要引入就好了
import Vue from 'vue'
import {
Button,
Form,
FormItem,
Input,
} from 'element-ui'
Vue.use(Button)
Vue.use(Form)
Vue.use(FormItem)
Vue.use(Input)
Vue.prototype.$message = Message
Vue.prototype.$confirm = MessageBox.confirm
4.最后在 main.js 中引入这个文件
//main.js 中添加下面这行代码(路径和文件名按自己的来)
import './plugins/element.js'
在 main.js 中添加如下代码
import ElementUI from 'element-ui';
Vue.use(ElementUI);
vant-ui按需引入
1.安装vant-ui插件
#先安装vant-ui
cnpm install vant-ui --save
# 再安装按需引入的插件
cnpm i babel-plugin-import -D
2.在babel.config.js中添加配置
plugins: [
['import', {
libraryName: 'vant',
libraryDirectory: 'es',
style: true
}, 'vant']
]
3.创建一个plugin文件夹,在plugin中定义一个js文件用来存放代码
4.之后在建好得js文件中首先导入vue,在导入需要的vant-ui插件,通过vue.use() 全局注入
5.在min.js里面引入
import 'vant/lib/index.css';
// 全局引入按需引入UI库 vant
import '@/plugins/vant'
15.sass配置
1、创建一个基于 webpack 模板的新项目
$ vue init webpack myvue
2、在当前目录下,安装依赖
$ cd myvue
$ npm install
3、安装sass的依赖包
npm install --save-dev sass-loader
//sass-loader依赖于node-sass
npm install --save-dev node-sass
4、在build文件夹下的webpack.base.conf.js的rules里面添加配置
{
test: /\.sass$/,
loaders: ['style', 'css', 'sass']
}
5、在APP.vue中修改style标签
<style lang="scss">
6、然后运行项目
16.rem、vw/vh设置
1、rem配置
rem:相对于根元素(即 html 元素)font-size 计算值的倍数。通俗的说,1rem = html 的 font-size 值
如何使用 rem 进行布局?
1.标签的 rem 单位的值怎么计算
通过使用 rem + js 改变 html 标签的 font-size(整体缩放)实现兼容性更高的页面
下面来举个例子,
当我们拿到的设计图是 750px 的时候,窗口宽度 750px,html 的 font-size 的大小为
100px;
也就是说 1rem = 100px;所以标题的 font-size 的大小为 26/100=.26rem;
2、vw/vh设置
根据 PSD 文件宽度或高度作为标准,元素单位 px 转换为 vw 或 vh,比如font-size: 12px,PSD 文件宽度 375,转换公式 12 * 100 / 375,则样式改为font-size: 3.2vw,下面是我经常使用的工具,有利于提高转换效率。
可以通过html下fontsize的值*100/PSD 文件宽度或高度来获取到vw 或 vh,从而实现兼容性更高的页面
现阶段手机端用的最多就是这个方法,能保持不同屏幕下元素显示效果一致, 也不用写多套样式。