需要安装准备好的底层环境:node环境,vue-cli脚手架
安装node:地址 node -v查看版本
安装vue-cli脚手架:
npm install -g @vue/cli 全局安装(不能创建vue 2.x项目)
npm install -g @vue/cli-init (作为桥接,创建vue 2.x项目)
创建项目:vue create 【项目名】
初始化:npm install
下载package.js里面的包和插件等,放置在node_modules中
开启服务:npm run serve
安装的库
npm install 指定的插件@4.1.0 --save
报错:Syntax Error: TypeError: this.getOptions is not a function
解决方案:less-loader 版本太高需要降低到 7版本
报错跨域问题:
解决:需要 import ‘./mock’,即将拦截的文件以及数据统一放到main.js中
el
作用:指定、设置,当前Vue实例所管理的视图。
注意:不能让el直接管理html或者body 报错!! mount->挂载
data
作用:指定、设置 当前Vue实例所用的数据。
特点:响应式数据(当数据变化时,视图中的数据会自动发生变化)
methos
作用:放置自定义函数。
注意:不推荐些箭头函数,因为箭头函数this指向的不是实例本身,即app本身
watch
作用:当被监测的数据发生变化时 会触发方法,要进行异步操作的时候。
<let a = [1,2,3];
let b = [0, ...a, 4];
b返回的数组为 [0,1,2,3,4],得出结论:展开运算符可以直接在数组内直接使用,同时可以生成一个新数组。
let obj = { a: 1, b: 2 };
let obj2 = { ...obj, c: 3 };
// { a:1, b:2, c:3 }
let obj3 = { ...obj, a: 3 }; // { a:3, b:2 }>
注意:展开运算符不能直接使用:
即:console.log(…person)//报错,展开运算符不能展开对象,需要使用{}进行包裹:因为console.log输出的是运算后的结果,即为表达式。
使用场景:字符串中需要包裹变量的时候
你输入的用户名是:${username.value},你输入的密码是${password.value}
简介:一个函数复合下面两个规范中的任何一个,那么函数就是高阶函数。
若A函数,接收的参数是一个函数,那么A就可以称之为高阶函数。
若A函数,调用的返回值依然是一个函数,那么A就可以称之为高阶函数。
常见的高阶函数
:Promise、setTimeout
函数的柯里化
:通过函数调用继续返回函数的方式,实现多次接受参数最后统一处理的函数编码形式
从数组第一个对象元素中提取某个属性,比如:err 对象中包含一个 errors 数组,errors 数组每一个对象都包含一个 msg 属性
err = {
errors: [
{
msg: 'this is a message'
}
]
}
快速的提取方法为:
const [{ msg }] = err.errors
或
const [ obj ] = err.errors
const { msg } = obj
如果不用解构写法为:
const msg = err.errors[0].msg
//模块引入
//方式一:
import m1 from './main.js'
//解构赋值形式
import {m1,m2} from './main.js'
//取别名的方式
import {m1 as guigu} from './main.js'
//模块导出
export let school = 'guigu'
export {
school,
school1
}
//默认导出
export default{
school,
school1
}
具体方式方法:见vue.js官网中的学习API中
v-taxt:更新标签中的内容
v-text和插值表达式的区别:
- v-text更新整个标签中的内容
- 插值表达式{{}}:更新标签中局部的内容
v-html:更新标签中的内容/标签(也可以替换标签中的全部内容)
注意事项:
- 可以渲染内容中的HTML标签
- 尽量避免使用,容易造成攻击
作用:绑定DOM事件监听器,并在时间被出发时执行一些JavaScript。
语法:v-on 简写为@
@事件名.修饰符 = ”methods中的方法名“
常用修饰符:事件修饰符,once和prevevt等。
注意:$event用来传递事件对象。
列表渲染:
语法:
v-for="item in 数组" v-for="(item,index) in 数组" // item指的时数据中每个元素的值,index指的是每个数字所在数组的索引、下标
对象渲染:
语法:
v-for="(item,index) in 对象"
注意事项:vue建议我们给每个循环遍历的标签li 加key属性,key属性值特点 要求是唯一值,key值为下标、索引,value值,key名
作用:vue渲染页面是,根据key的标识找到每一个元素,效率更高,关系到虚拟DOM的对比。
作用:动态绑定标签的任何属性,例如input 中的 value属性
场景:当标签属性值是不确定的是可以修改的
语法:v-bind:要绑定的属性名=“data中的数据”
简写:去掉v-bind,即:,例如:src/:id
//绑定class-对象:
<p v-bind:class="{active:a,left:b}">内容p>
data:{
a:ture,
b:false
}
//解析:通过动态来绑定class的类名
//绑定class-数组:
<p :class="[left,active]">内容p>
data:{
left:"a",
active:"b",
}
//解析:通过数组的方式,同时绑定多个类名。
//绑定style-对象
<p :style="{fontSize:a,color:b}">1236p>
data:{
a:"25px",
b:"#f5f5f5",
}
//绑定style-数组
//语法:数组语法,数组里面包含的是对象
<p :style="[a,b]">1236p>
data:{
a:{
'color':"#d00c0c"
},
b:{
'fontSize':'25px',
}
}
特点:双向数据绑定,数据发生变化可以更新到界面,通过界面可以更改数据,当在视图修改数据值时,data中的数据也会相应发生变化。
注意事项:v-model会忽略所有表单元素的value、checked、selected特性的初始值而总是将Vue实例的数据作为数据来源,应该在data选项中声明初始值。
表单元素的应用:
数据双向绑定实现的原理:
1.动态绑定数据,当data里面数据变化时,页面上的数据也会发生变化。
2.通过监听事件@input来触发事件,然后在事件中修改绑定的数据,即可实现数据的伪双向绑定。
场景:实现一个自定义v-mode的形式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Boi8gdwf-1619607904201)(img\1603104634638.png)]
v-if:
简介:根据表达式的值的 truthiness 来有条件地渲染元素。在切换时元素及它的数据绑定 / 组件被销毁并重建。
v-show:
简介:根据表达式之真假值,切换元素的 display
CSS property。在切换的时候,不会被销毁
当条件变化时该指令触发过渡效果。
keep-alive :
简介:等价于v-show,复杂的组件使用keepalive 简单的可以使用v-show来提高性能
场景:缓存组件,频繁切换,不需要重复渲染的情况,vue常用性能优化方案之一
简介:过滤器可以用在两个地方:双花括号插值和 v-bind 表达式 (后者从 2.1.0+ 开始支持)。
语法:
<p>处理后:{{msg | toUpper(200)} | toLower}</p>
//js
filters: {
toUpper(value,other) {
return value.toUpper()
},
toLower(value){
return value.toLowerCase()
}
}
解析:
1)传参数:
2)串联:
1)场景:当数据格式需要处理时(文本格式化)
2)分类:全局和局部(本地)
3)使用位置:{{}}和v-bind:属性=“”
1)全局过滤器:在newVue之前
简介:有的情况下,你仍然需要对普通 DOM 元素进行底层操作,这时候就会用到自定义指令。举个聚焦输入框的例子 。
**应用场景:**自定义指令获取 DOM 元素
语法:使用 directive 实例选项
//html <input v-focus> //js directives: { focus: { // 指令的定义 inserted: function (el) { el.focus() } } }
案例代码:实现一个自定义v-mode的形式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EQOzuQiT-1619607904206)(img\1603104634638.png)]
简介:一个指令定义对象可以提供如下几个钩子函数 (均为可选)
bind
:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
inserted
:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
update
:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。
componentUpdated
:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
unbind
:只调用一次,指令与元素解绑时调用。
el
:指令所绑定的元素,可以用来直接操作 DOM.
binding
:一个对象,包含以下 property:
name
:指令名,不包括 v-
前缀。value
:指令的绑定值,例如:v-my-directive="1 + 1"
中,绑定值为 2
。oldValue
:指令绑定的前一个值,仅在 update
和 componentUpdated
钩子中可用。无论值是否改变都可用。expression
:字符串形式的指令表达式。例如 v-my-directive="1 + 1"
中,表达式为 "1 + 1"
。arg
:传给指令的参数,可选。例如 v-my-directive:foo
中,参数为 "foo"
。modifiers
:一个包含修饰符的对象。例如:v-my-directive.foo.bar
中,修饰符对象为 { foo: true, bar: true }
。vnode
:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。
oldVnode
:上一个虚拟节点,仅在 update
和 componentUpdated
钩子中可用
场景:在Vue操作dom元素.
生命周期函数:mounted获取要操作的dom元素this.$refs.ref属性值。
场景:vue是异步渲染的框架,react也是,data改变之后,dom不会立刻渲染,$nextTick会在dom渲染之后被触发。
作用:以获取最新dom节点。
案例代码:
this.$nextTick(()=>{ //在节点渲染完成后才会调用
console.log(this.$refs.ulDemo)
})
简介:在模板中可以把computed当作data属性来使用,computed是一个对象,每个键是计算属性的值,注意:computed有缓存,data不变则不会重新计算。
使用场景:表达式、当数据A的逻辑很复杂时,把A这个数据卸载计算属性中;或者data中的数据b依赖了数据a
案例代码:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-08Lnw8Nf-1619607904208)(img\1602805842921.png)]
解析:get()在数据绑定后,相当于直接赋值给模板中。
set()会在数据改变时触发(数据绑定必须为双向的)
简介:watch是vue内部提供的一个用于侦听功能的更通用的方法,其用来响应数据的变化,通过特定的数据变化驱动一些操作。
解析:newValue:监听新的变化值,oldValue上一次的值
watch:{
message(newValue,oldValue1){
console.log(newValue,oldValue)
this.message = newValue
}
如果对象内有多个属性,并采用以下写法,则对象内每个属性都会被侦听,每个属性的变化都会执行一次侦听操作
解析:侦听普通变量的变化是使用以上方法,当侦听的某个变量值是对象时则不起作用,这时需要使用deep深度监听。当未设置immediate或者immediate的值为false时,被侦听的变量在页面初次加载时第一次绑定值的时候,并不会执行监听操作;但是当设置了immediate的值为true时,则会立刻执行一次监听操作。
'deepMessage.a.b':{
handler:'handerFun',
deep:true, //是否深度监听
immediate:true //监听第一次
}
deepMessage:{
handler:'handerFun',
deep:true, //是否深度监听
immediate:true //监听第一次
}
lastMessage:[
{
handler:'lastFun'
},
'lastFun1',
function(value){
console.log(value)
}
]
建议:在实际开发中,尽量可能使用各种第三方组件
简介:通过插槽分发内容,将
元素作为承载分发内容的出口。插槽内可以包含任何模板代码,包括 HTML,甚至是组件。
场景:和 HTML 元素一样,我们经常需要向一个组件传递内容。
基础案例:
//插入文本
<navigation-link url="/profile">
Your Profile
navigation-link>
//插入HTML
<navigation-link url="/profile">
<span class="fa fa-user">span>
Your Profile
navigation-link>
//插入组件
<navigation-link url="/profile">
<font-awesome-icon name="user">font-awesome-icon>
Your Profile
navigation-link>
//navigation-link组件里面
<a v-bind:href="url" class="nav-link">
<slot>slot>
a>
解析:slot会被替换成Your Profile”。
注意事项:如果
的 template
中没有包含一个
元素,则该组件起始标签和结束标签之间的任何内容都会被抛弃。
场景:在插槽使用数据时。
注意事项:该插槽跟模板的其它地方一样可以访问相同的实例 property (也就是相同的“作用域”),而不能访问
的作用域。例如 url
是访问不到的:
案例代码:
<navigation-link url="/profile">
Logged in as {{ user.name }}
navigation-link>
<navigation-link url="/profile">
Clicking here will send you to: {{ url }}
navigation-link>
//父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。
作用:设置具体的后备 (也就是默认的) 内容是很有用的,它只会在没有提供内容的时候被渲染。
案例:
<button type="submit">
<slot>Submitslot>
button>
//现在当我在一个父级组件中使用 <submit-button> 并且不提供任何插槽内容时:
<submit-button>submit-button>
//但是如果我们提供内容:
<submit-button>
Save
submit-button>
场景:需要使用多个插槽的时候。
特别注意:v-slot
只能添加在 上
缩写:参数之前的所有内容 (v-slot:
) 替换为字符 #
。例如 v-slot:header
可以被重写为 #header
案例:
<div class="container">
<header>
<slot name="header">slot>
header>
<main>
<slot>slot>
main>
<footer>
<slot name="footer">slot>
footer>
div>
解析:一个不带 name
的
出口会带有隐含的名字“default”。
在向具名插槽提供内容的时候,我们可以在一个 元素上使用
v-slot
指令,并以 v-slot
的参数的形式提供其名称:
元素中的所有内容都将会被传入相应的插槽。任何没有被包裹在带有
v-slot
的 中的内容都会被视为默认插槽的内容。
如果你希望更明确一些,仍然可以在一个 中包裹默认插槽的内容:
<base-layout>
<template v-slot:header>
<h1>Here might be a page titleh1>
template>
<template v-slot:default>
<p>A paragraph for the main content.p>
<p>And another one.p>
template>
<template v-slot:footer>
<p>Here's some contact infop>
template>
base-layout>
作用:在父容器内,在当前组件上使用当前组件(即子组件)内的数据(让插槽内容能够访问子组件中才有的数据)。
**解决方案:**为了让 user
在父级的插槽内容中可用,我们可以将 user
作为
元素的一个 attribute 绑定上去:
<span>
<slot v-bind:user="user">
{{ user.lastName }}
slot>
span>
//父容器内的组件
<current-user>
<template v-slot:default="slotProps">
{{ slotProps.user.firstName }}
template>
current-user>
解析:绑定在
元素上的 attribute 被称为插槽 prop。现在在父级作用域中,我们可以使用带值的 v-slot
来定义我们提供的插槽 prop 的名字。我们选择将包含所有插槽 prop 的对象命名为 slotProps
,但你也可以使用任意你喜欢的名字。default
为默认的插槽内容(数据)
出现多个插槽时:
<current-user>
<template v-slot:default="slotProps">
{{ slotProps.user.firstName }}
template>
<template v-slot:other="otherSlotProps">
...
template>
current-user>
简介:多个组件通过同一个挂载点进行组件的切换,is的值是哪个组件的名称,那么页面就会显示哪个组件。
场景:需要根据数据,动态渲染的场景,组件类型不确定。
使用方式:使用 is
attribute 来切换不同的组件.
案例:希望那些标签的组件实例能够被在它们第一次被创建的时候缓存下来,可以用一个
元素将其动态组件包裹起来
<keep-alive>
<component v-bind:is="currentTabComponent">component>
keep-alive>
//currentTabComponent 组件名
简介:Vue 允许你以一个工厂函数的方式定义你的组件,这个工厂函数会异步解析你的组件定义。Vue 只有在这个组件需要被渲染的时候才会触发该工厂函数,且会把结果缓存起来供未来重渲染。
场景:import函数,按需加载,异步加载大组件,vue常用性能优化方案之一。
components: {
FromDemo: () => import('./NextTick')
}
//组件别名:FromDemo;引入的组件import('./NextTick')
解析:组件的关系 父子 爷孙 兄弟
**解析:**父子关系,需要在父组件中引入子组件,此时组件间才算是父子关系。
使用的方式:props — this.$emit
//script
//导入子组件
import comChild from './comChild'
//注册子组件
components:{
comChild
}
//templated
//使用已经注册的组件
<comChild />
父->子: 利用的是 v-bind 的动态数据绑定,以及props来接收数据。
步骤:
1.向子组件传递数据:
语法:
解析:list为传递数据的 标识名,arr为传递的数据
2.在子组件中取出数据:
语法:
// props:['list'] //第一种写法 props:{ list:{ type:Array, //设置数据类型 default(){ return [] //给默认值 } } }
解析:props的用法与data中的数据一致。
子->父: 利用的是this的实例方法**$emit** 来发送数据,以及**v-on(@)**来监听事件的触发
步骤:
1.向子组件中使用this.$emit方法,传递数据:
语法:this.$emit(‘add’,this.num)
解析:该方法一般放置在函数里面,该函数被触发时,即可向父级发送数据。add:数据的标识名,this.num:传递的数据
//template <button @click="fan">发送数据</button> //script methods:{ fan(){ this.$emit('add',this.num) } }
2.父组件中取出数据:
解析:使用v-on(@):来监听标识名,一旦被触发,则会执行add1函数,并传递一个实参。
语法:
//template <comChild @add="add1"/> //script add1(num){ console.log(num) num = this.number++ this.list.push({ id:num,title:`标题${num}` }) }
解析:主要是用来处理非父子组件间的通信:爷孙组件、兄弟组件 (未解决)
**本质:**中央事件总线(通俗讲就是:eventBus事件车)的实质就是创建一个vue实例,通过一个空的vue实例作为桥梁实现vue组件间的通信。它是实现非父子组件通信的一种解决方案。
注意事项:
//vue2.x中 引入vue并导出
import Vue from 'vue'
export default new Vue();
//vue3.x中 引入vue并导出
//Vue3项目注册全局组件时使用Vue时报错"export 'default' (imported as 'Vue') was not found in 'vue',
//原因:脚手架版本太高,需要卸载现在的脚手架版本,重新安装
npm uninstall -g @vue/cli
npm install -g @vue/cli@3.0.4
import Vue from 'vue'
export const eventBus = new Vue() //es6 新语法
步骤一:在main.js(或创建新的js文件)中创建Vue实例,作为桥梁实现vue组件的通信.
代码:
import Vue from 'vue' export default new Vue();//暴露一个实例
步骤二:使用$emit发送数据到其它组件,发送端需要设置在页面销毁前将 该通信进行销毁。
代码:
//引入Vue实例,同时给一个别名 import eventBus from '../../event' //触发事件的函数 messageSister(){ eventBus.$emit('brotherSaid','妈妈说,该做作业了') } //销毁 $off beforeDestroy(){ eventBus.$off('brotherSaid','妈妈说,该做作业了') }
步骤三:设置接收端 $on,兄弟组件触发了‘brotherSaid’事件,既可以响应接受到了数据。
代码:
//组件生命周期created,此时可以接受到数据 created(){ eventBus.$on('brotherSaid', (message) => { //注意先定义好接收数据:当前组件数据中 fromBrother:'' console.log(message) }) }
解析:‘brotherSaid’:发送的一个共同的属性名,只有使用相同的属性名才能监听获取到数据
解析:该方法数据只能从顶层向下面的子代组件传输数据,不能向上传输,以此具有一定的局限性。使用的方法:provide()和inject
组件结构:
//简写
<com1>
<com2>
<com3>com3>
com2>
com1>
//该代码显示com3是com1的孙辈,因此为嵌套关系
步骤一:在顶层(发送数据端)编辑好发送的数据内容,通过一个自定义的标识名。
代码:
provide(){ return{ elparrent:this } } //解析:provide使用的方法名;elparrent发送端的标识名,用于给接送端传递数据;this为发送的数据,是当前的vue实例,能够调用到所有的数据(函数、数据)
**步骤二:**在接受端接受数据,使用的是inject实例选项。
代码:
inject:['elparrent'] //使用时 changeHander(){ this.elparrent.changeFun() } //解析:inject实例选项,elparrent发送端的标识名,使用this来使用即可
3.1.父组件:console.log(this.$children[0].name); 使用 来进行访问,其中[0]为该组件中的第一个子组件,.name为子组件中的数据
3.2.子组件:const {number} = this.$parent; 原理与取子组件的数据一致
4.1.在 爷组件向父组件传递数据的方式 与 父子组件间数据传递一致 ,爷向孙组件传递数据时,父组件起到了一种 数据中介的作用,所以,在父组件中,数据的传输为:<孙组件 v-bind='$attrs'>,孙组件使用数据可以为 {{$attrs.user}},
单页应用SPA
原理:前后端分离+前端路由,前端路由:根据不同的标识去渲染不同的组件。
好处:
1.用户操作更方便 2.完全的前端组件化
缺点:
1.首次加载大量资源 2.对搜索引擎SEO不友好 3.开发难度相对较高。
router功能作用:
实现单页面的切换
路由携带参数
路由的导航守卫
路由进行数据预载(进入组件前就请求获得数据)
路由:to属性
介绍:用于指定路由路径,以及传递参数
例子:Go to Foo
hash模式(默认) 例如:http://abc.com/#/user/10
h5 history模式 例如:http://abc.com/user/20 需要server端支持
注意:history有如下问题
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RfE3sttG-1619607904213)(img\1602245274479.png)]
<script src="https://unpkg.com/vue/dist/vue.js">script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js">script>
<div id="app">
<h1>Hello App!h1>
<p>
<router-link to="/foo">Go to Foorouter-link>
<router-link to="/bar">Go to Barrouter-link>
p>
<router-view>router-view>
div>
// 0. 如果使用模块化机制编程,导入Vue和VueRouter,要调用 Vue.use(VueRouter)
<!---- 下面这部分的内容 一般生成一个独立的js文件
// 1. 定义 (路由) 组件。
// 可以从其他文件 import 进来 (常用)
const Foo = { template: 'foo' }
const Bar = { template: 'bar' }
// 2. 定义路由
// 每个路由应该映射一个组件。 其中"component" 可以是
// 通过 Vue.extend() 创建的组件构造器,
// 或者,只是一个组件配置对象。
// 我们晚点再讨论嵌套路由。
const routes = [
{ path: '/foo', component: Foo },
{ path: '/bar', component: Bar }
]
// 3. 创建 router 实例,然后传 `routes` 配置
// 你还可以传别的配置参数, 不过先这么简单着吧。
const router = new VueRouter({
routes // (缩写) 相当于 routes: routes
})
--------------------------->
// 4. 创建和挂载根实例。
// 记得要通过 router 配置参数注入路由,
// 从而让整个应用都有路由功能
const app = new Vue({
router
}).$mount('#app')
// 现在,应用已经启动了!
案例代码:
const User = {
template: 'User'
}
const router = new VueRouter({
routes: [
// 动态路径参数 以冒号开头
{ path: '/user/:id', component: User }
]
})
解析:一个“路径参数”使用冒号 : 标记。当匹配到一个路由时,参数值会被设置到 this.$route.params
属性名 | 类型 | 作用 |
---|---|---|
$route.path | string | 字符串,对应当前路由的路径,总是解析为绝对路径,如 "/foo/bar" 。 |
$route.params | Object | 一个 key/value 对象,包含了动态片段和全匹配片段,如果没有路由参数,就是一个空对象。 |
$route.query | Object | 一个 key/value 对象,表示 URL 查询参数。例如,对于路径 /foo?user=1 ,则有 $route.query.user == 1 ,如果没有查询参数,则是个空对象。 |
$route.hash | string | 当前路由的 hash 值 (带 # ) ,如果没有 hash 值,则为空字符串。 |
$route.fullPath | string | 完成解析后的 URL,包含查询参数和 hash 的完整路径。 |
$route.redirectedFrom | 如果存在重定向,即为重定向来源的路由的名字。(参阅重定向和别名) | |
$route.name | 当前路由的名称,如果有的话。(查看命名路由) |
使用场景:相同路由匹配多个路由组件
案例代码:
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
export default router = new Router({
routes: [
{
path: '/user/:id',
component: User,
children: [
{
// 当 /user/:id/profile 匹配成功,
// UserProfile 会被渲染在 User 的 中
path: 'profile',
component: UserProfile
},
{
// 当 /user/:id/posts 匹配成功
// UserPosts 会被渲染在 User 的 中
path: 'posts',
component: UserPosts
}
]
}
]
})
解析:children
配置就是像 routes
配置一样的路由配置数组,所以呢,你可以嵌套多层路由。
介绍:实现导航链接的方式:
,还可以借助 router 的实例方法。
声明式 | 编程式 |
---|---|
|
$router.push(...) |
push跳转会有历史记录,repalce没有历史记录,没有返回上一步。
声明式 | 编程式 |
---|---|
|
$router.replace(...) |
案例:
this.$router.push('/demo')
this.$router.push({path:'/demo'})
this.$router.push({name:'demo'})
//放置在函数中
介绍:强制修改url标识 重新发起请求,
例如:
path:’/’ 希望渲染首页 -> comA组件 ;
{patn:‘/’,redirect:{name/path:值}}
:to="{name:‘routerdemo2’,query:{id:‘1234’}}"
:to="{name:‘routerdemo1’,params:{name1:‘张三’}}"
注意:params传递参数不能刷新,参数在url上显示;query是可以的,参数在url上显示;使用path跳转不能使用params传参。
案例:
this.$router.push({
path:'/demo2',
query:{
id:'6666',
name:'张三'
}
})
**场景:**检测用户登录状态 检测用户有没有账号
router.beforeEach((to,from,next) =>{
// console.log(to) //当前路由对象
// console.log(from)//上一个路由对象
// console.log(next)//跳到下一个路由守卫
next() //必须要有
})
1.在Vue中发送网络请求
1)接口服务器
2)明确接口规则是什么
3)postman->测试接口
2.json-server(json服务器):把json文件转换为服务器接口
1.npm i -g json-server(不行,添加环境变量,得下载nodejs)
2.新建路径(自定义)已经db.json(文件中添加https://github.com/typicode/json-server网址所要求)
3.在代码目录下新建了server文件夹->db.json
4.以管理员身份下打开 powershell,运行json-server --watch db.json,不行则要蛇形策略更改
5.端口号冲突:json-server --watch --port 3001 db.json
3.RESTFulJ接口规则
1.json-server工具应用了RESTFul接口规则
2.特点:只需要关心请求方式是什么,而不需要关注标识url
3.post增加 delete删除/1 put修改/1 get查询/1 模糊搜索?name_like=关键字
4.axios介绍
axios不是vue插件 可以在客户端和服务端使用 不支持jsonp
5.jsonp:跨域 原型
8种解决方案:1.jsonp -> script src="" -> callback()
1.使用前提:接口要支持jsonp
2.get
2.服务端处理 3.iframe src=“xxx.html”+location.hash
4.设置代理 转发 5.iframe+window.name 6.
6.异步操作
要在异步操作的外部获取到异步操作的结果->异步编程->callback->修改axios中的.then()方法的源码(不合理)
异步操作场景:1.ajax 2.定时器 3.点击事件 4.数据库操作
特点:代码不等待 后续代码会继续执行
调用时间:Vue实例刚刚被创建好,同时事件和生命周期方法初始化完毕后,开始调用。
特点:这时data和methods属性还没初始化完毕
调用时间:data和methods属性刚初始化完毕。
特点:最早可以访问数据(data)和方法(methos)的生命周期。
调用时间:虚拟DOM已经创建完毕,但还没渲染、挂载到页面。
调用时间:此时vue已经完成了模板的渲染。
特点:可以拿到页面上的数据。
调用时间:当数据发生变化时
特点:只有保存的数据改变的时候,才会被调用,此时页面还没更新
调用时间:实例数据更新到页面,并完成的时候
特点:数据和页面都同步更新,保持一致
调用时间:keep-alive组件激活时调用。类似v-show.该钩子在服务器端渲染期间不被调用
调用时间:当前组件将要销毁
特点:用于销毁一些需要一致循环的函数,或需要获取该组件中不存在元素的函数判断,例如定时器等;最后能够访问组件数据和方法的函数。
调用时间:当前组件已经被销毁了
特点:不要在这个生命周期中操作组件和数据
挂载: beforeCreate => created => beforeMount => mounted
更新: beforeUpdate => updated
销毁: beforeDestroy => destroyed
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。
它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
Vuex 也集成到 Vue 的官方调试工具 devtools extension (opens new window),提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能
Vuex有五个核心概念,state, getters, mutations, actions, modules。
状态管理: 简单理解就是统一管理和维护各个vue组件的可变化状态(你能够理解成vue组件里的某些data)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AMddDNuE-1619607904217)(img\1602244775741.png)]
介绍:每一个 Vuex 应用的核心就是 store(仓库)。“store”基本上就是一个容器,它包含着你的应用中大部分的状态 (state)。Vuex 和单纯的全局对象有以下两点不同:
Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用.
基本使用:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
count: 0
},
getters:{
getCount(state){
return state.mycount
}
},
mutations: {
increment (state) {
state.count++
}
}
})
介绍:state为一个对象,包含了全部的应用层级状态,作为一个“唯一数据源 (SSOT (opens new window))”而存在。这也意味着,每个应用将仅仅包含一个 store 实例。单一状态树让我们能够直接地定位任一特定的状态片段,在调试的过程中也能轻易地取得整个当前应用状态的快照。
案例取值:
//方式一:
//直接取值,相当于data
this.$store.state.属性名
//取模块comm中的数据
this.$store.state.comm.属性名
//方式二:
this.$store.state['属性名']
//方式三:
//在computed中先做处理,在取值
import {mapState} from 'vuex'
computed:{
...mapState(['mycount'])
}
<p>mycount:{{mycount}}</p>
介绍:在 store 中定义“getter”(可以认为是 store 的计算属性)。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
案例取值:
//方式一:
//直接取值,相当于data
this.$store.getters.属性名
//方式二:
this.$store.getters['属性名']
//取模块comm中getter中的数据,分模块时必须使用
this.$store.getters['comm/getList']
//方式三:
//在computed中先做处理,在取值
import {mapGetters} from 'vuex'
computed:{
...mapGetters(['getCount'])
//取模块comm中getter中的数据
...mapGetters('comm',['getList'])
}
<p>getCount:{{getCount}}</p>
介绍:更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。mutation必须是同步函数。
Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数:
案例取值:
//方式一:
//触发一个类型为 increment 的 mutation 时,使用commit
this.$store.commit('事件名',参数)
//取模块comm中mutations 中的数据
this.$store.commit('comm/increment',10)
//方式二:
//在computed中先做处理,在取值
import {mapGetters} from 'vuex'
computed:{
...mutations(['事件名'])
}
<button @click="事件名">添加</button>
既然 Vuex 的 store 中的状态是响应式的,那么当我们变更状态时,监视状态的 Vue 组件也会自动更新。这也意味着 Vuex 中的 mutation 也需要与使用 Vue 一样遵守一些注意事项:
使用 Vue.set(obj, 'newProp', 123)
, 或者
以新对象替换老对象。例如,利用对象展开运算符 (opens new window)我们可以这样写:
state.obj = { ...state.obj, newProp: 123 }
Action 类似于 mutation,不同在于:
案例代码:
//在methods调用
//Action 通过 store.dispatch 方法触发:
decrement(){
this.$store.dispatch('research',2)
//取模块comm中action中的数据
this.$store.dispatch('comm/recrement',2)
}
//在vuex中声明
mutations:{
research(state,num){
state.mycount -= num
}
},
actions:{
research({commit},num){
return commit('research',num)
}
}
解析:commit来调用
解决的问题:由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。
Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:
案例:
const moduleA = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态
//comm.js
const actions ……(下面)
export default {
state,
getters,
mutations,
actions,
namespaced:true //模块化
}
//可以通过添加 namespaced: true 的方式使其成为带命名空间的模块。
//全局性的vuex
import comm from './modules/comm'
export default new Vuex.Store({
modules:{
comm //进行导入
},
……
介绍:vue.js中有两个核心功能:响应式数据绑定,组件系统。主流的mvc框架都实现了单向数据绑定,而双向绑定无非是在单向绑定基础上给可输入元素添加了change事件,从而动态地修改model和view。
MVC模式将软件分为下面三个部分
1.视图(View):用户界面
2.控制器(Controller):业务逻辑
3.模型(Model):数据保存
MVC各个部分之间通信的方式如下:
1.视图传送指令到控制器
2.控制器完成业务逻辑后要求模型改变状态
3.模型将新的数据发送到视图,用户得到反馈
示意图如下:
以上所有通信都是单向的。接受用户指令的时候,MVC有两种方式,一种是通过视图接受指令,然后传递给控制器。另一种是用户直接给控制器发送指令。
实际使用中可能更加灵活,下面是以Backbone.js为例说明。
1.用户可以向视图(View)发送指令(DOM事件),再由View直接要求Model改变状态。
2.用户也可以向Controller发送指令(改变URL触发hashChange事件),再由Controller发送给View。
3.Controller很薄,只起到路由作用,而View非常厚,业务逻辑都放在View。所以Backbone索性取消了Controller,只保留了Router(路由器)
MVC模式体现了“关注点分离”这一设计原则,将一个人机交互应用涉及到的功能分为三部分,Model对应应用状态和业务功能的封装,可以将它理解为同时包含数据和行为的领域模型,Model接受Controller的请求并完成相应的业务处理,在应用状态改变的时候可以向View发出通知。View实现可视化界面的呈现和用户的交互操作,VIew层可以直接调用Model查询状态,Model也可以在自己状态发生变化的时候主动通知VIew。Controller是Model和View之间的连接器,用于控制应用程序的流程。View捕获用户交互操作后直接发送给Controller,完成相应的UI逻辑,如果涉及业务功能调用Controller会调用Model,修改Model状态。Controller也可以主动控制原View或者创建新的View对用户交互予以响应。
MVP模式将Controller改名为Presenter,同时改变了通信方向,如下图:
1.各部分之间的通信都是双向的。
2.视图(View)和模型(Model)不发生联系,都是通过表现(Presenter)传递
3.View非常薄,不部署任何业务逻辑,称为被动视图(Passive View),即没有任何主动性,而Presenter非常厚,所有逻辑都这里。
MVP适用于事件驱动的应用架构中,如asp.net web form,windows forms应用。
MVVM模式将Presenter层替换为ViewModel,其他与MVP模式基本一致,示意图如下:
它和MVP的区别是,采用双向绑定,视图层(View)的变动,自动反映在ViewModel,反之亦然。Angular和Vue,React采用这种方式。
MVVM的提出源于WPF,主要是用于分离应用界面层和业务逻辑层,WPF,Siverlight都基于数据驱动开发。
MVVM模式中,一个ViewModel和一个View匹配,完全和View绑定,所有View中的修改变化,都会更新到ViewModel中,同时VewModel的任何变化都会同步到View上显示。之所以自动同步是ViewModel中的属性都实现了observable这样的接口,也就是说当使用属性的set方法,会同时触发属性修改的事件,使绑定的UI自动刷新。
响应式数据绑定:
组件系统:
1.关于登录页面的验证:
**
MVC模式将软件分为下面三个部分
1.视图(View):用户界面
2.控制器(Controller):业务逻辑
3.模型(Model):数据保存
MVC各个部分之间通信的方式如下:
1.视图传送指令到控制器
2.控制器完成业务逻辑后要求模型改变状态
3.模型将新的数据发送到视图,用户得到反馈
示意图如下:
[外链图片转存中…(img-64IyTq7b-1619607904219)]
以上所有通信都是单向的。接受用户指令的时候,MVC有两种方式,一种是通过视图接受指令,然后传递给控制器。另一种是用户直接给控制器发送指令。
实际使用中可能更加灵活,下面是以Backbone.js为例说明。
1.用户可以向视图(View)发送指令(DOM事件),再由View直接要求Model改变状态。
2.用户也可以向Controller发送指令(改变URL触发hashChange事件),再由Controller发送给View。
3.Controller很薄,只起到路由作用,而View非常厚,业务逻辑都放在View。所以Backbone索性取消了Controller,只保留了Router(路由器)
MVC模式体现了“关注点分离”这一设计原则,将一个人机交互应用涉及到的功能分为三部分,Model对应应用状态和业务功能的封装,可以将它理解为同时包含数据和行为的领域模型,Model接受Controller的请求并完成相应的业务处理,在应用状态改变的时候可以向View发出通知。View实现可视化界面的呈现和用户的交互操作,VIew层可以直接调用Model查询状态,Model也可以在自己状态发生变化的时候主动通知VIew。Controller是Model和View之间的连接器,用于控制应用程序的流程。View捕获用户交互操作后直接发送给Controller,完成相应的UI逻辑,如果涉及业务功能调用Controller会调用Model,修改Model状态。Controller也可以主动控制原View或者创建新的View对用户交互予以响应。
MVP模式将Controller改名为Presenter,同时改变了通信方向,如下图:
[外链图片转存中…(img-B1xfXufM-1619607904221)]
1.各部分之间的通信都是双向的。
2.视图(View)和模型(Model)不发生联系,都是通过表现(Presenter)传递
3.View非常薄,不部署任何业务逻辑,称为被动视图(Passive View),即没有任何主动性,而Presenter非常厚,所有逻辑都这里。
MVP适用于事件驱动的应用架构中,如asp.net web form,windows forms应用。
MVVM模式将Presenter层替换为ViewModel,其他与MVP模式基本一致,示意图如下:
[外链图片转存中…(img-vGVko23f-1619607904222)]
它和MVP的区别是,采用双向绑定,视图层(View)的变动,自动反映在ViewModel,反之亦然。Angular和Vue,React采用这种方式。
MVVM的提出源于WPF,主要是用于分离应用界面层和业务逻辑层,WPF,Siverlight都基于数据驱动开发。
MVVM模式中,一个ViewModel和一个View匹配,完全和View绑定,所有View中的修改变化,都会更新到ViewModel中,同时VewModel的任何变化都会同步到View上显示。之所以自动同步是ViewModel中的属性都实现了observable这样的接口,也就是说当使用属性的set方法,会同时触发属性修改的事件,使绑定的UI自动刷新。
响应式数据绑定:
组件系统: