vue基础

什么是VUE框架

前端刚开始是通过js来获取dom,后来Jquery的诞生对dom的操作进行了一系列的封装,但是又出现了满屏$的尴尬,所以又诞生了MVVM框架,MVVM模式即在后端MVC框架的View层再进行扩展,将View层分为Model(数据处理),View(界面展示),VM(控制器),VM层是M层和V层中间的桥梁,也就是对M层和V层发生变化的处理,随着MVVM框架的诞生,前端三大框架便出现了。
Vue是一套用于构建用户界面的渐进式框架,何为渐进式框架,也就是你可以整个系统采用vue来开发,也可以将其中的几个页面或组件采用vue开发。可以使用vue的全家桶,也可以只使用vue。可以使用vue的单文件开发,也可以使用webpack+vue。这点和react很不同,react采用jsx语法,要想使用react,必须使用webpack等前端构建工具来处理jsx语法。

vue模板引擎

vue采用模板的方式来渲染页面,通过自身的render函数将模板创建为虚拟dom,在此过程中与创建的vm对象绑定,检查模板中使用的变量,指令和事件等。

创建vue实例

var vm = new Vue({
    // 挂载对象,也可以理解为模板id
    el:'#id',
    // data中的属性名为声明的变量,属性值为变量值
    data:{
        name:'cccc',
        name2:'aaaa',
        list:['1','2','3'],
        obj:{
        	id:1,
        	name:'obk'
		}
    },
    // 方法
    methods:{
        getName(){
            console.log(this.name)
        }
    },
    // 计算属性,所计算的属性中使用的变量发生变化,会自动重新计算
    // 方法名可直接当做变量名使用
    computed:{
        fullName(){
            return this.name+this.name2
        }
    },
    // 侦听属性,将要侦听哪个变量,方法名就为变量名
    watch:{
        name(nv){
            console.log(nv)
        }
    }
})

插值表达式 {{ }}

<p>{{ name }}</p>

插值表达式内部可以写变量,还可以完成简单运算与逻辑 (避免页面闪烁,使用v-cloak指令)

指令

将vm中的变量或方法通过指令和某个元素绑定

v-text 插入文本
<p v-text="name"></p>
v-html 插入html
<p v-html="name"></p>
v-bind 属性绑定  用":"替代
<p v-bind:title="name"></p>
<p :title="name"></p>
v-on   事件绑定  用"@"替代
//给p标签绑定点击事件
<p v-on:click="getName"></p>
<p @click="getName"></p>
v-if 控制元素渲染与否
<p v-if="true">v-if绑定的元素会在渲染的时候控制是否渲染该元素,绑定值为Boolean</p>
v-show 控制元素显示与否
<p v-show="false">v-show绑定的元素会改变样式display为none或block来控制元素是否显示,元素频繁切换使用</p>
v-for 列表循环
// 循环列表 
<p v-for="(item,index) in list">{{ item }}</p>
// 迭代数字
<p v-for="count in 10">{{ count }}</p>
// 遍历对象
<p v-for="(val,key,index) in list">{{ 'key是'+key }}{{ 'val是'+val }}{{ 'index是'+index }}</p>
v-cloak 用于解决vue实例加载之前,页面显示插值符号的问题
[v-cloak]{
	display:none
}
<p v-cloak>{{ name }}</p>
v-model 数据双向绑定,用于form表单元素
<input type="text" v-model="name">
v-model实现原理为数据劫持,即Object.defineProperty(obj,key,options);
通过get和set控制读写该属性值时的事件
<input type="text" id="input">
<h4 id="output"></h4>
<button id="btn">点击</button>
<p v-for="count in 10">{{ count }}</p>
var input = document.getElementById('input');
var output = document.getElementById('output');
var btn = document.getElementById('btn');
var o = {
    value:''
};
input.onkeyup = function(){
    o.value = this.value;
}
btn.onclick = function(){
    o.value = '按钮点击'
}
Object.defineProperty(o,'value',{
    set(val){
        output.innerText = val;
        input.value = val;
    },
})

事件修饰符

在事件处理程序中调用 event.preventDefault() 或 event.stopPropagation() 是非常常见的需求。尽管我们可以在方法中轻松实现这点,但更好的方式是:方法只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。为了解决这个问题,Vue.js 为 v-on 提供了事件修饰符。

.stop  阻止事件冒泡
.prevent  阻止事件默认行为
.capture  事件从捕获阶段开始
.self    只有自身可以触发事件
.once  事件只执行一次
.passive 一些事件的默认事件会立即执行,例如:scroll
// 事件修饰符可以串联
// 但是要注意顺序
<p @click.prevent.self="getName">会阻止事件默认行为,包括其子元素的事件默认行为</p>
<p @click.self.prevent="getName">只会阻止自身事件的默认行为</p> 

按键修饰符

在监听键盘事件时,我们经常需要检查详细的按键。
Vue 提供了绝大多数常用的按键码的别名:(有一些按键在不同的浏览器会有不同的keyCode)
.enter
.tab
.delete (捕获“删除”和“退格”键)
.esc
.space
.up
.down
.left
.right
<p @keyup.enter="getName">可以直接使用vue提供的按键码的别名</p>
<p @keyup.13="getName">也可以直接使用keyCode</p>
//也可以使用Vue.config.keyCodes来定义自己的按键码别名;
Vue.config.keyCodes.f12 = 45;
// 将按键码为45的键取别名叫f12

鼠标按钮修饰符

.left   左键
.right  右键
.middle 中键

class与style绑定

new Vue({
	data:{
		className:'ceshi',
		styleObj:{
			'color':'red',
			'font-size':'16px'
			}
		}
	})
<p :class="className" :style="styleObj">因为使用属性绑定,所以属性值可以为一个变量或一个方法</p>
<p :class="['ceshi','ceshi1']">class也可以是一个数组,数组内要添加的类名</p>
<p :class="{'ceshi':true,'ceshi1':false}">class也可以是一个对象,属性值为true的属性名为要添加的类名</p>
<p :class="[isActive=='now'?'ceshi':'ceshi1']">class数组中也可以使用三元来选择类</p>
//同样的,style中也可以使用三元
<p :style="{'display':isActive==''now'?'block':'none'}"></p>

生命周期

每个实例从new Vue()开始到销毁的过程,都有一个完成的生命周期

var vm = new Vue({
    beforeCreate(){
        // 在实例初始化之前,在此阶段,无法访问到该实例中的data和methods
    },
    created(){
        // 实例初始化完成,在此阶段,可以操作实例中的data和methods
    },
    beforeMount(){
        // 实例挂载渲染之前,同上,此阶段,可以操作实例,但无法操作元素
    },
    mounted(){
        // 实例已经渲染挂载完成,不仅可以操作实例的data和methods,还可以操作元素
    },
    beforeDestroy(){
        // 实例销毁,解除绑定之前,此阶段还可以操作实例的data和methds以及元素
    },
    destroyed(){
        //实例销毁完成,无法操作实例
    },
    beforeUpdate(){
        // 当实例中的data被修改时,即将开始重新渲染
    },
    updated(){
        // 实例中的data修改完成,且dom重新渲染完成
    },
})
注:生命周期函数不能使用箭头函数来写

在这里插入图片描述

组件

组件的注册方式分为全局注册、局部注册以及在模块系统中注册。局部注册以及模块系统中注册需要在vm实例中挂载,而全局注册可以在任何使用实例的地方使用。使用方法即在模板在中直接使用组件名称标签。即<组件名称></组件名称>

全局注册
// 直接挂载在Vue构建函数上,可以在任何地方使用
Vue.component('组件名称',{
	template:'模板',
});
局部注册
// 局部注册的组件只能在该实例挂载的el中使用,如该例只能在#app中使用
new Vue({
    el:'#app',
    components:{
        'componentA':{
            template:'<div><p>这是componentA组件</p></div>'
        }
    }
})
模块系统注册

模块系统用户前端模块化开发过程中

// 导入需要注册的模块
import ComponentA from './components/ComponentA.vue';
export default {
	// 将导入的组件挂载在当前实例上
	components:{
		ComponentA,
	}
}

父子组件之间的传值和事件调用

只要存在组件,就必然存在数据和事件之间的互动。

// 父组件
<template>
	<div>
		// 给子组件绑定属性来传值,绑定事件来传递方法,ref用来直接获取子组件的实例
		<Component :parentMsg="msg" @parentClick="changeMsg" ref="component"></Component>
		<button @click="getChild">获取子组件的事件和值</button>
	</div>
</template>
<script>
import Component from './Component.vue';
export default {
	components:{
		Component,
	}
	data(){
		return {
			msg:'父组件的msg'
		}
	},
	methods:{
		changeMsg(){
			this.msg = '这是通过事件改变的父组件的值'
		},
		getChild(){
			// 通过this.$refs.组件名称.事件名称 可以直接调用子组件中的事件
			this.$refs.component.returnMsg();
			// 通过this.$refs.组件名称.变量 可以获取子组件的变量  可修改
			console.log('父组件可以直接获得子组件的值:' + this.$refs.component.selfMsg)
		}
	}
}
</scrpit>
// Component 页面
<template>
	<div>
		<p>父组件传过来的值:{{ parentMsg }}</p>
		<p>组件本身的值:{{ selfMsg }}</p>
		<button @click="getParentEvent">点击</button>
	</div>
</template>
<script>
export default {
	// 子组件中使用props来接收传值
	props:['parentMsg'],
	data(){
		return {
			selfMsg:'自身的值'
		}
	},
	methods:{
		getParentEvent(){
			// 使用this.$emit来触发传的方法,第二个参数为子组件给父组件的传值
			this.$emit('parentClick');
		},
		returnMsg(){
			console.log('通过父组件调用子组件方法拿到的值' + this.selfMsg);
		}
	}
}
</scrpit>

1.父组件给子组件传值,在子组件标签上绑定属性,属性值为要传的数据。在子组件中用props来接收,props是一个数组,数组内的每一项为字符串,是父组件在子组件标签上绑定的属性。
2.父组件给子组件传事件,在子组件标签上绑定事件,值为要传的事件。在子组件中用this.$emit(事件名,参数)来触发。这个参数可以作为子组件向父组件传值的途径。
3.父组件在子组件标签中声明ref属性,就可以直接使用this.$refs.xxx来获取子组件实例,从而直接获取子组件的变量或方法。

注:父子组件传值属于单向数据流,子组件内不允许修改。
注:父组件使用ref获取子组件的实例后,可以修改子组件中的变量

插槽

组件内可能有部分内容需要在使用的时候自定义其中的元素等,就需要插槽。

// 父组件页面
<template>
	<Component>
		// 插槽中可以是一段文字
		这是一个插槽
		// 也可以是html
		<p>这是一段html</p>
		// 也可以是组件
		<Component2></Component2>
		// 插槽中的作用域还在这个当前页面,并不是组件内
		<p>{{ msg }}</p>
	</Component>
</template>
<script>
import Component from './Component.vue';
import Component2 from './Component2.vue';
export default {
	components:{
		Component,
		Component2
	},
	data(){
		return {
			msg:'这是一段文字'
		}
	}
}
</script>
// Component组件页面
<template>
	<div>
		<p>插槽上部</p>
		// 在组件内需要使用插槽的位置,放置<slot></slot>标签
		<slot></slot>
		<p>插槽底部</p>
	</div>
</template>
默认内容
当组件内部有slot标签,但是在使用中未提供内容,此时就可以为插槽提供默认内容
<slot>slot标签内部的为默认的插槽内容</slot>
具名插槽
组件内部可能会有多个插槽,为了方便使内容和插槽对应,就提供了具名插槽
// 父组件页面
<template>
	<Component>
		// v-slot指令的参数为所对应的插槽的name,
		// v-slot指令的参数为default或没有template标签包裹的内容都会对应没有name的插槽
		// v-slot指令可以简写为#
		<template v-slot:header>
		    <h1>Here might be a page title</h1>
		 </template>
		
		 <p>A paragraph for the main content.</p>
		 <p>And another one.</p>
		
		 <template #footer>
		   <p>Here's some contact info</p>
		 </template>
	</Component>
</template>
// Component组件页面
<template>
	<div>
		<div>
			<p>头部</p>
			<slot name="header"></slot>
		</div>
		<div>
			<p>内容</p>
			<slot></slot>
		</div>
		<div>
			<p>底部</p>
			<slot name="footer"></slot>
		</div>
	</div>
</template>
作用域插槽
一般情况下,插槽的作用域只限于当前页面,但是实际开发中,需要实现插槽中引用组件中的变量
首先在插槽中对插槽进行数据绑定
然后在组件使用地方使用v-slot来获取该插槽所有绑定的属性。
// 父组件页面
<template>
	<Component>
		// 在使用组件的地方,使用v-slot指令绑定的值为一个object,object为插槽数据绑定的属性的集合
		// 可以对此处slotprops进行解构赋值来直接获取要使用的变量 v-slot="{user}"
		<template v-slot="slotprops">
			<p>{{ slotprops.user.name }}</p>
		</template>
	</Component>
</template>
// Component页面
<template>
	<div>
		// 对插槽进行数据绑定
		<slot :user="user"></slot>
	</div>
</template>
<script>
export default {
	data(){
		return {
			user:{
				name:'用户名'
			}
		}
	}
}
</script>

自定义指令

除了vue自带的一些指令外,vue还允许自定义指令来对dom进行底层操作。
同样的,指令也有局部注册和全局注册两种

全局注册
// 直接挂载到Vue构造函数上,可以在任何地方使用
Vue.directive('指令名',{
	bind(el,binding,vnode){},
	inserted(){},
	update(){},
});
局部注册
export default {
	directives:{
		// 慈湖的指令名,不带‘v-’
		'指令名':{
			// 指令与元素绑定时触发,此时元素还未插入到页面中
			// 此时只能操作dom元素的style,要想操作dom的事件,必须要等dom插入到页面中
			bind(el,binding){
				// el绑定该指令的dom元素,binding为指令的属性包括
				// name:指令名,不包括 v- 前缀。
				// value:指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2。
				// oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
				// expression:字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1"。
				// arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 "foo"。
				// modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }。
			},
			// 绑定该指令的元素插入到页面中触发,此时可以操作dom事件,如focus();click();
			inserted(el,binding){},
			// 所在组件的vnode发生更新
			update(el,binding){},
		}
	}
}

如果只关注bind和update两个钩子函数,也就是只操作dom的style,可以这样写

<p v-color="'red'">指令绑定的是一个变量,所以字符串要加''</p>
export default {
	directives:{
		'color'(el,binding){
			el.style.color = binding.value;
		}
	}
}

指令还可以添加参数 ,是指令更灵活

<p v-position:left="20">指令参数直接在指令后面写,此处left为参数</p>
<p v-postion:[direction]="20">指令参数可以为动态参数</p>
export default {
	directives:{
		'position'(el,binding){
			el.style[binding.arg]= binding.value;
		}
	},
	data(){
		direction:'right'
	}
}

自定义过滤器

vue.js允许自定义过滤器,可被用于常用文本格式化,常用于v-bind或插值表达式中。过滤器应该被添加在 JavaScript 表达式的尾部,由“管道”符号指示:

// 在插值表达式中
<p>{{ message | formatter }}</p>
// 在v-bind中
<div v-bind:id="rawId | formatId"></div>
全局注册
Vue.filter('过滤器名称',function(value){
	return value.toUpperCase();
})
局部注册
export default {
	filters:{
		// 过滤器的第一个参数为当前使用该过滤器的字符串,后面的参数可以自定义,在使用的时候传参
		'过滤器名称'(val){
			return val.toUpperCase();
		}
 	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值