vue-基础总结2

212 阅读6分钟

回顾

基础总结1里简单介绍了什么是vue,为什么使用vue,mvvm设计模式,数据绑定,属性绑定,方法绑定,计算属性,侦听器

计算属性和侦听器区别

1,同步处理运算,计算属性更加方便 2,异步处理侦听器方便

  • computed,watch 都是watcher的实例,只是传入的构建参数不同,在vm._watcher可以看到这些实例
  • 计算属性同样使用object.defineProperty方法将属性绑定到vue实例上

?这边之后可以详细展开~

样式绑定

有一个常用的结合三目运算tab切换样式

<a :class="active == index?active :''">{{index}}</a>
  • 动态 :class 接受一个对象,或表达式
  • 静态 class="style"

条件渲染

v-if,v-else

什么是条件渲染:通过v-if指令来判断是否参与到dom渲染

<div id="app">
    <p v-if="isShow">v-if</p>
</div>

<script>
    new Vue({
        el: '#app',
        data: {
            isShow: true
        }
    })
</script>
<input v-if="isShow" type="text" placeholder="true" />
<input v-else type="text" placeholder="false" />

上面的例子修改isShow后,value值不会改变

需要加上key,vue可以监听到相应input

<input v-if="isShow" type="text" placeholder="true" key="true" />
<input v-else type="text" placeholder="false" key="false"/>

v-show

v-show 是通过改变display样式来决定是否隐藏的

  • v-if是通过动态增删DOM来隐藏显示的
  • v-if动态修改DOM,消耗大,用于初始化
  • v-if和v-show最大区别在于是否增删DOM,后者只是控制display样式
  • 当v-if="true"时,vue会编译为虚拟DOM并缓存,带下次条件渲染直接使用

列表渲染

v-for

v-for 可遍历两种数据类型:数组和对象

v-for="(item, index) in array" v-for="(value, key, index) in object"


<div id="app">
	<template v-for="(item, index) in books">
		<p>{{ item.id }}</p>
		<p>{{ item.name }}</p>
	</template>
</div>

<script>
	var vm = new Vue({
		el: '#app',
		data: {
			books: [
			{
				id: 1,
				name: 'JavaScript'
			},
			{
				id: 2,
				name: 'Java'
			},
			{
				id: 3,
				name: 'Python'
			}]		
		}
	})

</script>
  • v-for 可以遍历数组,对象
  • 同一元素v-for优先级大于v-if,即先执行遍历,在执行判断
  • key值的作用要了解Vue更新DOM机制(后面写),即Diff算法。
  • 该算法有三个假设,其中一个是同级元素可以通过唯一id值区分,而key值的作用即作为这个id值,使更新(包括插入,删除,新增,交换等等)时,vue能够甄别到底是哪些虚拟DOM发生了变化,而不是笼统的批量更新。

列表更新(排序,过滤)

理解点: 数组常用方法

arr.sort() : 排序

// 控制台输出
vm.array.sort(function (a, b) {
    return a.price - b.price
})

arr.filter(): 过滤

vm.array.filter(function(value){
    return value.name.indexOf('xxx')
})
  • sort和filter最大区别,sort应用的是同一对象,filter复制了了一个新的数组,Vue感知不到,这里涉及到了变异方法
  • vue劫持了sort,做了封装,而filter却没有
  • Vue变异方法对原有数组方法进行封装,可以触发Vue更新

Vue变异方法有哪些?

push, pop, unshift, shitf, splice, reverse, sort

Vue数组没有封装的方法 filter,concat,slice,arr[i] = 'xxx'

如何解决没有封装方法执行响应呢?

第一种方法

vm.array = vm.array.filter(function(value){
    return value.name.indexOf('xxx')
})

第二种方法 vm.$set 可以动态响应属性

vm.$set(vm.list, index, value)

事件及表单

事件

事件:响应用户输入,返回指令输出

v-on指令,简写"@"

题目:使用v-on写一个加减器

事件修饰符 修饰符:用于部分改变事件逻辑,比如说阻止冒泡了,阻止浏览器默认行为等

  • .stop: 阻止事件冒泡
  • .self: 当触发事件的对象是自己本身才执行(@click.self="function")(添加.self后,只要event.target为绑定元素自身时执行回调函数)

事件修饰符 二

  • .capture: 监听器采用事件捕获模型 outer,inner 执行顺序:1,outer,inner

  • .once: 监听器触发一次后移除:点击一次监听器被清除

  • .passive:告诉浏览器该监听器是”主动的“.passive效果作用:是为了滑动更顺畅

这三个修饰符用的同一个方法

......

数据双向绑定 v-model

过程:修改视图层数据,DOM listening 修改model数据

v-model 本质是一个语法糖

<input type="text" v-model="text">
<span>{{text}}</span>
<script>
new Vue({
    el: '#app',
    data: {
        text: ''
    }
})
</script>

不用v-model如何实现数据双向绑定呢?

这里会用到 @input 监听input事件 oninput

<div id="app">
	<input type="text" name="test" :value="text" @input="handlerInput" />
	<span>{{text}}</span>
</div>

<script type="text/javascript">
new Vue({
	el: '#app',
	data: {
		text: 'test'
	},
	methods: {
		handlerInput: function (event) {
			this.text = event.target.value
		}
	}
})	
</script>

总结: v-model 仅仅是语法糖,实际动态绑定value属性,监听input事件,v-model 底层实现是通过模板编译的

v-model修饰符

  • .trim : 去除字符串前后的空格
  • .number : 将输入的转换为数字类型
  • .lazy: v-model.lazy="text"使用lazy修饰符后,修改不会马上改变,失去焦点后执行改变

file 文件上传空间

用到 onchange

<input type="file" @change="handlerFile">

<script>
new Vue({
    el: '#app',
    data: {
        file: null,
    },
    methods: {
        handlerFile: function (evt) {
            this.file = evt.target.files[0]
        }
    }
})
</script>

组件

什么是组件? 是一个功能块的集合,vue本身是由一个组件树组成的,header,content,footer都可以是一个组件。

为什么使用组件? 低耦合,便于维护,一处开发多处使用

组件注册

全局注册,局部注册

注意命名方式: 1,my-name 2,MyName

全局注册:

Vue.component('name', {
    template: '',
    data: () {
        return {
            
        }
    }
})

局部注册:

new Vue({
    el: '#app',
    compontents: {
        'my-name': {
            template: '',
            data () {
                return {
                    
                }
            }
        }
    }
})

父子组件间传参

props 传参

props用于父组件传参到子组件

<div id="app">
	<my-button :count="count"></my-button>
</div>

<!-- <script type="text/javascript" src="js/button.js"></script> -->
<script>
	new Vue({
		el: '#app',
		data: {
			count: 10
		},
		components: {
			'my-button': {
				data () {
					return {}
				},
				props: {
					count: {
						type: Number,
						default: 1,
						validator: function(value) {
							return value > 1 && value < 10
						}
					}
				},
				template: '<button>{{count}}</button>'
			}
		}
	})
</script>

注意:

注意props 参数 type(类型),default(默认值),validator(为数据添加限制)

props: {
    arg: {
        type: Number,
        default: 1,
        validator: function (value) {
            return value > 10 && value < 1
        }
    }
}

自定义事件

// 子组件
this.$emit(functionName, arg1, arg2)

// 父组件
<my-header @funcitonName="ParentFunctionName"></my-header>

methods : {
    ParentFunctionName: function (arg1, arg2) {
        // arg1, arg2
    }
}
  • this.$parent : 获取父组件
  • this.$children : 子组件数组

兄弟组件传参

file:///Users/xqls/Desktop/笔记/img/borther.png

这里用到 中间件: eventBus.js

var eventBus = new Vue()

vue.prototype.eventBus = eventBus

// child1
this.eventBus.$emit('send', arg)

// child2
created: () {
    var that = this
    this.eventBus.$on('send', function (text) {
        that.text = text
    })
}

注意:

  • eventBus 是vue的一个实例,this.eventBus.emit('send', arg) , $on分发给另一组件
  • created中that = this 是作用域问题,可以看js高程函数表达式那章节
  • vuex是状态管理器,可以实现组件间传值
  • props中定义的属性是只读的,如果修改vue会抛出错误。

插槽

什么是插槽? 组件内预留位置,在引用组件时插入元素块

官方解释: Vue 实现了一套内容分发的 API,这套 API 基于当前的 Web Components 规范草案,将 元素作为承载分发内容的出口。

语法?

<slot></slot>

// 具名插槽
<slot name="slotName"></slot>

实现一个例子?

<!-- 引用组件,插入内容 -->
<my-content>
    <p v-slot="header">my-header</p>
    <p v-slot="footer">my-footer</p>
</my-content>


<!-- 子组件模板 -->
<template id="content">
    <div>
        <slot name="header"></slot>
    </div>
    <div>
        <slot name="footer"></slot>
    </div>
</template>

// script 注册子组件
components: {
    'my-content': {
        template: '#content'
    }
}

自定义指令

自定义指令提供一种机制将数据的变化映射为 DOM 行为。

v-if, v-show, v-for, v-model, v-on, b-bind

  • 指令组成:v-指令名称:参数.修饰符 = 表达式
  • 指令注册:全局注册,局部注册
  • 指令都有生命周期,钩子函数

创建一个指令

Vue.directive('test', function(el, bindings, vnode))