概念
渐进式 javascript 框架 , 一套拥有自己规则的语法 渐进式: 逐渐进步, 想用什么就用什么, 不必全都使用
库和框架
封装的属性或方法 (例jquery.js) 框架: 拥有自己的规则和元素, 比库强大的多 (例vue.js)
脚手架-介绍
官方提供脚手架, 快速搭建项目基础结构 webpack自己配置环境繁琐 脚手架是为了保证各施工过程顺利进行而搭设的工作平台 在代码里的体现, 就是一套固定标准的, 文件夹+文件+webpack配置 零配置,开箱即用,基于它快速搭建项目基本开发环境
脚手架-准备
安装@vue/cli全局模块包npm install -g @vue/cli以后创建Vue, 得到Vue命令,创建脚手架项目
脚手架-创建项目-启动服务:Vue命令, 创建一个脚手架项目, 并启动webpack开发服务器
- 创建项目 注意: 项目名不能带大写字母, 中文和特殊符号 vue create 英文名称
import Vue from 'vue' // 引入vue 得到Vue这个甘薯
import App from './App.vue' // 引入App文件里的一切过来
Vue.config.productionTip = false // 控制台里有一句话
new Vue({ // 实例化对象
render: h => h(App), // render(固定)配置型 函数渲染App.vue文件里的标签样式
}).$mount('#app') // $mount()把app渲染到
Main.js 是webpack打包入口 App.vue页面入口 index.html网页入口
脚手架自定义配置 src并列处 创建 vue.config.js 其他方式不变
Eslint 是代码检查工具 违反规定就报错 使用在vue.config,js 中 使用lintOnSave: false 进行关闭 之后重启服务器
在vue中的style Scoped这个属性 只在此组件中添加css的"scoped"属性 css 就不会冲突
而且template 属性中必须有 一个根标签div
单vue文件的好处?独立作用域,不再担心变量重名问题
单vue文件使用注意事项? template里只能有一个根标签
单vue文件里标签和样式最后怎么显示到页面? webpack打包后, 插入到index.html显示
脚手架-清理欢迎页面
src/App.vue默认有很多内容, 可以全部删除留下框 assets 和 components 文件夹下的一切删除掉 (不要logo和HelloWorld页面)
vue语法-插值表达式
语法:{{ 表达式 }}又叫: 声明式渲染/文本插值/大胡子语法
export default 中有 data方法{return{}} data是个方法 里面必须return 对象
Vue基础-MVVM设计模式 (Model-View-ViewMode数据 视图 视图数据层)
是一种软件的架构模式 有助于将图形用户界面的开发与业务逻辑或后端逻辑(数据模型)的开发分离开来,这是通过置标语言或GUI代码实现的。MVVM的视图模型是一个值转换器,这意味着视图模型负责从模型中暴露(转换)数据对象,以便轻松管理和呈现对象。在这方面,视图模型比视图做得更多,并且处理大部分视图的显示逻辑。 视图模型可以实现中介者模式,组织对视图所支持的用例集的后端逻辑的访问
设计模式: 是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。(代码分层, 架构设计)
MVVM,一种软件架构模式,决定了写代码的思想和层次
M: model数据模型 (data里定义)
V: view视图 (页面标签)
VM: ViewModel视图模型 (vue.js源码)
MVVM通过数据双向绑定让数据自动地双向同步 不再需要操作DOM
在vue中,不推荐直接手动操作DOM!! 在vue中,通过数据驱动视图,不要在想着怎么操作DOM,而是想着如何操作数据!!(思想转变)
Vue指令学习
以V-开头的标签属性 叫指令 给标签添加额外功能
v-bin动态属性
给vue属性标签设置vue变量的值 v-bind:href=”Vue变量” 作用标签的原生属性添加Vue变量 语法糖为 : :属性名=’vue变量名’
v-on事件绑定
v-on:事件名 = ‘methods中的函数名’ 他的语法糖为 @事件名=” methods方法”
export default {
data:{return { 数据 }}
methods:{
addSum1 () {
this.sum++ // 执行函数 methods函数中的this:当前vue文件(组件)对象,webpack在运行打包时 会把 data/methods里的变量和方法 统统的放到this的身上
},
}}
Vue指令-v-on事件对象 如何获事件对象 有参数(@click="tow(10, $event)")与无参数(@click="one")两种:当没有参数的时候直接通过形参直接接收即可 如果有其他参数 就要在实参处 手动写上 $event 而且参数要 一一对应 这样在在形参处就可以拿到 事件对象
v-on的事件修饰符
@事件名.修饰符="methods里函数" .stop 阻止事件冒泡 .prevent 阻止默认行为 两个都可以一起使用 @click.prevent.stop="aFn" 既要阻止冒泡 又要阻止默认跳转
给键盘事件, 绑定修饰符 @keyup.enter 监测回车按键 @keyup.esc 监测返回按键
更多修饰符:
https://cn.vuejs.org/v2/guide/events.html#%E6%8C%89%E9%94%AE%E4%BF%AE%E9%A5%B0%E7%AC%A6
转换数组split(‘’) 翻转数组arr.reverse() 转换为字符串let str = arr.join(‘’)
v-model双向绑定
语法: v-model="vue数据变量" 数据变化-> 视图自动同步视图变化 -> 数据自动同步 只能用在一个 表单身上 表中的 与 vue中变量 一起改变 在vue中的插件中进行保存 才能显示 而且在密码框中 vue的插件也会显示出来(双向绑定)
下拉菜单的v-model要绑定在select上
v-model 遇到复选vue的变量非数组(变量给的是字符串) 关联的复选框checkbox(true/flase)
数组 关联的是复选框的value属性 (也是是 将变量变成数组的方式 就会变成 value )
数据驱动页面在变量内写上value 也是可以改变 页面的数据的
v-model的修饰符
. 以parseFloat转成数字类型 .trim 去除首尾空白字符 .lazy 在change(改变)时触发而非input时 只要被标签一转手(获取,都是字符) 所以要使用 v-model.number=’变量’同步到的就不是字符串
Vue指令-v-html
语法:v-html”Vue的变量” 作用:快速的设置innerHTML标签 还有v-text:把值当成普通txt {{插值表达式把值当成普通字符串显示}}
Vue指令-v-show和v-if
v-show="vue变量"(变量是布尔值) true显示 false隐藏 v-show 用的display:none隐藏 (频繁切换使用)
v-if="vue变量"(变量是布尔值) true显示 false隐藏 v-if 直接从DOM树上移除
v-else 使用 作用场景 两个标签 要相互互斥显示的时候
Vue指令-v-for
v-for="(值变量, 索引变量) in 目标结构" v-for="值 变量 in 目标结构"
知识点
数组方法:filter
-+
let newArr = arr.filter((val) => {return val >= 30}) 数组调用.filter()方法 - 传入一个函数体 (固定格式) 运行过程: filter会遍历数组里的每一项, 对每一项执行一次函数体(会把每个值传给形参) 作用: 每次遍历如果val值符合return的条件, 就会被filter收集起来 返回值: 当filter遍历结束以后, 返回收集到的符合条件的那些值形成的新数组
更新检测 key的作用
触发V-for的更新 reverse()翻转数组可以进行for的更新 而截取数组是不可以的 单独字面量是不可以跟新数组的 数组方法修改是可以的 整个重新赋值 是可以的 总结: 除了字面量的方式以外 只要改变原数组都能到这v-for更新
Vue提供了 this.$set(this.arr, 0, 1000)t方法 改变数组中的某个值参数1: 更新目标结构 参数 2: 更新位置 参数3: 更新值
v-for 更新:会准备一套DOM结构 渲染到页面上 v-for检测到目标结构变化 在生成DOM结构作对比 只会改变有差异的部分 尽可能原地复用现有标签
key的作用
无key 和由key(值为索引),v-for更新的时,(就地复用标签) 有key(值为id ),v-for 更新的时候 会提高’ 更新’的性能key值的要求:唯一不重复 数字或字符串 结论:key属性提高更新是 性能 DOM变化后用 key 来做对比找出差异 更新真实的DOM key的值要么用id 没有id用索引
vue动态class 和 style
:class="{类名: 布尔值||变量 , 类名2:布尔值}" :style="{css属性: 值}"
在使用 bootstrap 内的css 的时候 要在入口处进行引用但是 import 'bootstrap/dist/css/bootstrap.css' 在node_modules内找到 'bootstrap 文件 内的 /dist/css/bootstrap.css 就可以使用 css了
let index = findIndex((obj)=> obj.XX=== XX) findIndex()方法 找到条件对应的就进行停止函数 返回数组下标用
时间处理:下载 moment 包 在模块中进行引用import moment from 'moment' 定义函数 将现在new data() 传进来
return moment(dateObj).format("YYYY-MM-DD") 返回出去 值
vue计算属性-computed
一个数据, 依赖另外一些数据计算而来的结果 computed: {"计算属性名" () {return "值"}} 作用:当一个变量的值 通过其他变量 计算而得来的前面的 效果:计算属性里引用的变量发生值的变化后 重新执行计算属性里面的函数代码
计算属性的优势: 计算属性计算一次并缓存 第一次计算完成后 保存到缓存中 第二次值没有变 就直接取出缓存中的值 进行使用 当依赖的值发生改变 当计算属性内使用的变量发生改变 计算属性会重新计算一次并缓存 与 函数相比 调用一次执行一次 使用场景 当变量值 依赖其他变量计算而得来才用
在给计算属性赋值的时候才使用完整写法 语法:属性名:{set(值){ }, get() {return "值"}}
set() {},有人给计算属性 "赋值"的时候 会自动触发次函数 (当页面中的值发生改变就会执行set)
get() {} 有人要使用计算属性变量值的时候 会自动触发 此函数 必须return值 (数据在给页面的时候才会执行)
侦听器watch
可以侦听data/computed属性值改变
语法: watch: {"被侦听的属性名" (newVal, oldVal){}} newVal 新的值 oldVal旧的值 在监听数组 或者 对象的时候 需要在 watch对象中 使用 deep; true 开启深度监听 这样就可以监听对象或者数组 newVal, oldVal监听变量的值(本身就是个独享) 改变数据 改的是对象里面的属性值 对象本身并未修改(还是那个对象)
完全监听
watch: {
list: {deep: true, handler() {localStorage.setItem("todolist", JSON.stringify(this.list));},},}
list 为要监听的变量 deep: true 深度监听的设置 list 对象内要有一个 函数 函数内会有两个参数 newVal 和 oldVal
Vue组件
一个页面, 可以拆分成一个个组件,一个组件就是一个整体, 每个组件可以有自己独立的 结构 样式 和 行为(html, css和js)
组件化思想 封装一套 复用的标签 + 样式 +js 反复调用和使用
创建组件
局部注册 和 全局注册 注册的名字是什么 然后将这个名字以标签的形式写在模板内
分为四步: 创建组件 引入(import XXX from “./XX/XX/XXX”)注册组件(Vue.component()方法注册组建) 使用组建必须在Vue实例的范围内使用
注册组建: 全局注册:Vue.component(“组件名”: XXX) 局部注册:component:{“组件名”:引入的组件名, 组件名}(名字与 属性名相同就可以直接简写) 组件名就是 使用时候的标签名
组件-scoped作用 <style scoped>
解决多个组件样式名相同, 冲突问题
Webpacl 在解析和打包VUE文件内标签和样式的时候会自动给标签添加data-v-hash值属性, 所有选择都带属性选择 依次来限制css选择器的作用范围
组件通信-父向子-props
从某个 .vue文件 向另外.vue文件 传值 的时候 还是父子关系的时候
使用:方式 父组件 à 子组件 确认好之间关系 语法: 在子组件内 props[“变量1”,”变量2”](一定是个字符的方式vue会把他们解析为变量) 父组件内 在标签上 向变量传值 字后子组件就可以使父组件里面的数据了
组件就是用来展示数据的 我在子组改传来的值 父组件重新渲染会把 props的值覆盖 结论 props的变量会覆盖
使用对象形式
Props:{ bgc: String, 直接定义一个字符串
Color:{type:String, 必须是个字符串类型 default:"black" 默认值是black }}
content:{type:String, 必须是个字符串类型 required:true 是个必须传入的值}}
对象内还可以validator(val){ } 来自动校验规则 val是传来的值 如果 return true就证明可以传入 如果返回的是false 就不可以使用
组件通信_单向数据流
我们不能违反 单向数据流 因为父组件重新渲染会把 props的值覆盖
从发父向子传递的流向 props 只能读 不能改
组件通信-子向父 this.$emit()
子组件触发自定义事件 父组件内 绑定自定义事件和事件处理函数 语法@自定义事件名=”父methods的函数名” 子组件在发生点击的时候 执行点击函数函数内使用 this.$emit(”父组件的自定义事件名”,参数) 就回去找父组件得自定义名所对应函数 接收$emit 传来的值 执行函数 更改数据通过for循环重新渲染 到子组件中
VUE声明周期
一个Vue实例从创建 到销毁的过程 就是Vue实例的声明周期
钩子函数
Vue 框架内置函数,随着组件的生命周期阶段,自动执行
特定的时间点,执行特定的操作 组件创建完毕后,可以在created 生命周期函数中发起Ajax 请求,从而初始化 data 数据 4大阶段8个方法
四大阶段( 每一个 阶段有两个方法)
初始化阶段 初始化前: beforeCreate 初始化之后created
挂载阶段 挂载前beforeMount 挂载后 mounted
更新 更新前 beforeUpdate 更新后 updated
销毁 销毁前beforeDestroy 销毁后 destroyed
初始化阶段: 初始前created里操作data中的变量 beforeCreate是拿不到 data中的数据的
挂载阶段: template选项检查 虚拟DOM挂载成真实DOM之前 beforeMount – 生命周期钩子函数被执行
1.template选项检查 有 - 编译template返回render渲染函数 无 – 编译el选项对应标签作为template(要渲染的模板)
2.虚拟DOM挂载成真实DOM之前
3.beforeMount – 生命周期钩子函数被执行
4.Create … – 把虚拟DOM和渲染的数据一并挂到真实DOM上
5.真实DOM挂载完毕
6.mounted – 生命周期钩子函数被执行
在获取真实DOM中一定要在mounted中获取
虚拟DOM比真实DOM优点
- 虚拟DDOM的关键属性要比真实DOM少(一个标签对象有200+属性)
- 操作虚拟DOM要比真实DOM快(因为他是一个本深就是一个JS对象)
更新阶段
掌握更新阶段2个钩子函数作用和执行时机
- 当data里数据改变, 更新DOM之前
- beforeUpdate – 生命周期钩子函数被执行
- Virtual DOM…… – 虚拟DOM重新渲染, 打补丁到真实DOM
- updated – 生命周期钩子函数被执行
- 当有data数据改变 – 重复这个循环
销毁阶段
beforeDestroy() {} 销毁前
destroyed(){}销毁后 在销毁后我们要手动清除组件中的 计时器 定时器 全局事件等等
1.当$destroy()被调用 – 比如组件DOM被移除(例v-if)
2.beforeDestroy – 生命周期钩子函数被执行
3.拆卸数据监视器、子组件和事件侦听器
4.实例销毁后, 最后触发一个钩子函数
5.destroyed – 生命周期钩子函数被执行
Axios使用
Axios 是一个专门发送ajax请求网络请求的库 下载 axios包 基于原生ajax+Promise技术封装通用与前后端的请求库
使用 下载 axios包 在需要使用的地方进行引用 在恰当的实际发送网络请求 axios()调用后 会在原地留下一个 promise(承诺)对象 (包含一个异步任务的 JS原生的ajax请求) promise 里ajax请求成功-内部的resolve()传出结果给res res拿到的是ajax处理后准换的后的对象 他会把 原生的ajax拿回来的JSON字符串转换为 js类型放到data字段里
axios({
methods:'get', 请求的方式
url:'http://123.57.109.30:3006/api/getbooks' 请求的地址
data:{} 请求体
params:{} 查询字符串的?后面
}).then(res=>{console.log(res);}).catch(err=>{console.log(err);}) //请求失败和成功的响应
axios.defaults.baseURL="URL地址" 拼接基地址 这样就不用总是配置了
获取DOM
Vue中自带的$refs 使用场景父组件里,直接拿到子组件队形(调用子组件里方法\变量) 在组件中订定义一个ref=”别名” 在恰当的时机 使用 this.$refs.别名 对饮过的组件对象获取在原地 data改变DOM在随之改更新的过程是异步
$nextTick的作用
当我们数据变化 à 更新DOM的过程是 “异步的” 局部等待DOM更新后在执行一段代码 放入$nextTick()函数中
插槽
口诀: <slot>夹着内容默认显示内容, 如果不给插槽slot传东西, 则使用<slot>夹着的内容在原地显示
传入数据用props 传入标签就点用插槽 术语:对组件分发不同的标签的一种技术
使用 在 子组件中使用Slot标签占位 父组件上 使用子组件夹着的地方传入具体的标签替换到 slot上 如果父级不给子级传递东西 则slot标签夹着的内容在原地进行显示 直接在slot标签内 写好默认显示内容 当父级使用组件并为给我们传入具体标签或内容的时候
具名插槽 组件中遇到了多个 slot 使用 在slot标签上加name属性名 父组件中使用时候 子标签夹着template配合 v-slot:插槽名 使用 它会把 template夹着内容 配合 v-slot分发给 对应名字的 slot标签处 一个template对应一个插槽 子组件中标签内 可以写多个template v-slot: 可以简写成一个
作用域插槽
使用插槽是 想使用子组件内变量
子组件 在slot上 绑定自定义属性和子组件内的值 父组件在使用组建的时候 传入自定义标签 使用template 和V-solt=自定义变量名’ 里面定义多个:自定义属性 都可以拿到
子组件<slot name="container" :row="defaultObj">{{ defaultObj.defaultOne }}</slot>
父组件<template v-slot:container="scope"><p>不是默认内容
</p>{{ scope.row.defaultTwo}}</template>
黄色位置 即把名字得到 还有定义的属性把对象拿来使用
自定义指令
获取标签 扩展额外功能
全局注册-语法 Vue.directive(“指令名”, ,{inserted(el) { }}) el拿到使用这个指令的原生标签 使用的时候 v-指令名 directive("fofo", {inserted(el) {el.focus();}}); 局部注册
v-model作用
v-model是个语法他不发 VUE在解析这个指令时向标签内的value属性赋值给标签绑定input事件, 并把收到的值, 赋予给vue变量