文章目录
前言
提示:这里可以添加本文要记录的大概内容:
vue基础知识普及专区
概念
MVVP框架以及适用的场景
1.MVVP框架是一个Model-View-ViewModel框架,其中ViewMode连接模型(Model)和视图(View)。其中ViewModel是最重要的一个环节,它是模型(Model)和视图(View)通信的一个桥梁,当你有数据需要展示的时候,ViewModel会自动地将数据绑定到View上面,当View上有一些操作或者事件,Model想要改变的时候,也是通过ViewModel。在数据操作比较多的场景中,MVVM框架更适合,有助于通过操作数据渲染页面。
model:数据模型,用于对数据的操作;
View:表示UI组件,作用是将模型的数据转换成UI展示;
ViewModel:视图模型,用于同步Model和View。
在MVVM架构下,view和Model之间没有直接联系,而是通过ViewModel进行交互,Model和ViewModel之间的交互是双向的,因此View数据的变化会同步到Model,Model数据变化也会立即反应在View。
***扩展***
MVC由Model, View, ViewMode三部分构成:
model:数据模型,用于对数据的操作;
View:表示UI组件,作用是将模型的数据转换成UI展示;
Controller:控制器,进行业务逻辑处理,不会自动同步渲染,需要开发人员进行干涉。通过Controller进行获取处理数据,再通过View将数据渲染出来。
2.MVVM是数据绑定的入口,整合了Observer,Complie和Watcher三者,通过Observer来监听自己model数据的变化(遍历数据对象,给所有属性加上setter和getter监听数据的变化),通过complie进行解析模板,通过Watcher作为complie和Observer之间桥梁。
Vue.js
Vue.js是一套用户界面渐进式的框架,采用自下而上的增量开发的设计,具有轻量级、易获取、组件化、简洁(HTML模板+JSON数据+Vue.js实例化对象)、数据驱动(计算属性和模板表达式)、低耦合度、独立开发等优点。
Vue.js采用ES5提供的属性特性功能,包括子属性对象的属性,设置set和get特性方法,当给这个对象赋值时,会触发set特性方法,于是就能监听数据变化。
complie解析模板指令
complie解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,就会收到通知,并更新视图。
watcher订阅者
watcher订阅者是Observer和Compile之间通信的桥梁;主要功能如下:在自身实例化时向属性订阅器(dep)里面添加自己;自身必须有一个update()方法;在dep.notice()发布通告时,能调用自身的update()方法,并触发Complie中绑定的回调函数。
vue-loader
它是vue文件的加载器,将template、js、style,通过webpack将vue格式的文件转换成js。
Vue响应式原理
Vue的响应式原理的核心是通过ES5的保护对象的Object.defindeProperty中的访问器属性中的set和get方法,data中声明的属性被添加了访问器属性,当修改data中的数据时,自动调用set方法,检测到数据的变化时,会通知watcher自动触发render当前组件,生成新的虚拟DOM,vue框架会遍历对比新旧虚拟DOM树,并记录不同点,最后加载修改到真是DOM树。
active-class
它是vue-router模块的router-link组件的属性。
vue的key
Key 是虚拟DOM对象的标识,他帮助Vue的diff算法进行虚拟DOM与就虚拟DOM的对比:
旧虚拟DOM未找到新虚拟DOM相同的Key,创建新的真实DOM;
旧的虚拟DOM找到与新虚拟DOM相同的Key,若内容一致,采用旧的虚拟DOM,若对比发现二者内容不一致,则新DOM代替旧的DOM。
不使用Key会导致数据进行顺序操作遭破坏,会产生没必要的真实DOM更新,虽界面效果没问题,但效率低下;若结构还包含输入类的DOM,会产生错误的DOM更新。
vue路由类型
3 种路由模式的说明如下:
hash: 使⽤ URL hash 值来作路由。⽀持所有浏览器,包括不⽀持 HTML5History Api 的浏览器;
history : 依赖 HTML5 History API 和服务器配置。具体可以查看 HTML5History 模式;
abstract : ⽀持所有 JavaScript 运⾏环境,如 Node.js 服务器端。如果发现没有浏览器的 API,路由会⾃动强制进⼊这个模式.
Vue.nextTick
在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM
this.$nextTick (function () {
// DOM 更新了
})
vue-router动态路由
在router目录下定义号视图路径,然后在调用视图时,通过path:“/视图路径”。
vue-router导航钩子
有3种;
第一种:全局导航钩子:router.before.Each(to,from,next),作用是跳转前进行判断拦截。
代码示例:
①路径设权限
{
path: '/role',
name: 'role',
meta: {
title: '会员',
auth: true
},
component: () => import("../views/RoleView")
},
②设置全局前置守卫,判断权限
// 设置全局前置导航守卫
router.beforeEach((to, from, next) => {
// 若有权限
if (to.meta.auth) {
let token =localStorage.getItem("h5-token");
if(token){
next();
}else{
next({
path:'/loginPassword',
query:{
url:window.location.href,
}
})
}
}
// 无权限就正常跳转
else{
next();
}
})
}
第二种:组件内的钩子;
组件内路由守卫3个:
beforeRouteEnter(to, from, next) {
// 进入当前组件 当前组件不存在 this不存在
//console.log(to,from);
//如果想获取组件的实例
//给next 添加一个匿名函数回调 形参vm 代表当前组件
next((vm)=>{
// console.log(vm);
// vm等价this 指当前组件实例 可以操作当前组件的相关变量
});
},
beforeRouteUpdate(to,from,next){
// 在当前路由改变,但是该组件被复用时调用
// 由于会渲染同样的组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
beforeRouteLeave(to, from, next) {
// 离开当前组件
//console.log(this);
next();
},
第三种单独路由独享组件。
beforeEnter:(to,from,next)=>{}
实现传参
第一种:父传子:父组件内调用子组件标签内附加=》 “ :‘传的变量名a’=‘要传的数据’ ”;
子组件用props:[‘父组件传来的变量名a’] 或者
props:{
父组件传过来的变量名a:{type:数据类型,require:true},
父组件传过来的变量名b:{type:数据类型,require:false},
}
子组件接收数据:
①直接获取
mounted() {
let _this=this;
let {datas,status}=_this._props;
console.log(datas,999999);
},
避免获取失败,可用定时器获取
mounted() {
let _this=this;
let {datas,status}=_this._props;
setTimeout(()=>{
console.log(this._props)
console.log(datas,111111)
},2000)
}
②深拷贝
mounted() {
let _this=this;
let props = {..._this._props};
console.log("props.......",props)
},
③用watch监听
//直接监听data,因为这里的props的变量名为data
watch:{
data(newData,prevData){
console.log(newData,123654789)
}
}
第二种:子传父
子组件数据通过 this.$emit(“自定义变量名A”,要传的数据),
父组件接收步骤:
①设置个获取数据的方法
getDate:function(data){
//Getdata是预先在父组件定义存储变量名
this.getdata = data;
}
在父组件调用的子组件标签里面设置自定义触发事件:
@子组件定义的变量名A=“getDate” ```
第三种:页面路由传参
第一页面:this.$router.push({
//跳转路径设置的两种方法
//第一种
path: “/要跳转的路径”,
//第二种
//name:“/要跳转的路径name值”,
//传数据的两种方法
//第一种通过query传
query:{
传数据的变量名A:this.要传的数据
},
//第二种通过params传
params:{
传数据的变量名A:this.要传的数据
},
})
第二个页面
接收步骤:
①定义变量B存储;
②第一种的接收=》
this.变量B=this. r o u t e . q u e r y . 上个页面传数据的变量名 A ;第一种的接收 = 》 t h i s . 变量 B = t h i s . route.query.上个页面传数据的变量名A; 第一种的接收=》 this.变量B=this. route.query.上个页面传数据的变量名A;第一种的接收=》this.变量B=this.route.params.上个页面传数据的变量名A;
第四种 用ref=“自定义名”=》标识组件 this.$refs.自定义名=》获取标识组件的所有数据
第五种 兄弟组件通信过程(总线模式)( $on、$off 和 $once 将被踢出)
实现步骤:
①Main.js 定义$bus
Let
b
u
s
=
n
e
w
V
u
e
(
)
;
V
u
e
.
p
r
o
t
o
t
y
p
e
.
bus = new Vue(); Vue.prototype.
bus=newVue();Vue.prototype.bus=
b
u
s
;
②其他页面通过在
m
o
u
n
t
e
d
里创建事件
=
》
t
h
i
s
.
bus; ②其他页面通过在mounted里创建事件=》this.
bus;②其他页面通过在mounted里创建事件=》this.bus.
o
n
(
“定义变量
A
”
,
用方法接收数据
f
u
n
c
t
i
o
n
(
d
a
t
a
)
t
h
i
s
.
d
a
t
a
=
d
a
t
a
)
;
t
h
i
s
.
on (“定义变量A”,用方法接收数据function(data){this.data=data}); this.
on(“定义变量A”,用方法接收数据function(data)this.data=data);this.bus.$emit(“定义变量A”,传参)
第六种 跨组件通信
父组件provide:{变量名:“数据”}
子组件接收 inject:[“变量名”]
## Vue生命周期
| 生命周期| 作用 |
|--|--|
|BeforCreate |Vue实例还未初始化(data和methods) |
| created |组件实例化完成,但是DOM未生成,data数据未挂载 |
|BeforeMount | 完成data初始化,但组件的内容未渲染 |
| Mounted |完成了数据和组件的挂载 |
| beforeUpdate |Vue是数据驱动,View层数据变化前,不是data中数据改变 |
| updated | 页面刷新或数据更新,会触发 |
|activated附加:提倡缓存切换组件<keep-alive :max=“最多缓存个数” :exclude=“排除缓存的组件名” :exclude=“排除缓存的组件名” :include=“包含的缓存组件名”>| 1. keep-alive,组件被激活时调用; 2. activated钩子函数必须在APP全局组件化时运用<keep-alive><router-view></router-view></keep-alive>,不然无法生效;3.可作为组件销毁前数据存储 |
|deactivated |1. keep-alive,组件被移除时调用;2. activated钩子函数必须在APP全局组件化时运用<keep-alive><router-view></router-view></keep-alive>,不然无法生效|
|beforeDestroy |销毁前 |
|Destroyed | 销毁后|
## vuex
### 使用场景
Vuex是一种开发框架或者模式,是对Vue.js框架数据层面的扩展,通过状态(数据源)集中管理驱动组件的变化,应用的状态集中放在store中,改变状态的方式是提交mutation,这是同步操作失误,异步逻辑封装在action中。
Vuex集中式存储管理应用的所有组件状态,并以相应的规则保证状态以可预测的方式发生变化;
Vuex要引入store,并注入Vue.js组件中,在组件内部即可通过$store访问store对象;
使用场景包括:在单页面应用中,用于组件间的通信,例如音乐播放器、登录状态等管理、加入购物车等。
Vuex结构:
state 状态中心
export default new Vuex.Store({ state:{ counter:0 },});
mutations 更换状态
export default new Vuex.Store({
mutations:
{
add(state) {
state.counter++
}
}
});
actions 动作(类似controller,存储动态事件)
export default new Vuex.Store({
actions:
{
add({commit}) {
setTimeout(() = >{}
}
});
getters从state派生类似计算属性(),但getters可以在多组件之间复用
export default new Vuex.Store({
getters:
{
doubleCounter(state) { // 计算剩余数量 return state.counter * 2;
}
}
})
;
不使用Vuex会带来的问题
可维护性会下降,想修改数据要维护三个地方;
可读性会下降,因为一个组件里的数据,根本无源可循;
增加耦合,大量的上传派发,会让耦合性大大增加。
Vuex 原理解析
实现一个插件,是vue.js数据状态管理系统:声明store类,挂载$store
Store具体实现(五大模块):
(1).State:专门存储数据,本身是js对象,页面刷新时,若没做持久化处理,数据就会清空。(modules模块申明小模块,小模块的state模块传数据不是对象,而是用函数传输:state:()=> ({键名:键值}) );
(2).Getters:类似计算属性;
(3).Mutations:同步提交;
(4).Actions:异步请求;
(5).Modules: modules,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。
vue常用自定义指令
(1). v-bind绑定数据
v-bind:src=“value” =》 :src/:class=“value”;
(2). v-on触发事件
v-on:click=“value” =》 @click=“function” @click=“function()”;
(3). v-for遍历
v-for=“(item,index) in Arry|Object|number|string|Iterable”;
(4).v-if ,v-else条件渲染
v-if可单独,v-else必须配合v-if使用;
(5).v-slot 插槽
(6).v-model 双向绑定数据
v-model=“value”
Axios
Axios替代Vue2.0的vue-resourse.js插件的一个模块,用于请求后台资源的请求。
解决vue样式覆盖不生效问题
一般是因为scoped私有化(局部化)导致,引入第三方组件库也会导致,因此可以通过外部创建css文件,通过main.js引入,或者用深度作用操作符(/deep/),可以使样式作用的更深。
在vue.js开发环境下调用接口,如何避免跨域在工程目录
config/index.js内对proxyTable项进行配置
proxyTable:{
‘/api’:{
target:’http://xxxx.com’,
changeOrigin:true,
pathRewrite:{
‘^/api’:’’
}
}
}
vuex和redux的区别
引入方式:
Vuex中用$store被直接注入到组件事例中,使用dispatch和commit提交更新;通过mapState或者直接通过this.$store来获取vuex存储的数据或方法。
Redux中,我们每一个组件都需要显示用connect把props和dispatch连接起来。
在组件中,vuex更加灵活,组件可以dispatch action 也可以commit updates,而Redux中只能进行dispatch,不能直接调用reducer进行修改。
原理:
Redux使用的不可变数据,vuex数据是可变的。Redux每次都是用新的state替代旧的state,而vuex直接修改。
Redux在检测数据变化的时候,是通过diff的方法比较差异,而vuex和vue一样,通过触发setter/getter来比较数据变化。
引入方式:
Vue和React 技术选型
相同点:
1.数据驱动页面,提供响应式的视图组件;
2.都有virtual DOM ,组件化的开发,通过props参数进行父子通信,都实现了webComponents规范;
3.数据流动单向,都支持服务器的渲染SSR;
4.都是支持native的方法,react有React native,vue有wexx;
不同点:
- 数据绑定:Vue实现了双向绑定,react数据流动是单向;
- 数据渲染:react大规模渲染更快,而且支持大规模项目,Vue适合小快型项目;
- 开发风格:react推荐做法jsx+inline style,把HTML和css写在js;而vue采用webpack+vue-loader单文件组件格式,js、html、css同一文件。
Vue3 响应式数据如何实现
响应式核心方法就是 reactive 和 effect, 其中 reactive 方法是负责将数据变成响应式, effect 方法的作用是根据数据变化去更新视图或调用函数
import { reactive,ref} from “vue”;
Stup(){
//普通数据类型用
refLet str=ref(“123”);
//复杂数据类型
Let state=reactive({
Name: “xx”,
Age:12
});
Let obj = reactive({title:”H5”})
//Ref基本数据类型在函数内必须加“.value“
Const handleClick= ()=>{
str.value =”22”
}
//obj 直接再标签内点击修改可以实现,但定义的函数内不可以直接实现
const headleObj=()=>{
//错误写法
//Obj.title.value = ‘JS’;
//正确写法
obj.value.title = ‘JS’
}
}