目录
首先:我们先引入vue.js,我这里用的是:2.0版本的vue.js
如果不会使用的大家可以参考Vue的官方文档:Vue.js - 渐进式 JavaScript 框架 | Vue.js
- <script src="js/vue.js" type="text/javascript">script>
1.1 class绑定(已经在中定义的样式)
使用方式:v-bind:class="expression"
expression的类型:字符串、数组、对象
1.2 style绑定(属性style定义样式)
v-bind:style="expression"
expression的类型:字符串、数组、对象
案例演示:
- html>
- <html>
- <head>
- <meta charset="utf-8">
- <title>title>
-
- <script src="js/vue.js" type="text/javascript">script>
- head>
- <style>
- .cl{
- color: red;
- font-weight:bold;
- }
- .cl1{
- font-size: 35px;
- }
- style>
- <body>
-
- <div id="app">
- <h1>{{msg}}h1>
-
- <button @click="test">有种点我button><br/>
-
- <span class="cl">牛逼轰轰span>
-
- <span style="color:blue;font-weight:600;">牛逼轰轰span>
- <h1>Vue方式的style和class:1.字符串、2.数组、3.对象h1>
- <h2>1.字符串形式:h2>
- <div v-bind:style="{color:color,fontSize:size+'px'}">
- 飞雪连天射白鹿
- div>
-
- <h2>2.数组形式(class绑定):h2>
- <div :class="cls">
- 笑书神侠倚碧鸳
- div>
- <h2>3.对象形式(style绑定)h2>
- <div :style="styleObj">
- 青山横北郭,白水绕东城
- div>
-
-
- <script>
- var flag = false;
- //实例化:Vue
- var vue = new Vue({
- el:"#app",//定义边界:也就是Vue的作用范围
- data:function(){//此处定义vue的变量
- return {
- "msg":"张三",
- "color":'pink',
- "size":'50',
- "cls":['cl','cl1'],//以数组的形式套样式
- "styleObj":{//以对象形式套样式
- color:'green',
- fontSize:"26px",
- fontWeight:'blod'
- }
- }
- },
- //定义方法:
- methods:{
- test:function(){
- console.log(123);
- if(!flag){
- this.msg="老六";
- flag=true;
- }else{
- this.msg="张三";
- flag=false;
- }
-
- }
- }
- });
- script>
- body>
- html>
运行效果:
事件处理器: 事件监听可以使用v-on 指令
Vue通过由点(.)表示的指令后缀来调用修饰符
.stop
-
- <a v-on:click.stop="doThis">a>
.stop阻止冒泡事件案例:
- html>
-
- <html>
- <head>
- <meta charset="utf-8" />
- <title>作用:阻止事件冒泡title>
-
- <script src="js/vue.js" type="text/javascript">script>
- head>
- <body>
-
-
- <h1>阻止事件冒泡h1>
- <div @click="showMsg()" id="outSide" style="width:100px; height:100px; background:#000; padding:50px">
-
-
-
-
- <div @click.stop="Msg()" id="inSide" style="width:100px; height:100px; background:#CCC">div>
- div>
- <script type="text/javascript">
- //阻止事件冒泡后,你点击灰色盒子,整个过程只弹一次对话框了(注意与默认情况对比)
- var vue = new Vue({
- //el:定义作用域
- el:'#outSide',
- //data:专门定义v-bind/v-model/{{}}...中的属性
- data:function(){
- return{
- }
- },
- methods:{
- showMsg:function(){
- console.log("showMsg");
- },
- Msg:function(){
- console.log("Msg");
- }
- }
- });
- script>
- body>
- html>
效果演示:
什么是事件冒泡?(官方解释)
答:
在一个对象上触发某类事件(比如单击onclick事件),如果此对象定义了此事件的处理程序,那么此事件就会调用这个处理程序,如果没有定义此事件处理程序或者事件返回true,那么这个事件会向这个对象的父级对象传播,从里到外,直至它被处理(父级对象所有同类事件都将被激活),或者它到达了对象层次的最顶层,即document对象(有些浏览器是window)。
打个比方说:你在地方法院要上诉一件案子,如果地方没有处理此类案件的法院,地方相关部门会帮你继续往上级法院上诉,比如从市级到省级,直至到中央法院,最终使你的案件得以处理。
.prevent(一般作用于验证)
- <form v-on:submit.prevent="onSubmit">form>
-
- <a v-on:click.stop.prevent="doThat">a>
-
- <form v-on:submit.prevent>form>
.capture
-
- <div v-on:click.capture="doThis">...div>
.self
-
- <div v-on:click.self="doThat">...div>
.once
-
- <a v-on:click.once="doThis">a>
部分案例演示:
- html>
- <html>
- <head>
- <meta charset="utf-8">
- <title>title>
-
- <script src="js/vue.js" type="text/javascript">script>
- head>
- <body>
-
- <div id="app">
- <h1>{{msg}}h1>
-
-
- <h2>示例一:h2>
-
-
- <h2>示例二:h2>
- <button @click.once="dothis()">有种点我button><br/>
-
- <h2>示例三:h2>
- <form action="userLogin.action" @submit.prevent="doSumbit">
- 账号:<input type="text" v-model="msg" />
- <input type="submit" value="提交"/>
- form>
- div>
-
- <script>
- var flag = false;
- //实例化:Vue
- var vue = new Vue({
- el:"#app",//定义边界:也就是Vue的作用范围
- data:function(){//此处定义vue的变量
- return {
- "msg":"张三",
- }
- },
- //定义方法:
- methods:{
- dothis:function(){
- console.log(123);
- if(!flag){
- this.msg="老六";
- flag=true;
- }else{
- this.msg="张三";
- flag=false;
- }
- },
- doSumbit:function(){
- console.log("doSumbit");
- }
- }
- });
- script>
- body>
- html>
运行效果:
Vue允许为v-on在监听键盘事件时添加按键修饰符:
Vue为最常用的按键提供了别名
全部的按键别名:
- .enter
- .tab
- .delete (捕获 "删除" 和 "退格" 键)
- .esc
- .space
- .up
- .down
- .left
- .right
- .ctrl
- .alt
- .shift
- .meta
案例演示(其它按键效果的与此相同):
- html>
- <html>
- <head>
- <meta charset="utf-8">
- <title>title>
-
- <script src="js/vue.js" type="text/javascript">script>
- head>
- <body>
-
- <div id="app">
-
-
- <input type="text" @keydown.enter="doKeyDown()" />
- div>
-
- <script>
- var flag = false;
- //实例化:Vue
- var vue = new Vue({
- el:"#app",//定义边界:也就是Vue的作用范围
- data:function(){//此处定义vue的变量
- return {
- //"msg":"张三",
- }
- },
- //定义方法:
- methods:{
- doKeyDown:function(){
- console.log("doKeyDown");
- }
- }
- });
- script>
- body>
- html>
运行结果:
修饰符
.lazy
默认情况下, v-model在input事件中同步输入框的值与数据,但你可以添加一个修饰符lazy,从而转变为在change事件中同步
.number 使用方式如下(以下修饰符使用方式与此一致):
账号:<input type="text" v-model.number="username" /><br/>
将用户的输入值转为 Number 类型
.trim
自动过滤用户输入的首尾空格
案例演示:
- html>
- <html>
- <head>
- <meta charset="utf-8">
- <title>title>
-
- <script src="js/vue.js" type="text/javascript">script>
- head>
- <body>
-
- <div id="app">
-
- 账号:<input type="text" v-model.number="username" /><br/>
- 密码:<input type="password" v-model="password" /><br/>
- 性别:<input type="radio" v-model="sex" value="1" />男
- <input type="radio" v-model="sex" value="2" />女<br/>
- 籍贯:<select v-model="areaSelected">
- <option value=''>---请选择---option>
- <option v-for="a in area" :value="a.id">
- {{a.name}}
- option>
- select><br/>
-
- 爱好:
- <span v-for="h in hobbies">
-
- <input type="checkbox" v-model="hobby" :value="h.id"/>
- {{h.name}}
- span><br/>
- 备注:<textarea v-model="remark">textarea><br/>
- <div><input type="checkbox" v-model="flag" />阅读以上内容div>
-
- <button @click="doRegister" :disabled="!flag">注册button>
-
-
-
- <script>
- var flag = false;
- //实例化:Vue
- var vue = new Vue({
- el:"#app",//定义边界:也就是Vue的作用范围
- data:function(){//此处定义vue的变量
- return {
- username:'',
- password:'',
- sex:'1',
- area:[
- {id:1,name:'长沙'},
- {id:2,name:'株洲'},
- {id:3,name:'湘潭'},
- {id:4,name:'衡阳'}
- ],
- areaSelected:'',
- hobbies:[
- {id:1,name:'听音乐'},
- {id:2,name:'羽毛球'},
- {id:3,name:'下棋'}
- ],
- hobby:[],
- remark:'',
- flag:false
- }
- },
- //定义方法:
- methods:{
- doRegister:function(){
- let params={
- username:this.username,
- password:this.password,
- sex:this.sex,
- area:this.areaSelected,
- hobby:this.hobby,
- remark:this.remark
- };
- console.log(params);
- }
- }
- });
- script>
- body>
- html>
效果展示:
除了Vue自带的指令(v-on|v-model)等, Vue也允许注册自定义指令,根据作用范围又分为:
全局指令/局部指令
- Vue.directive("focus",{});//全局指令
- new Vue({
- el:"#d1",
- directives:{//局部指令
- focus:{}
- }
- });
案例演示:
- html>
- <html>
- <head>
- <meta charset="utf-8">
- <title>title>
-
- <script src="js/vue.js" type="text/javascript">script>
- head>
- <body>
-
- <div id="app">
- <h2>局部指令h2>
- <div v-fos="name">
- div>
- <h2>全局指令h2>
- <div v-kfc="22">div>
- div>
- <script>
- var flag = false;
- /* 全局指令 :作用域更大,都可以调用到*/
- Vue.directive('kfc',{
- inserted:function(el,binding){
- console.log(el);
- console.log(binding);
- }
- })
- //实例化:Vue
- var vue = new Vue({
- el:"#app",//定义边界:也就是Vue的作用范围
- data:function(){//此处定义vue的变量
- return {
- name:'zs'
- }
- },
- //定义方法:
- methods:{
- },
- //自定义指令:仅在实例Vue里被调用
- directives:{
- fos:{
- inserted:function(el,binding){//钩子函数
- //el:打印当前所在的元素
- console.log(el);
- //打印的基本信息
- console.log(binding);
- }
- }
- }
- });
- script>
- body>
- html>
效果展示:
指令须知:
指令定义函数提供了几个钩子函数用来帮助实现功能(可选)
bind: 只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作
inserted: 被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于 document 中)。
update: 被绑定元素所在的模板更新时调用,而不论绑定值是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新(详细的钩子函数参数见下)。
componentUpdated: 被绑定元素所在模板完成一次更新周期时调用。
unbind: 只调用一次, 指令与元素解绑时调用。钩子函数的参数有:
el: 指令所绑定的元素,可以用来直接操作 DOM 。
binding: 一个对象,包含以下属性:
name: 指令名,不包括 v- 前缀。
value: 指令的绑定值, 例如: v-my-directive="1 + 1", value 的值是 2。
oldValue: 指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
expression: 绑定值的表达式或变量名。 例如 v-my-directive="1 + 1" , expression 的值是 "1 + 1"。
arg: 传给指令的参数。例如 v-my-directive:foo, arg 的值是 "foo"。
modifiers: 一个包含修饰符的对象。 例如: v-my-directive.foo.bar, 修饰符对象 modifiers 的值是 { foo: true, bar: true }。
vnode: Vue 编译生成的虚拟节点。
oldVnode: 上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。
组件的作用:一个独立页面(组件),封装重用代码的目的,一个完整的页面由n多个组件组成。
组件(Component)是Vue最强大的功能之一
组件可以扩展HTML元素,封装可重用的代码
组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的界面都可以抽象为一个组件树
全局组件:Vue.component(tagName, options),tagName为组件名,options为配置选项。
局部组件: new Vue({el:'#d1',components:{...}})
注册后,我们可以使用以下方式来调用组件:
props是父组件用来传递数据的一个自定义属性。
父组件的数据需要通过props把数据传给子组件,子组件需要显式地用props选项声明 "prop"
注1:因为组件是可复用的 Vue 实例,所以它们与 new Vue 接收相同的选项,例如 data、computed、watch、methods
以及生命周期钩子等。仅有的例外是像el这样根实例特有的选项。
注2:当我们定义这个
组件时,你可能会发现它的data并不是像这样直接提供一个对象
data: {
count: 0
}取而代之的是,一个组件的data选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝:
data: function () {
return {
count: 0
}
}
注3:定义组件名的方式有两种
短横线分隔命名(建议使用)
Vue.component('my-component-name', { /* ... */ }),引用方式:首字母大写命名
Vue.component('MyComponentName', { /* ... */ }),引用方式:和 都是可接受的 注4:HTML 中的特性名是大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符。这意味着当你使用 DOM 中的模板时,
camelCase (驼峰命名法) 的 prop 名需要使用其等价的 kebab-case (短横线分隔命名) 命名:
props: ['postTitle'],注5:props: ['title', 'likes', 'isPublished', 'commentIds', 'author']
希望每个 prop 都有指定的值类型
props: {
title: String,
likes: Number,
isPublished: Boolean,
commentIds: Array,
author: Object,
callback: Function,
contactsPromise: Promise // or any other constructor
}
案例演示:
- html>
- <html>
- <head>
- <meta charset="utf-8">
- <title>title>
-
- <script src="js/vue.js" type="text/javascript">script>
- head>
- <body>
-
-
- <div id="app">
- <h2>局部组件&全局组件h2>
-
-
-
-
- <kfc-button @three-click="doTest">kfc-button>
-
- <ff-button :firstName="name">ff-button>
- div>
-
-
- <script>
- var flag = false;
- /* 全局组件 :作用域更大,都可以调用到*/
- Vue.component('ff-button',{
- //有且只有一个根节点
- //有可能template是一个表格
- template:"
[全局组件]
", - props:['firstName'],
- //在自定义组件中请使用函数方法
- data:function(){
- return{
- count:0
- }
- },
- methods:{
- doClick:function(){
- console.log("全局组件:从父到子传过来的属性值:"+this.firstName);
- this.count++;
- }
- }
- });
-
- //实例化:Vue
- //组件的定义:
- //1)全局组件:Vue.component(组件名称,配置选项)
- //2)局部组件:new Vue({...,components{...}})
- //全局组件和局部组件的父组件都是new Vue();Vue实例
-
- //组件的命名:
- //1)短横线命名法:kfc-button
- //2)首字符大写命名法(帕斯卡):KfcButton
-
- //什么是驼峰命名法:kfcButton
- //组件之间的传参
- //1)父到子:采用props属性方式传递参数,允许传递基本类型、对象及动态值(类似:一瓶水,我们需要往里面注入一些东西,我们就需要打开盖子(开个孔(入口)))
- //2)子到父:采用事件方式传递参数,$emit
- var vue = new Vue({
- el:"#app",//定义边界:也就是Vue的作用范围
- data:function(){//此处定义vue的变量
- return {
- name:'zs'
- }
- },
- //定义方法:
- methods:{
- doTest:function(c){
- console.log("从子到父传过来的属性值:"+c);
- }
- },
- //局部组件
- components:{
- 'kfc-button':{
- //有且只有一个根节点
- //有可能template是一个表格
- /* template:"
[局部组件]
", */ - /* 子传父形式 */
- template:"
[局部组件]
", - props:['firstName'],
- //在自定义组件中请使用函数方法
- data:function(){
- return{
- count:0
- }
- },
- methods:{
- doClick:function(){
- this.count++;
- },
- //子到父测试
- doThreeClick:function(){
- this.count++;
- if(this.count%3==0){
- console.log("局部组件:从父到子传过来的属性值:"+this.firstName);
- console.log("[局部组件]count=%s",this.count);
- //将事件传过去
- this.$emit('three-click',this.count);
- }
- }
- }
- }
- }
- });
- script>
- body>
- html>
效果展示:
组件文件:.vue 后缀结尾
形式例如:
- <template>
- template>
-
- <script>
- /* 自定义组件js代码存放
- 作用范围:仅在当前Vue实例(当前组件内有效)
- 例如:
- data:function(){
- return{
- count:0
- }
- },
- methods:{
- doClick:function(){
- this.count++;
- }
- }
-
- */
- script>
-
- <style>
- /* 组件样式 */
- style>
组件传值作用:用于主页面左侧菜单折叠的参数传递
监听事件:$on(eventName)
触发事件:$emit(eventName)注1:Vue自定义事件是为组件间通信设计
vue中父组件通过prop传递数据给子组件,而想要将子组件的数据传递给父组件,则可以通过自定义事件的绑定
父Vue实例->Vue实例,通过prop传递数据
子Vue实例->父Vue实例,通过事件传递数据注2:事件名
不同于组件和prop,事件名不存在任何自动化的大小写转换。而是触发的事件名需要完全匹配监听这个事件所用的名称
建议使用“短横线分隔命名”,例如:three-click
# 只配合一个事件名使用 $emit:
- <div id="emit-example-simple">
- <welcome-button v-on:welcome="sayHi">welcome-button>
- div>
- <script>
- Vue.component('welcome-button', {
- template: `
-
- Click me to be welcomed
-
- `
- })
- new Vue({
- el: '#emit-example-simple',
- methods: {
- sayHi: function () {
- alert('Hi!')
- }
- }
- })
- script>
# 配合额外的参数使用 $emit:
- <div id="app">
- <div id="counter-event-example">
-
- <magic-eight-ball v-on:give-advice="showAdvice">welcome-button>
- div>
- div>
-
- <script>
- Vue.component("magic-eight-ball", {
- data:function(){
- return{
- possibleAdvice:["Yes","No","Maybe"]
- }
- },
- methods:{
- giveAdvice:function(){
- var randomAdviceIndex=Math.floor(Math.random()*this.possibleAdvice.length)
- this.$emit('give-advice',this.possibleAdvice[randomAdviceIndex])
- }
- },
- template: `
-
- Click me to for advice
-
- `
- });
- new Vue({
- el: '#counter-event-example',
- methods: {
- showAdvice: function (advice) {
- alert(advice)
- }
- }
- })
- script>
- 数据传递
-
- <div id="app">
- <parent>parent>
- div>
- <script>
- //定义局部子组件
- var childNode={
- template:`
- <div class="child">
- <div>
- <span>子组件数据span>
- <input v-model="childMsg" v-on:input="data">
- div>
- <p>{{childMsg}}p>
- div>
- `,
- data(){
- return {
- childMsg:"我不猜"
- }
- },
- methods:{
- data(){
- this.$emit('pass-data',this.childMsg)
- }
- }
- }
- //定义父组件
- var parentNode={
- template:`
- <div class="parent">
- <div>
- <span>父组件数据span>
- <input v-model="msg">
- div>
- <p>{{msg}}p>
- <child v-on:pass-data="getData">child>
- div>
- `,
- components:{
- 'child':childNode
- },
- data(){
- return {
- msg:"你猜"
- }
- },
- methods:{
- getData(value){
- this.msg=value;
- }
- }
- }
- new Vue({
- el: '#app',
- components:{
- 'parent':parentNode
- }
- })
- script>
效果演示:
子组件通过数据绑定将自身的信息传递给父组件,从而改变父组件内容。
注:
现在在组件上使用 v-on 只会监听自定义事件 (组件用 $emit 触发的事件)。如果要监听根元素的原生事件,可以使用 .native 修饰符,比如:
<my-component v-on:click.native="doSomething">my-component>