style
绑定对象语法:v-bind:style="{color:activeColor,fontSize:fontSize+'px'}"
vue组件
全局组件和局部组件
父子组件通讯-数据传递
Slot
Vue-router
什么是前端路由:就是根据不同的url地址展示不同的内容或页面
vue-router
用来构建spa
或者this.$router.push({path:''})
动态路由匹配
嵌套路由
编程式路由
命名路由和命名视图
什么是动态路由匹配
示例:
import GoodsList from './../views/GoodsList'
Vue.use(Router)
export default new Router({
routers: [
{
path: '/goods/:goodsId',
name: 'GoodsList',
component: GoodsList
}
]
})
{{$route.params.goodsId}}
什么是嵌套路由
// App.vue
import GoodsList from './../views/GoodsList'
import Title from '@/views/Title'
import Image from '@/views/Image'
Vue.use(Router)
export default new Router({
routers: [
{
path: '/goods',
name: 'GoodsList',
component: GoodsList,
children: [
{
path: 'title',
name: 'title',
component: Title
},
{
path: 'img',
name: 'img',
component: Image
}
]
}
]
})
{{$route.params.goodsId}}
显示商品标题
显示图片
什么是编程式路由
通过js来实现页面的跳转。
$router.push("name")
$router.push({path:"name"})
$router.push({path:"name?a=123"})或者$router.push({path:"name",query:{a:123}})
$router.go(1)
import GoodsList from './../views/GoodsList'
import Title from '@/views/Title'
import Image from '@/views/Image'
import Cart from '@/views/Cart'
Vue.use(Router)
export default new Router({
routers: [
{
path: '/goods',
name: 'GoodsList',
component: GoodsList,
children: [
{
path: 'title',
name: 'title',
component: Title
},
{
path: 'img',
name: 'img',
component: Image
}
]
},
{
path: '/cart',
component: Cart
}
]
})
{{$route.params.goodsId}}
显示商品标题
显示图片
购物车
跳转购物车
...
methods: {
jump() {
this.$router.push("/cart");
// ({path: '/cart?id=123'});
}
}
命令路由和命名视图
给路由定义不同的名字,根据名字进行匹配
给不同的router-view
定义名字,通过名字进行对应组件的渲染
跳转到购物车页面
跳转到购物车页面
路由:
{
path: '/cart/:cartId",
name: 'cart',
component: Cart
}
app.vue代码如下:
router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import GoodsList from './../views/GoodsList'
import Title from '@/views/Title'
import Image from '@/views/Image'
import Cart from '@/views/Cart'
Vue.use(Router);
export default new Router({
routers: {
{
path: '/',
name: 'GoodsList',
components: {
default: GoodsList,
title: Title,
img: Image
}
},
{
path: '/cart/:cartId',
name: 'cart',
components: Cart
}
}
})
Vue-resource和Axios
下载安装方式:
npm install vue-ressource -save
vue-resource
的请求api
是按照rest
风格设计的,提供7个请求api:
get(url, [options])
head(url, [options])
delete(url, [options])
jsonp(url, [options])
post(url, [body], [options])
put(url, [body], [options])
patch(url, [body], [option])
全局拦截器interceptors
Vue.http.interceptors.push{(request, next) => {
// 请求发送前的处理逻辑
next((response) => {
// 请求发送后的处理逻辑
return response
})
})
vue-resource.html(全局拦截器)
mounted() {
Vue.http.interceptors.push(function(request,next){
next(function(response){
return response;
});
});
}
axios的使用
npm install axios -save
示例:
function getUserAccount(){
return axios.get('/user/12345');
}
function getUserPermissions(){
return axios.get('/user/12345/permissions');
}
axios.all([getUserAccount(), getUserPermissions()])
.then(axios.spread(function(acct, perms){
}));
mounted: function(){
axios.interceptors.request.use(function(config){
return config;
})
axios.interceptors.response.use(function(response){
return response;
})
}
ES6常用命令
函数的Rest参数和扩展,Promise使用,module.exports
和es6 import/export
的使用
let checkLogin = function () {
return new Promise(function(resolve,reject){
let flag = document.cookie.indexOf("userId") > -1 ? true:false
if(flag) {
resolve({
status: 0,
result: true
})
}else{
reject("error");
}
})
};
checkLogin().then(function(res){
if(res.status==0){
console.log("login success");
}
}).catch((error)=>{
console.log(`error:${error}`);
})
一旦有了名字就要大块来接收
export let sum = (x,y)=>{
return x+y;
}
export let minus = (m,n) => {
return m-n;
}
import {sum, minus} from './util'
sum()
console.log(`sum:${sum(1,2)}`);
import * as util from './util'
// util.sum(1,2)
AMD,CMD,CommonJS和ES6
AMD
是RequireJS
在推广过程中对模块定义的规范化产出
CMD
是SeaJS
在推广过程中对模块定义的规范化产出
CommonJS
规范-module.exports
示例:
exports.area = function(r){
return Math.PI * r * r;
};
脚手架
Vue基础:环境搭建,模板,计算属性,类与样式,条件,列表渲染,事件处理,深入了解组件,路由基础,Vuex基础。
vue-cli@3
[email protected]
// 第一种搭建
npm install -g @vue/cli
// 第二种搭建
yarn global add @vue/cli
v-bind缩写
// 完整语法
...
// 缩写
...
v-on缩写
// 完整语法
...
// 缩写
...
自定义指令
声明自定义指令的名称,通过vue.directive
声明,设置钩子函数,在什么时机做什么事情:
// 注册一个全局自定义指令 v-focus
Vue.directive('focus', {
// 当被绑定的元素插入到DOM中时
inserted: function(el){
// 聚焦元素
el.focus()
}
})
钩子函数
一个指令定义对象可以提供如下几个钩子函数:
(初始化的操作) bind
,只调用一次,指令第一次绑定到元素时调用,在这里可以进行一次性的初始化设置。
inserted
,被绑定元素插入父节点时调用,(仅保证父节点存在,但不一定已被插入文档中)。
update
,所在组件的VNode
更新时调用,但是可能发生在其子VNode
更新之前。指令的值可能发生了改变,也可能没有,但是你可以通过比较更新前后的值来忽略不必要的模板更新。
componentUpdated
,指令所在组件的VNode
及其子VNode
全部更新后调用。
unbind
,只调用一次,指令与元素解绑时调用。
指令钩子函数会被传入以下参数
el
,指令所绑定的元素,可以用来直接操作DOM
。
binding
,一个对象,包含以下属性:
name
,指令名,不包含v-
前缀
value
,指令的绑定值,例如,v-my-directive="1+1"
中,绑定值为2
oldValue
,指令绑定的前一个值,仅在update
和componentUpdated
钩子中可用,无论值是否改变都可用。
expression
,字符串形式的指令表达式,例如v-my-directive="1+"
中,表达式为"1+1"
arg
,传给指令的参数,可选。例如v-my-directive:foo
中,参数为"foo"
modifiers
,一个包含修饰符的对象,例如:v-my-directive.foo.bar
中,修饰符对象为{foo:true,bar:true}
vnode
,vue
编译生成的虚拟节点。
oldVnode
,上一个虚拟节点,仅在update
和componentUpdated
钩子中可用。
除了el
外,其它参数都应该是只读的,切勿进行修改。如果需要在钩子之间共享数据,建议通过元素的dataset
来进行。
计算属性
示例:
{{message}}
{{reversedMessage}}
应用场景:具有依赖关系的数据监听。
事件
事件的定义以及缩写
事件传参和事件对象
快速结合键盘事件提升效率
事件修饰符
在事件处理程序中调用event.preventDefault()
或event.stopPropagation()
是非常常见的需求。
vue.js
为v-on
提供了事件修饰符:
.stop
.prevent
.capture
.self
.once
.passive
深入了解组件
props
, 组件的参数传递;slot
,插槽在组件抽象设计中的应用;自定义事件,父子组件的通信方式。
生命周期钩子
beforeCreate
组件创建前
created
组件创建前
beforeMount
组件挂载前
mounted
组件挂载完毕
beforeUpdate
组件更新之前
updated
组件更新完毕
beforeDestory
组件销毁前
destory
组件销毁完毕
示例:
{{dada}}
修改数据
销毁组件
var vm = new Vue({
el: '#app',
data: {
info: 'dadaqianduan.cn‘
},
beforeCreate: function(){
console.log("beforeCreated,组件创建前");
console.log(this.$el);
console.log(this.$data);
},
created: function(){
console.log("created,组件创建完毕");
console.log(this.$el);
console.log(this.$data);
console.log(this.$data.info);
},
beforeMount: function() {
console.log("beforeMounted,组件挂载前");
console.log(this.$el);
console.log(this.$data);
console.log(this.$data.info);
},
mounted: function(){
console.log("mounted,组件挂载完毕");
console.log(this.$el);
console.log(this.$data);
console.log(this.$data.info);
},
beforeUpdate: function(){
console.log("beforeUpdate,组件更新前");
console.log(this.$el);
console.log(this.$data);
console.log(this.$data.info);
},
updated: function(){
console.log("updated,组件更新完毕");
console.log(this.$el);
console.log(this.$data);
console.log(this.$data.info);
},
beforeDestroy: function(){
console.log("beforeDestory,组件销毁前");
console.log(this.$el);
console.log(this.$data);
console.log(this.$data.info);
},
destroyed: function(){
console.log("destoryed,组件销毁完毕");
console.log(this.$el);
console.log(this.$data);
console.log(this.$data.info);
},
})
组件创建前-beforeCreate:组件创建前,组件需要挂载的DOM元素el和组件的数据data都未被创建。
el: undefined
data: undefined
组件创建完毕-created:组件的数据已经创建完毕,但是DOM元素的el还没被创建
el: undefined
data: {info: 'dadaqianduan.cn’}
组件挂载前-beforeMount:DOM元素被创建,而data中的数据还没有
el有值,data有值,info没值
组件挂载完毕-mounted:data中的数据有值。el,data,info
都有值。
组件更新前-beforeUpdate:data数据已经更新,dom元素的内容也同步更新。
组件更新完毕-updated:data数据已经更新,dom元素的内容也同步更新。
组件销毁之前-beforeDestroy:销毁前,不再受vue
管理,但是可以继续更新数据,但模板已经不再更新了。
组件销毁之前-destroyed:组件销毁完毕,不再受vue
管理。
生命周期阶段
new Vue()
,新建vue
实例
初始化,事件和生命周期
beforeCreate
初始化,注入和校验
created
是否指定el
选项,是直接走判断(是否指定template
选项),否-当调用vm.$mount(el)
函数时(是否指定template
选项)
是否指定template
选项-(是:将template
编译到render
函数中,否:将el
外部的html
作为template
编译)
beforeMount
创建vm.$el
并用其替换el
mounted
挂载完毕(如当data
被修改时,调用beforeUpdate
-,进入虚拟DOM
重新渲染并应用更新,调用updated
。
当调用vm.$destroy()
函数时。
beforeDestroy
解除绑定,销毁子组件以及事件监听器
15.销毁完毕-destroyed
父子组件通信
父组件可以通过props
传递给子组件,子组件可以通过$parent,$emit
传递父组件。
// 组件引用
// 引入
import Dada from './components/Dada'
export default {
name: 'App',
// 注册
components: {Dada}
}
流程:引入,注册,使用。
props
示例:
Vue.component('da-da', {
props: ['textTitle'],
template: '{{textTitle}} '
})
// 使用
prop
类型如下:
props: {
title: String,
likes: Number,
isPublished: Boolean,
commentIds: Array,
author: Object,
callback: Function,
contactsPromise: Promise
}
传递静态或动态prop
prop
可以通过v-bind
动态赋值:
// 动态赋值
父组件prop
的更新会向下流动到子组件中,但是反过来则不行,这样会防止从子组件意外变更父级组件的状态,表示你不应该在一个子组件内部改变prop
,否则vue
会在浏览器的控制台中发出警告。
这个 prop
用来传递一个初始值;这个子组件接下来希望将其作为一个本地的 prop
数据来使用。在这种情况下,最好定义一个本地的 data property
并将这个 prop
用作其初始值
示例:
props: ['dada'],
data: function () {
return {
counter: this.dada
}
}
以一种原始的值传入且需要进行转换。
示例:
props: ['size'],
computed: {
normalizedSize: function () {
return this.size.trim().toLowerCase()
}
}
prop
验证
示例:
Vue.component('my-component', {
props: {
// 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
propA: Number,
// 多个可能的类型
propB: [String, Number],
// 必填的字符串
propC: {
type: String,
required: true
},
// 带有默认值的数字
propD: {
type: Number,
default: 100
},
// 带有默认值的对象
propE: {
type: Object,
// 对象或数组默认值必须从一个工厂函数获取
default: function () {
return { message: 'hello' }
}
},
// 自定义验证函数
propF: {
validator: function (value) {
// 这个值必须匹配下列字符串中的一个
return ['success', 'warning', 'danger'].indexOf(value) !== -1
}
}
}
})
类型检查
type
可以是下列原生构造函数中的一个:通过 instanceof
来进行检查确认。
String
Number
Boolean
Array
Object
Date
Function
Symbol
$emit
子组件通过$emit
向父组件传递通信。
vm.$emit(eventName,[...args])
参数:
1. {string} eventName
2. [...args]
触发当前实例上的事件,附加参数都会传给监听器回调。
子组件中执行$emit(eventName)
时,就会触发父组件中对应的event。
'parent是
vue`的一个实例属性,它表示的是当前组件的父实例
假如父组件中有一个方法为sayDa
,在子组件中可以直接使用this.$parent.sayDa
去调用父组件的方法。
Vuex项目实战
Vuex的基本使用步骤
Vuex的核心概念
Vuex实现业务功能
Vuex概述
组件之间共享数据的方式
如果父组件要向子组件传值,使用v-bind属性绑定
如果子组件要向父组件传值,使用v-on事件绑定
兄弟组件之间共享数据:EventBus
$on
接收数据的那个组件
$emit
发送数据的那个组件
Vuex是什么
vuex是实现组件全局状态数据管理的一种机制,可以方便的实现组件之间数据的共享。
使用vuex统一管理状态的好处
1.能够在vuex中集中管理共享的数据,易于开发和后期维护
2.能够高效地实现组件之间的数据共享,提高开发效率
3.存储在vuex中的数据都是响应式的,能够实时保持数据与页面的同步
什么样的数据可以存储到vuex中
一般情况下,只有组件之间共享的数据,才有必要存储到vuex中,对于组件中私有的数据,存储在组件自身的data中。
vue的基本使用
安装vuex依赖包
npm install vuex --save
导入vuex包
import Vuex from 'vuex'
Vue.use(Vuex)
创建store对象
const store = new Vuex.Store({
// state中存放的是全局共享的数据
state: {count:0}
})
将store对象挂载到vue实例中
new Vue({
el: '#app',
render: h=>h(app),
router,
// 将创建的共享数据对象,挂载到Vue实例中
// 所有的组件,就可以直接从store中获取全局的数据
store
})
vuex的核心概念
组件访问state中数据的第一种方式:
this.$store.state.全局数据名称
组件访问state中的数据第二种方式:
// 从vuex中按需导入mapState函数
import {mapState} from 'vuex'
通过刚导入的mapState
函数,将当前组件需要的全局数据,映射为当前组件的computed
计算属性:
// 将全局数据,映射为当前组件的计算属性
computed: {
...mapState(['count'])
}
Mutation
用于修改store的数据
只能通过mutation
变更Store
数据,不可以直接操作Store
中的数据。
通过这种方式虽然操作起稍微繁琐一些,但是可以集中监控所有数据的变化。
// 定义Mutation
const store = new Vue.store({
state: {
count: 0
},
mutations: {
add(state) {
// 变更状态
state.count++
}
}
})
// 触发mutation
methods: {
handle1() {
// 触发mutations的第一种方式
this.$store.commit('add')
}
}
可以在触发mutations
时传递参数:
// 定义Mutation
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
addN(state,step){
// 变更状态
state.count += step
}
}
})
// 触发mutation
methods: {
handle2() {
// 在调用commit函数
// 触发mutations 时携带参数
this.$store.commit('addN',1)
}
}
this.$store.commit()
是触发mutations
的第一种方式,第二种如下:
// 从vuex中按需导入mapMutations函数
import {mapMutations} from 'vuex'
将需要的mutations
函数,映射为当前组件的methods
方法:
methods: {
...mapMutations(['add','addN'])
}
不要在mutations函数中,执行异步操作
Action 用于处理异步任务。
如果通过异步操作变更数据,必须通过Action,而不能使用Mutation,但是在Action中还是通过触发Mutation的方式间接变更数据。
// 定义Action
const store = new Vuex.store({
mutations: {
add(state){
state.count();
}
},
actions: {
addAsync(context){
setTimeout(()=>{
context.commit('add')
},1000)
}
}
// 触发Action
mothods: {
handle() {
// 触发actions的第一种方式
this.$store.dispatch('addAsync');
}
}
触发action异步任务时携带参数:
this.$store.dispatch('addNAsync',5)
触发actions的第二种方式:
// 从vuex中按需导入mapActions函数
import {mapActions} from 'vuex'
将需要的actions函数,映射为当前组件的methods方法:
methods: {
...mapActions(['addAsync','addNASync'])
}
import {mapState,mapMutations,mapActions} from 'vuex
computed: {
...mapState(['count'])
},
methods: {
...mapMutations(['sub','subN']),
...mapActions(['subAsync']),
btnHandler1(){
this.sub()
},
btnHandle2(){
this.subN()
}
}
getter
vuex中的getter
Getter用于对Store中的数据进行加工处理形成新的数据
Getter可以对Store中已有的数据加工处理后形成新的数据。
Store中数据发生变化,Getter的数据会跟着改变
const store = new Vuex.store({
state: {
count: 0
},
getters: {
showNum: state => {
return state.count
}
}
})
使用getters的第一种方式:
this.$store.getters.名称
使用getters的第二种方式:
import { mapGetters } from 'vuex'
computed: {
...mapGetters(['showNum'])
}