简介
vuex : Vue组件中每個data变量,它就是一个状态,当应用程序足够庞大时,如果将这些状态集中管理就会非常方便,于是Vuex便应运而生
axios : src/utils/http.js 用于封装axios异步GET/POST/DELETE等方式获取数据
基于实践开发项目sst-PO system初步搭建:(vue-cli + vuex + axios)
npm install -g vue-cli
npm install axios vuex
MVVM
MVVM由Model,View,ViewModel 三部分构成,Model层代表数据模型(也可以在Model中定义数据修改和操作的业务逻辑),View代表视图层,负责将数据模型转化在页面展示,ViewModel是一个同步View和Model的对象。
在MVVM架构下,View和Model之间并没有直接联系,而是通过ViewModel进行交互,Model和ViewModel之间的交互是双向的, 因此View数据的变化会同步到Model中,而Model数据的变化也会立即反应到View 上。
ViewModel通过双向数据绑定把View层和Model层连接了起来,而View和 Model之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理。
VUEX
仅需要checkbox/radio等单一值改变情况下,使用VUEX是动态获取数据且改变时需要$set/$forceUpdate/$nextTick,单一改变时显得累赘, 使用以下方式定义函数生成静态数据,这样checkbox/radio只需要v-model改变值;
async ajaxTest(){
// $api代表VUEX的modules文件夹,并非api文件夹
let {data} = await this.$api.systemAutoRule.getData();
conosle.log(data)
}
Model层(数据)改变而视图层(UI)没同步三种处理方式:
// First Kind
let test = 1;
this.$forceUpdate() // 强制深入层级重绘
// Second Kind
// 回调函数延迟到下次 DOM 更新循环之后执行
this.$nextTick([callback])
// Third Kind
this.$set(object,index,value); // 对象重绘(object:对象,index:索引,value:改成的值)
自定义组件Component
native:父组件绑定的事件跟子组件绑定的自定义事件名称相同时可用.native修饰符执行父组件原生事件:
组件HTML调用
// 特别注意是ref如需循环必须添加唯一的ref;
<test ref="testForm" my-message="hello" :myObject="{name:'Devin'}" :isShow="true" >
<div slot="title">
<button> BUTTON </button>
</div>
<div> OTHER </div>
</test>
* 组件引用
<template>
<div>
<div class="main">
<slot name="title"></slot> // slot插槽使用:通过name对应特定内容
<slot></slot> // slot插槽使用:放置内容(除去特定)
</div>
<div>
</template>
<script>
import Test from '@/components/test'
export default{
components: { Test } ,
name : "test" ,
// 父级数据通信到子级
props:{
myMessage:{ type : String , default : '' },
myObject : { type : Object , default : ()=>{} }, // 注意类型为数组/对象的默认值需要函数返回,否则报错
},
watch:{
isShow(val){ } // 侦听父组件isShow变化而触发,注意像myMessage如果是API数据是无法侦听变化
}
}
</script>
// 父级/祖级/同级调用子级组件函数
this.$refa["testForm"].toXX();
// 子级数据通信到父级
this.$emit() 触发事件 : 相对于JS调用函数 => toEvent(object)
this.$on 绑定事件 : 相对于JS定义函数 => function toEvent(object){ ... }
// 两个组件之间需要进行通信,但是它们彼此不是父子组件
var bus = new Vue();
bus.$emit('say-hello', 'world') // 在组件 A 的 methods 方法中触发事件
bus.$on('say-hello', function (arg) { // 在组件 B 的 created 钩子函数中监听事件
console.log('hello ' + arg); // hello world
})
自定义指令
尽管Vue推崇数据驱动视图的理念,有的情况下仍需要对普通DOM元素进行底层操作,自定义指令就是一种有效的补充和扩展,且自定义指令需要钩子函数;
// INPUT自动获取焦点
export default {
update: function (el,binding) {
if(binding.value.isShowList) el.querySelector('input').focus();
}
}
// 比如VUE中使用jQuery插件:
<table id="testTable">
<tr v-for="(el, lineIndex) in lines" v-line-inserted="lineIndex" >
<td> <input name="bindSelect2" /> <td>
</tr>
</table>
function renderLines(el, lineIndex){
$("testTable tr").eq(lineIndex).select2({...});
}
Vue.directive('line-inserted', {
inserted: function (el, binding) {
var lineIndex = binding.value;
renderLines(el, lineIndex);
}
});
Computed 与 Watch使用与区别
computed是计算属性,依赖其它的属性计算得出最后的第三方值(自动侦听依赖其它的值改变而触发)
watch是去监听本身值的变化,然后执行相对应的函数( 侦听指定值改变而触发 )注意:computed中无法获取到API的数据,唯有使用watch
// computed页面加载时触发或关联数据改变时触发
computed:{
num : function(val){
return this.i * 2 ; //必须要return返回;
}
},
// 当data改变而自身随之改变
watch:{
data:{
deep:true, // 深度监听,一般用于json属性某值改变
immediate: true, // 用于首次即可执行(常用初始化获取API数据后父组件传递到子组件)
handler:function(newVal,oldVal){
}
}
}
v-bind 动态绑定属性
特殊属性class
方法1. :class='[red,blue]'
方法2. :class='{ red:false , blue:true }'
;
特殊属性style
:style='json'
( json:{ color:'red',backgroundColor:'blue' }
json代表controller内的数据);
Event
element 事件默认参数 -> $event
阻止事件冒泡 -> Vue简写:@click.stop='Func'
;
阻止默认事件 -> Vue简写: @click.prevent='Func'
;
触发捕获事件 -> Vue简写: @click.capture='Func'
;
原生事件触发 -> @click.native ( 组件中自定事件名与原生事件名一致,native即使区分原生事件,比如el-radio使用click事件 )
export default 和 export 区别
export与export default均可用于导出常量、函数、文件、模块等 (export、import可以有多个,export default仅有一个)
通过export方式导出,在导入时要加{},export default则不需要
生命周期 (实际项目理解)
由于VUE是写在onload中所以不存在jquery的onready & onload说法,仍存在VUE自身DOM/数据生命周期,一般文档时就载入用黑下划线的事件;
-
beforecreated
DOM、Data未初始化 -
created
Data已初始化、DOM并没生成,用于新增数据 -
beforeMount
DOM、Data均初始化 -
mounted
后端返回数据配合路由钩子处理虚拟DOM; -
beforeDestory
删除组件前;
获取API:
-
axios默认不启用跨域异步访问(Access-Control-Allow-Origin),需要服务器(后端)开启才能使用;
-
封装Axios全局使用: 参考PO目录 src/utils/http.js(包含TOKEN验证配置 + Vue + Axios + Element Message)
BUG
Failed to mount component: template or render function not defined
- 原因:主要时vue-loader版本问题,根据官方设置default即可 https://github.com/vuejs/vue-loader/releases/tag/v13.0.0