VUE笔记
壹
Day1
MVC与MVVM
v-bink
是vue中,提供的用于绑定属性的指令(简写 : )
v-bink 中,可以写合法的JS表达式
v-on
vue提供了事件绑定机制(简写 @ )
事件修饰符
- .stop 阻止冒泡事件
- .prevent 阻止默认行为
- .capture 实现捕获事件机制
- .self 实现当前元素自己的事件,不同通过冒泡或捕获事件实现
- .once 只触发一次
总结
1、如何定义一个基本的vue结构
2、插值表达式 v-text
3、v-cloak
4、v-html
5、v-bink 属性绑定机机制 缩写 :
6、v-on 事件绑定机制 缩写 @
实例
<div id="app">
<input type="button" value="跑起来" @click="lang">
<input type="button" value="低调" @click="stop">
<h4>{{msg}}</h4>
</div>
<script src="vue.min.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
msg: 'hahahahahahlalalal~',
intervalId: null
},
methods: {
lang(){
// var _this = this
// setInterval(function(){
//获取到第一个字符
// var start = _this.msg.substring(0,1)
//获取到后面所有的字符
// var end = _this.msg.substring(1)
// _this.msg = end + start
// },400)
// setInterval(() => {
// var start = this.msg.substring(0,1)
// var end = this.msg.substring(1)
// this.msg = end + start
// },400)
if(this.intervalId !== null) {return}
this.intervalId = setInterval(() => {
var start = this.msg.substring(0,1)
var end = this.msg.substring(1)
this.msg = end + start
},400)
},
stop() {
clearInterval(this.intervalId)
this.intervalId = null
}
}
})
</script>
使用class / style样式
- 数组
- 数组中使用三元表达式
- 数组中嵌套对象
- 直接使用对象
//1、数组
<h1 :class="['red','thin']">......<h1>
//2、数组中使用三元表达式
<h1 :class="['red','thin',isActive?'active':'']">......<h1>
//3、数组中嵌套对象
<h1 :class="['red','thin',{ 'active': isactive }]">......<h1>
//4、直接使用对象
<h1 :class="{red: true, italit: true, thin: true}">......<h1>
v-for
- 遍历对象
-(val, key, i)in user 键值对,索引 - 遍历数组
-(item, i) in list 元素,索引
(遍历的可以是普通数组,对象数组,对象,还可以是数字)
在组件中,使用v-for循环的时候,或者一些特殊的情况中,如果v-for有问题,必须在使用v-for的同时,指定 唯一的 字符串 数字 类型 key值
v-if 和 v-show
- v-if 每次都会重新删除或创建元素(有较高的切换性能消耗)
- v-show 每次不会进行DOM的删除和创建操作,只是切换了元素 diaplay: none 样式(有较高的初始渲染消耗)
如果元素涉及到频繁的切换,最好不要使用 v-if
如果元素可能永远也不会被显示出来被用户看到,则推荐使用 v-if
小结
贰
Day2
过滤器
过滤器调用时候的格式
{{ name | nameope }}
//定义全局的过滤器,名字为msgfn
Vue.filter('nameope ', function(name){
})
//定义局部的过滤器
filters: {
'dateFilter': function() {
}
}
按键修饰符
在监听键盘事件时,我们经常需要检查详细的按键。Vue 允许为 v-on 在监听键盘事件时添加按键
<!-- 只有在 `key` 是 `Enter` 时调用 `vm.submit()` -->
<input v-on:keyup.enter="submit">
为了在必要的情况下支持旧浏览器,Vue 提供了绝大多数常用的按键码的别名:
- .enter
- .tab
- .delete (捕获“删除”和“退格”键)
- .esc
- .space
- .up
- .down
- .left
- .right
你还可以通过全局 config.keyCodes 对象自定义按键修饰符别名:
// 可以使用 `v-on:keyup.f1`
Vue.config.keyCodes.f1 = 112
过自定义指令
Vue 也允许注册自定义指令。注意,在 Vue2.0 中,代码复用和抽象的主要形式是组件。然而,有的情况下,你仍然需要对普通 DOM 元素进行底层操作,这时候就会用到自定义指令。举个聚焦输入框的例子,如下:
// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
// 当被绑定的元素插入到 DOM 中时……
inserted: function (el) {
// 聚焦元素
el.focus()
}
})
注册局部指令,组件中也接受一个 directives 的选项
directives: {
focus: {
// 指令的定义
inserted: function (el) {
el.focus()
}
}
}
然后你可以在模板中任何元素上使用新的 v-focus 属性,如下:
<input v-focus>
深入解析
// 使用 Vue.directive() 定义全局的指令 v-focus
// 参数1:指令的名称
// (注意:在定义的时候,指令名称面前不需要加v-,调用的时候则必须 在指令名称前 加 v- 前缀进行调用)
// 参数2:是一个对象,这个对象身上,有一些指令相关的函数,这些函数可以在特定的阶段,执行相关的操作
Vue.directive('focus', {
bind: function() { // 每当指令绑定到元素上的时候,会立即执行这个 bind 函数,只执行一次
// 注意:在每个 函数中,第一个参数,永远是 el ,表示 被绑定了指令的那个元素,这个el参数是一个原生的js对象
// 在元素刚绑定了指令的时候,还没有 插入到 DOM中去,这时候调用 focus 方法没有作用
// 因为,一个元素,只有插入到DOM之后,才能获得焦点
// 和样式有关的操作
// el.focus()
},
inserted: function(el, binding) { // inserted 表示元素 插入到DOM中的时候,会执行 inserted 函数【触发一次】
// 和js行为有关的操作
el.focus()
el.style.color = binding.value
},
updated: function() { // 当VNode 更新的时候,会执行 updated 函数,可能会触发很多次
}
})
钩子函数
- bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
- inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
- update:所在组件的 VNode 更新时调用,
- componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
- unbind:只调用一次,指令与元素解绑时调用。
函数的参数 (即 el、binding、vnode 和 oldVnode)
" blue " 和 " ’ blue ’ "
注意:
解析:v-focus=" ’ blue ’ "
(“ blue ”表示变量,这么写编译是会去找 blue 这个 变量 ,会报错
" ’ blue ’ " 表示字符串 )
在自定义指令中传参binding,
binding.value = blue
binding.expression = ’ blue ’
小结
叁
Day3
过渡&动画
- v-enter 【时间点】 是进入之前,元素的初始状态,此时还没有开始进入
- v-leave-to 【时间点】 是动画离开之后,离开的终止状态,此时,元素动画已经结束
- v-enter-active 【入场动画的时间段】
- v-leave-active 【离场动画的时间段】
1、基本使用
<div id="app1">
<input type="button" value="点击" @click="flag=!flag">
<transition name="my">
<h3 v-if="flag">I Love You</h3>
</transition>
</div>
var vm1 = new Vue({
el: '#app1',
data: {
flag: false
}
})
.my-enter,
.my-leave-to {
opacity: 0;
transform: translateX(100px);
}
.my-enter-active,
.my-leave-active {
transition: all .5s;
}
2、Vue 的过渡系统和其他第三方 CSS 动画库 (Animate.css)
<transition
name="custom-classes-transition"
enter-active-class="animated tada"
leave-active-class="animated bounceOutRight"
>
<p v-if="show">hello</p>
</transition>
3、可以用 组件上的 duration属性定制一个显性的过渡持续时间 (以毫秒计):
<transition :duration="1000">...</transition>
// 定制进入和移出的持续时间:
<transition :duration="{ enter: 500, leave: 800 }">...</transition>
4、JavaScript 钩子
<transition
v-on:before-enter="beforeEnter"
v-on:enter="enter"
v-on:after-enter="afterEnter"
v-on:enter-cancelled="enterCancelled"
v-on:before-leave="beforeLeave"
v-on:leave="leave"
v-on:after-leave="afterLeave"
v-on:leave-cancelled="leaveCancelled"
>
<!-- ... -->
</transition>
// 当与 CSS 结合使用时
// 回调函数 done 是可选的
当只用 JavaScript 过渡的时候,在 enter 和 leave 中必须使用 done 进行回调。否则,它们将被同步调用,过渡会立即完成。
leave: function (el, done) {
// ...
done()
},
5、列表动画 transition-group ,需要写:key,不同于 transition,它会以一个真实元素呈现:默认为一个 。你也可以通过 tag attribute 更换为其他元素。
<transition-group name="list" tag="p">
<span v-for="item in items" v-bind:key="item" class="list-item">
{{ item }}
</span>
</transition-group>
6、补充:
el.offsetWidth:强制动画刷新
移除的动画
// 让列表删除时,被删除的下一个元素会飘飘上来
.v-move{
transition: all .2s ease
}
.v-leave-active{
// absolute脱离文档流
position: absolute
}
组件 component
1、什么是组件?
组建的出现,就是为了拆分 Vue 实例的代码量,能够让我们以不同的组件,来划分不同的功能模块,将来我们需要什么样的功能,就可以去调用对应的组件即可。
2、组件化和模块化区别?
- 模块化:是从代码逻辑的角度进行划分的;方便代码分成开发,保证每个功能模块的职能单一
- 组件化:是从UI界面的角度进行划分的;前端的组件化,方便UI组件的重用。
3、全局组建的3种定义
第一:Vue.extend(推荐后两种方式)
Vue.component('myCon1', Vue.extend({
template: `<h3>123</h3>`
}))
第二:(简洁)
Vue.component('myCon2', {
template: '<h3>456</h3>'
})
第三:(优势:打代码会有提示)
Vue.component('myCon3', {
template: '#my'
})
<template id="my">
<div>
<p>789</p>
</div>
</template>
以上的3种定义方式的调用调用
<div id="app">
<my-con1></my-con1>
<my-con2></my-con2>
<my-con3></my-con3>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {},
methods: {}
})
</script>
4、局部组建的定义
5、一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝:
(因为组件可以被复用,要保证组件间的数据互相独立,不被污染,所以使用 function 返回独立于当前组建的新对象)
data: function () {
return {
count: 0
}
}
6、组建的切换的2种方式
第一:通过定义flag = false / true
<a href="" @click.prevent="flag=true">123</a>
<a href="" @click.prevent="flag=false">456</a>
<my-con1 v-if="flag"></my-con1>
<my-con2 v-else="flag"></my-con2>
第二:使用 component (其中 : is 属性可以指定 将要切换组件 的 组件名称)
<a href="" @click.prevent="tagBox='myCon1'">123</a>
<a href="" @click.prevent="tagBox='myCon2'">456</a>
<component :is="tagBox"></component>
<script>
Vue.component('myCon1', Vue.extend({
template: `<h3>123</h3>`
}))
Vue.component('myCon2', {
template: '<h3>456</h3>'
})
var vm = new Vue({
el: '#app',
data: {
flag: true,
tagBox: 'myCon1'
}
})
</script>
7、组建动画
小结
Vue提供的标签
- transition
- transitionGroup
- template
- component
肆
Day4
组父组件向子组件传值 / 方法
1、传值
父组件,可以在引用子组件的时候,通过 属性绑定:v-bind,把 需要传递给 子组件 的数据,以属性绑定的形式,传递到子组件内部,供子组件使用。
- 父组件定义变量 msg: ‘我是父组件的msg数据,想要在子组件显示’,
- 在父组件中(即 在使用子组件的标签中 )自定义绑定属性:v-bind:sonmsg=“msg”
- 在子组件的props数组中定义 props: [‘sonmsg’]
- 在子组件的 template模板 中引用父组件传过来的值 {{ sonmsg }}
代码实例如下:(注释的笔记也要看)
<div id="app">
<my-con3 :sonmsg="msg"></my-con3>
</div>
<template id="my">
<div>
<p>I am son-----This is father's data:{{sonmsg}}</p>
</div>
</template>
<script>
var vm = new Vue({
el: '#app',
data: {
msg: '我是父组件的msg数据,想要在子组件显示',
fomeSonData: null
}
})
Vue.component('myCon3', {
// 注意:组件中的 所有 props 中的数据,都是通过 父组件传给子组件的
// 把父组件传递过来的 sonmsg 属性,先在 props 数组中定义一下,这样才能使用这个数据
// 只读,不可重新被赋值
props: ['sonmsg'],
template: '#my',
// 子组件中的data数据并不是通过父组件传递过来的,而是子组件自身私有的,
// 比如:子组件通过 ajax,请求回来的数据,都可以放到 data 身上
// 可读可写
data: function(){
return {
}
}
})
</script>
2、传方法
父组件向子组件传递 方法 ,使用的是 事件绑定机制:v-on,当我们自定义一个事件属性之后, 那么,子组件就能够,通过 $emit() 来调用 传递进去的方法.
- 父组件定义方法show
- 在父组件中(即 在使用子组件的标签中 )自定义绑定事件:@sonfun=“show”
(注意:sonfun = " show() "——表示 先把 show 调用,把调用的结果传给 sonfun
sonfun = " show " ——把方法的引用原封不懂的交给 sonfun ) - 在子组件 template模板 中绑定点击事件 @click=“myclick”
- 然后在子组件中定义事件函数 myclick ,使用 this.$emit(‘sonfun’, this.sondata) 调用父组件中的方法,(参数1:自定义绑定事件的名称;参数2…:要传入的参数 )
<div id="app">
<my-con3 @sonfun="show"></my-con3>
</div>
<template id="my">
<div>
<input type="button" value="我是子组件中的按钮" @click="myclick">
</div>
</template>
<script>
var vm = new Vue({
el: '#app',
data: {
fomeSonData: null
},
methods: {
show(data) {
console.log('Father Father :' + JSON.stringify(data))
this.fomeSonData = data
}
}
})
Vue.component('myCon3', {
template: '#my',
data: function(){
return {
sondata: { name: 'zhangsan', age: 18 }
}
},
props: ['sonmsg'],
methods: {
// 当点击子组件按钮时,如何拿到父组件传来的show方法,并调用这个方法
// emit 英文原意:触发,调用,发射的意思
myclick() {
this.$emit('sonfun', this.sondata)
}
}
})
</script>
3、ref
可以在父组件引用子组件时,在子组件标签上定义 ref 属性,父组件就可以拿到子组件的值和调用子组件的方法
this.$refs.nameRef.
兄弟组件传值
//一、
var bor = new Vue()
//二
bor.$on('tom-event',(val)=>{})
//三
bor.$emit('tom-event', 2)
实例
<div id="app">
<div>父组件</div>
<tom></tom>
<jerry></jerry>
</div>
<script>
// look here1
var bor = new Vue()
Vue.component('tom',{
template: `
<div>
<div>Tom: --- {{num}}</div>
<button @click="handle"> 点我 Jerry+1 </button>
</div>
`,
data: function(){
return {
num: 0
}
},
// look here3
methods: {
handle(){
bor.$emit('jerry-event', 1)
}
},
// look here2
mounted: function(){
bor.$on('tom-event',(val)=>{
this.num += val
})
}
})
Vue.component('jerry',{
template: `
<div>
<div>Jerry: --- {{num}}</div>
<button @click="handle"> 点我 Tom+2 </button>
</div>
`,
data: function(){
return {
num: 0
}
},
methods: {
handle(){
bor.$emit('tom-event', 2)
}
},
mounted: function(){
bor.$on('jerry-event',(val)=>{
this.num += val
})
}
})
var vm = new Vue({
el: '#app'
})
</script>
路由 vue-router
1、进本使用
一、引入
<script src="js/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
二、router-link用于切换链接,router-view展示匹配到的组件
<div id="app">
<!-- <a href="#/login">login</a>
<a href="#/reginer">reginer</a> -->
<!-- router-link 默认渲染为一个a 标签,可使用tag属性指定标签 -->
<router-link to="/login?id=10">login</router-link>
<router-link to="/reginer">reginer</router-link>
<!-- 这是 vue-router 提供的元素,专门用来当作占位符,将来,路由规则,匹配到的组件,就会展示到这个router-view中
所以,我们可以把router-view认为是一个占位符 -->
<router-view></router-view>
</div>
三、创建路由,定义路由规则,注册路由
<script>
// 组件的模板对象
var login = {
template: `<h1>登录组件---{{$route.query}}</h1>`
}
var reginer = {
template: `<h1>注册组件</h1>`
}
// 创建一个路由对象,当导入 vue-router 之后,在 windows 全局对象中,就有了一个 路由的构造函数(VueRouter)
// 在 new 路由对象的时候,可以为 构造函数,传递一个配置对象
var router = new VueRouter({
// 这个配置对象中的 routes 表示【路由匹配规则】的意思
routes: [
// 每个路由规则,都是一个对象,这个规则对象身上有两个必须的属性
// 属性1:path ,表示监听 哪个路由链接地址
// 属性2:component ,表示 如果 路由是前面匹配到的 path,则展示component属性对应的那个组件
// 注意:component 的属性值,必须是一个 组建的模板对象,不能是 组件的引用名称Vue.component('namelogin',login) 别这样定义一个组件
{ path: '/login', component: login },
{ path: '/reginer/', component: reginer }
]
})
var vm = new Vue({
el: '#app',
data: {},
// 将路由规则对象,注册到 vm 实例,用来监听 URL地址 的变化,然后展示对赢得组件
router: router
})
</script>
2、执行过程
- 点击链接,修改url地址
- 路由对象注册到 ym 实例上
- 路由监听到 url 改变
- 于是进行路由规则匹配的匹配
3、如果是a标签 链接路径需要 #
<a href="#/login">login</a>
4、 这是 vue-router 提供的元素,专门用来当作占位符,将来,路由规则,匹配到的组件,就会展示到这个router-view中,所以,我们可以把router-view认为是一个占位符
<router-view></router-view>
5、重定向,指定刚打开的页面
// 这里的 redirect 与 Node 中的 redirect 完全是两码事
// {path: '/', component: login },
{path: '/', redirect: '/login'}
6、高亮
linkActiveClass
- 类型: string
- 默认值: “router-link-active”
全局配置 默认的激活的 class。参考 router-link。
<style>
/* .router-link-active, */
.myactive{
color: orange;
font-size: 24px;
}
</style>
7、动画 - 包在 transition 元素中
8、参数(两种方式)
<router-link to="/login?id=10">login</router-link>
<router-link to="/reginer/10">reginer</router-link>
// 组件的模板对象
var login = {
template: `<h1>登录组件---{{$route.query}}</h1>`
}
var reginer = {
template: `<h1>注册组件---{{$route.param}}</h1>`
}
9、路由嵌套
var reginer = {
template: `
<div>
<h1>注册组件</h1>
<router-link to="/reginer/demo1">demo1</router-link>
<router-link to="/reginer/demo2">demo2</router-link>
<router-view></router-view>
</div>
`
}
{
path: '/reginer/',
component: reginer,
children: [
{ path: 'demo1', component: demo1 },
{ path: 'demo2', component: demo2 }
]
}
10、常见的页面–头左右(在router-view中用到name)
https://blog.csdn.net/weixin_44764873/article/details/105586700
小结
伍
Day5
methods:业务逻辑·
<div id="app">
<input type="text" v-model="starNum">+
<input type="text" v-model="endNum">=
<input type="text" v-model="allNum">
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
starNum: '',
endNum: '',
allNum: ''
},
methods: {
handle () {
this.allNum = this.starNum + '-' + this.endNum;
}
}
})
</script>
watch:监听虚拟的东西
使用这个属性,可以监听 data 中指定数据的变化,然后触发这个 watch 中对应的 function 处理函数
var vm = new Vue({
el: '#app',
data: {
starNum: '',
endNum: '',
allNum: ''
},
methods: {},
watch: {
'starNum': function(newVal, oldVal){
this.allNum = newVal + '-' + this.endNum;
},
'endNum': function(newVal, oldVal){
this.allNum = this.starNum + '-' + newVal;
}
}
})
监听路由地址
watch: {
'$route.path': function(newVal){
if (newVal === '/login'){
console.log('login')
}else if(newVal === '/reginer'){
console.log('reginer')
}
}
}
computed:数据操作
var vm = new Vue({
el: '#app',
data: {
starNum: '',
endNum: ''
},
methods: {},
computed: {
'allNum': function() {
return this.starNum + '-' + this.endNum
}
}
})
watch、computed和methods
- computed 属性的结果会被缓存,除非依赖的响应式属性发生变化才会被重新计算,主要当作属性来使用;
- methods 方法表示一个具体的操作,主要书写业务逻辑;
- watch 一个对象,键是需要观察的表达式,值是对应回调函数,主要用来监听某些特定数据的变化,从而进行某些具体的业务逻辑操作,可以看作是 computed 和 methods 的结合体。