框架 -> 全方位、功能齐全javascript
代码上的不一样:css
通常使用框架:其框架在帮咱们运行已编写好的代码html
库:小而精框架:大而全 ( 框架包含了各类库 )vue
引包java
<script>
引入npm install --yes npm install vue --save ( npm install vue -S )
建立实例化对象 new Vue( options 对象 ) react
optionsnpm
data : 数据属性 ( 既能够是一个对象,也能够是一个函数 )后端
template : 模板内容设计模式
vue的模板语法:app
{{ 表达式 }}
设计模式:MVC 与 MVVM
MVC:Model( 数据模型 )、View( 视图 )、Controller( 控制器 )
MVVM:Model、View、ViewModel
在vue中提供了一些对于页面+数据的更为方便的输出,这些操做就叫作指令
<div v-xxx></div>
经常使用指令
display:none;
,是基于css样式的切换。v-if 与 v-show 的区别 ( 官网解释 )
v-if
是“真正”的条件渲染,由于它会确保在切换过程当中条件块内的事件监听器和子组件适当的被销毁和重建。v-if
也是惰性的:若是在初始渲染时条件为假,则什么也不作——直到条件第一次变为真时,才会开始渲染条件块。v-show
就简单的多——无论初始条件是什么,元素总会被渲染。而且只是简单的基于css进行 显/隐 切换。v-if
有更高的切换开销,而v-show
有更高的初始渲染开销。所以,若是须要很是频繁的切换,则使用v-show
较好;若是在运行时条件不多改变,则使用v-if
较好。v-bind:class="box"
,简写 :
。<div class="container" :class="{active: true}"></div> // 渲染为 DOM <div class="container active"></div>
v-on:原生事件名 = '函数名'
,简写 @
// html <div class="container" @click="clickHandler"></div> // js methods:{ clickHandler(e){ console.log(this); } }
v-for="item,index in arr"
<ul> <li v-for="item,index in list"> {{index}}--{{item}} </li> </ul>
v-model:数据双向绑定
<input v-model="msg"> // 等同于 <input :value="msg" @input="msg = $event.target.value" />
那么v-model
其实就是v-bind
和v-on
的语法糖。
局部组件使用打油诗:声子挂子用子
声明子组件;父组件挂载子组件;父组件使用子组件。
// 局部组件的声明 var App = { data(){ return{ } }, template:` <div>我是入口组件</div> ` } // vue实例 new Vue({ el:"", data(){ }, // 挂载子组件 components:{ App }, // 父组件直接可使用 template:`<App />` })
组件命名: 1.短横线分隔 命名:当引用组件时,也要使用 短横线分隔 形式。( 如: <my-compnent-name> )
2.驼峰式命名:当引用组件时,可使用 短横线分隔 形式或者 驼峰 形式。( 如: <my-compnent-name> 或 <MyCompnentName>)
[注]:直接在DOM( 即非字符串的模板 )中使用时只有 短横线分隔 形式是有效的。
[建议]:命名时用 驼峰 形式,使用时用 短横线分隔 形式。
Vue.component("组件名", options)
// 全局组件声明 // 第一个参数是组件的名字,第二个参数是options配置项 Vue.component("Vbtn", { template:` <button>按钮</button> ` }) // 全局组件使用 var App = { template:` <div> ... <Vbtn /> </div> ` }
Vue.component("Parent", { data(){ return{ msg:"我是父组件的数据" } }, template:` <div> <p>我是父组件</p> <Child :childData="msg" /> </div> ` })
Vue.component("Child", { template:` <div> <p>我是子组件</p> <input type="text" v-model="childData" /> </div> `, props:["childData"] })
在子组件中 触发原生的事件,在函数中使用 $emit
触发其父组件中自定义的事件
$emit("自定义的事件名", "消息")
// Child Vue.component("Child", { template:` <div> <p>我是子组件</p> <input type="text" v-model="childData" @input="changeValue(childData)" /> </div> `, props:["childData"], methods:{ changeValue(val){ // 自定义的事件必定要经过 this.$emit() 去触发 // $emit("自定义的事件名", "消息") this.$emit(childHandler, val) } } }) // Parent Vue.component("Parent", { data(){ return{ msg:"我是父组件的数据" } }, template:` <div> <p>我是父组件</p> <Child :childData="msg" @childHandler="childHandlerFn" /> </div> `, methods:{ childHandlerFn(val){ console.log(val); } } })
插槽:内置组件 slot,做为承载分发内容的出口
/* 模拟 elementUI 按钮组件的实现 */ // 子组件 Vue.component("Vbtn", { template:` <button class="default" :class="type"> <slot>按钮</slot> </button> `, props:["type"] }) // 父组件 var App = { template:` <div> ... <Vbtn type="primary">登录</Vbtn> <Vbtn type="success">注册</Vbtn> </div> ` }
// 子组件 Vue.component("liItem", { template:` <li> 第一个槽 <slot name="idx-1"></slot> 第二个槽 <slot name="idx-2"></slot> </li> ` }) // 父组件 var App = { template:` <div> <ul> <liItem> <h1 slot="idx-1">我是第一个槽</h1> <h3 slot="idx-2">我是第二个槽</h3> </liItem> </ul> </div> ` }
分类
/* 局部过滤器 */ // 1.声明过滤器 // 2. {{ 数据 | 过滤器的名字 }} var App = { data(){ return{ price:0, msg:"hello filter" } }, template:` <div> <input type="number" v-model="price" /> <!-- 使用过滤器 --> <h2>{{ price | myCurPrice }}</h2> <h3>{{ price | myReverse }}</h3> </div> `, filters:{ // 声明过滤器 myCurPrice: function(val){ return "¥" + val } } } /* 全局过滤器 */ // 字符串反转过滤器 Vue.filter("myReverse", function(val){ return val.split("").reverse().join(""); })
{{ 数据 | 过滤器的名字(能够传值) }}
例: {{ price | myReverse("这里是传入的值") }}
// 其中 arg 就是传入的值
Vue.filter("myReverse", function(val, arg){
return val.split("").reverse().join("");
})
watch 监听的是单个属性基本的数据类型 -- 简单监视
复杂的数据类型 -- 深度监视
new Vue({ el:"", data(){ return{ msg : '' } }, watch:{ msg: function(newVal, oldVal){ console.log(newVal, oldVal); } } })
new Vue({ el:"", data(){ return{ userList : [{name:"jack"}] } }, watch:{ userList: { deep:true, // 深度监视 handler: function(newVal, oldVal){ console.log(newVal, oldVal); } } } })
// html <img :src="getCurSrc" /> <ul> <li v-for="item,index in dataList" @click="clickHandler(index)" :class="{active: curIdx == index}">{{ index }}</li> </ul> // js new Vue({ el:"", data(){ return{ dataList:[{imgsrc:'1'},{imgsrc:'2'},{imgsrc:'3'}], curIdx : 0 } }, computed:{ // 计算属性默认只有 getter getCurSrc: function(){ return this.dataList[this.curIdx].imgsrc } }, methods:{ clickHandler(index){ this.curIdx = index; } } })
// js new Vue({ computed:{ getCurSrc: { set: function(newVal){ console.log(newVal); this.curIdx = newVal; }, get: function(){ return this.dataList[this.curIdx].imgsrc } } }, methods:{ clickHandler(index){ // 点语法 set方法 和 get方法 // getter 方法 console.log(this.getCurSrc); // 调用set方法 this.getCurSrc = index; } } })
created:组件建立以后 会调用
mounted:挂载数据到 DOM 以后会调用
beforeUpdate:在更新DOM以前 调用该钩子
updated:在更新DOM以后 调用该钩子
vue 内置组件 <keep-alive></keep-alive>
:能在组件的切换过程当中将状态保留在内存中,防止重复渲染DOM。