Vue入门实例及思想(二)
样式绑定
class绑定:v-bind:class="expression";
style绑定:v-bind:style="expression"; expression允许接收的类型:字符串、数组、对象。
<p :class="clas">但是他不可能一直都是Vue的菜鸟。</p> <p :class="claess">这里是数组的两个类选择器的样式</p> <div :style="syt">Vue用对象方式绑定style样式</div> <div :style="{color:cname,fontSize: fsize}">Vue的直接对象方式绑定style样式</div>
修饰符(Vue通过.指令后缀来调用修饰符实现不同的功能)
(1).lazy:默认情况下, v-model在input事件中同步输入框的值与数据,但你可以添加一个修饰符lazy,从而转变为在change事件中同步。
(2).number:将用户的输入值转为 Number 类型。
(3) .trim:自动过滤用户输入的首尾空格。
<input type="text" v-model="content" placeholder="请输入" /><button @click="doMsg">发送</button><br /> <!-- 实例2:实现一次性按钮once --> <input type="text" v-model="content" placeholder="请输入" /><button @click.once="doMsg">只可发送一次</button><br /> <!-- 实例3:阻止表单提交prevent --> <form action="dsafaf.html" method="post" @submit.prevent="doSubmit" > <label for="bname">书本名称:</label><input type="text" name="bname" v-model="bname" /><br /> <label for="price">书本价格:</label><input type="text" name="price" v-model="price" /><br /> <input type="submit" value="新增" /><br /> </form> <!-- 修饰符可以串联,多个修饰符 --> <a href="" @click.stop.prevent="doMsg">修饰符可以串联</a> <!-- 阻止事件冒泡 --> <a href="" @click.stop="doMsg()">阻止单击事件冒泡</a> <!-- 只当事件在该元素本身(而不是子元素)触发时触发回调 --> <div v-on:click.self="doMsg" :class="claess">只在此区域发生的事件监听有效</div> <!-- 实例4:回车发送消息 --> <p> <input type="text" v-model="mesg" placeholder="请输入" @keyup.enter="sendMsg" /> </p>
表单(Vue中表单操作)
<label for="username">账号:</label><input type="text" name="username" v-model="uname" /><br /> <label for="password">密码:</label><input type="password" name="password" v-model="pwd" /><br /> <label for="sex">性别:</label> <input type="radio" v-model="sex" value="男" />男 <input type="radio" v-model="sex" value="女" />女<br /> <label for="city">城市:</label><select v-model="city" style="width: 165px;"> <option value="">--请选择--</option> <option v-for="ct in cites" :value="ct.value">{{ct.name}}</option> </select><br /> <label>爱好:</label><span v-for="h in hobbies"><input type="checkbox" v-model="hobby" :value='h.id'/>{{h.name}}</span><br /> <label for="text">备注:</label><textarea v-model="textara"></textarea><br /> <input type="checkbox" title="勾选代表你已同意相关协议" v-model="flag" /><a href="#">我已阅读并同意相关协议</a><br /> <button @click="doRegister" :disabled="!flag">注册</button>
自定义指令(除了Vue自带的指令,Vue也允许注册自定义指令。根据作用范围分为全局指令和局部指令。)
Vue.directive("focus",{});//全局指令
new Vue({
el:"#d1",
directives:{//局部指令
focus:{}
}
});
<!-- 局部 --> <div v-clog:abs.a.b="ts"> 此元素带有自定义的局部指令。 </div> <div ref='direct'> 此元素带有自定义的全局指令。 </div>
自定义指令的钩子函数:
bind: 只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作
inserted: 被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于 document 中)。
update: 被绑定元素所在的模板更新时调用,而不论绑定值是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新(详细的钩子函数参数见下)。
componentUpdated: 被绑定元素所在模板完成一次更新周期时调用。
unbind: 只调用一次, 指令与元素解绑时调用。
vue组件
组件(Component)是Vue最强大的功能之一;组件可以扩展HTML元素,封装可重用的代码;组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的界面都可以抽象为一个组件树。
全局组件:Vue.component(tagName, options),tagName为组件名,options为配置选项。
局部组件: new Vue({el:'#d1',components:{...}})
局部组件定义:
components:{//局部组件 'custom-button':{//自定义组件必须使用‘-’命名法。 template:"<button @click='doClick'>[局部组件]已点击{{count}}次</button>",//模板 data(){//为组件定义data属性必须使用函数方式返回属性,因为组件是多例模式。 return { count:0 } }, methods:{ doClick(){ ++this.count; console.log(this.textName); } }, props:{ textName:{//参数名 type:[String,Number,Object,Boolean],//可选参数 required:true//必选 }, },//传递参数必须使用驼峰命名法,并且此属性可以接受动态值。 } }
全局组件:
/* 全局组件 */ Vue.component('kfc-button',{ template:"<button @click='doThreeClick'>[全局组件]已点击{{count}}次</button>",//模板 data(){//为组件定义data属性必须使用函数方式返回属性,因为组件是多例模式。 return { count:0 } }, methods:{ doThreeClick(){ ++this.count; if(this.count%3===0){ console.log('子组件点击次数是3的倍数:次数为:',this.count); //利用$emit将子组件中的参数传递到父组件 this.$emit('three-click',this.count);//注意组件中定义的事件名称要与标签体中的事件名对应,调用的方法用参数接受传递的值,必须使用短横线分隔命名法 } } } });
HTML语言:
<p> <!-- 推荐使用短横线 --> <custom-button text-name="王五"></custom-button> </p> <h3>5.2 全局组件</h3> <p> <!-- 推荐使用短横线 --> <kfc-button ></kfc-button> </p>
传参数的问题,因为我们总有那种需要在组件之间传递数据的需求:
props是父组件用来传递数据的一个自定义属性。
<h3>5.3 传参问题</h3> <p> <!-- 父组件 -> 子组件通过props定义参数的方式 --> <!-- 只能使用短横线分隔命名法,因为HTML语言的元素属性(attribute)是不敏感大小写的,在浏览器编译时会自动将大写的属性转换为小写。 --> <custom-button :text-name="stu.name"></custom-button><!-- 这个stu为对象,可以调用方法或使用表达式 --> </p> <p> <!-- 子组件 -> 父组件通过$emit自定义事件传递参数的方式 --> <kfc-button @three-click="doComponentParent"></kfc-button> </p>
附上所有实例代码(可直接运行):
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Vue实例</title> <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.js" type="text/javascript" charset="utf-8"></script> <style type="text/css"> .cla{ color: crimson; font-size: 25px; } .cl1{ color: blueviolet; font-weight: bold; } .cl2{ background-color: darkorange; } </style> </head> <body> <div id="app"><!-- 挂载区域 --> <h2>{{ts}}</h2> <h2>1.样式绑定(表达式可以接收对象,数组,字符串)</h2> <h3>1.1 class绑定</h3> <!-- 传统方式 --> <p class="cla">这是一个Vue的菜鸟初学者。</p> <!-- Vue方式 --> <p :class="clas">但是他不可能一直都是Vue的菜鸟。</p> <p :class="claess">这里是数组的两个类选择器的样式</p> <h3>1.2 style绑定</h3> <!-- 传统方式 --> <div style="color: aqua;font-size: 25px;">传统方式的内联style样式</div> <!-- Vue方式 --> <div :style="syt">Vue用对象方式绑定style样式</div> <div :style="{color:cname,fontSize: fsize}">Vue的直接对象方式绑定style样式</div> <div :style="syt">Vue方式绑定style样式</div> <h2>2.修饰符(Vue通过.指令后缀来调用修饰符实现不同的功能)</h2> <h3>2.1 事件修饰符和按键修饰符</h3> <!-- 实例1:按钮点击事件 --> <p>{{msg}}</p> <input type="text" v-model="content" placeholder="请输入" /><button @click="doMsg">发送</button><br /> <!-- 实例2:实现一次性按钮once --> <input type="text" v-model="content" placeholder="请输入" /><button @click.once="doMsg">只可发送一次</button><br /> <!-- 实例3:阻止表单提交prevent --> <form action="dsafaf.html" method="post" @submit.prevent="doSubmit" > <label for="bname">书本名称:</label><input type="text" name="bname" v-model="bname" /><br /> <label for="price">书本价格:</label><input type="text" name="price" v-model="price" /><br /> <input type="submit" value="新增" /><br /> </form> <!-- 修饰符可以串联,多个修饰符 --> <a href="" @click.stop.prevent="doMsg">修饰符可以串联</a> <!-- 阻止事件冒泡 --> <a href="" @click.stop="doMsg()">阻止单击事件冒泡</a> <!-- 只当事件在该元素本身(而不是子元素)触发时触发回调 --> <div v-on:click.self="doMsg" :class="claess">只在此区域发生的事件监听有效</div> <!-- 实例4:回车发送消息 --> <p> <input type="text" v-model="mesg" placeholder="请输入" @keyup.enter="sendMsg" /> </p> <h2>3.表单</h2> <label for="username">账号:</label><input type="text" name="username" v-model="uname" /><br /> <label for="password">密码:</label><input type="password" name="password" v-model="pwd" /><br /> <label for="sex">性别:</label> <input type="radio" v-model="sex" value="男" />男 <input type="radio" v-model="sex" value="女" />女<br /> <label for="city">城市:</label><select v-model="city" style="width: 165px;"> <option value="">--请选择--</option> <option v-for="ct in cites" :value="ct.value">{{ct.name}}</option> </select><br /> <label>爱好:</label><span v-for="h in hobbies"><input type="checkbox" v-model="hobby" :value='h.id'/>{{h.name}}</span><br /> <label for="text">备注:</label><textarea v-model="textara"></textarea><br /> <input type="checkbox" title="勾选代表你已同意相关协议" v-model="flag" /><a href="#">我已阅读并同意相关协议</a><br /> <button @click="doRegister" :disabled="!flag">注册</button> <h2>4.自定义指令(除了Vue自带的指令,Vue也允许注册自定义指令。根据作用范围分为全局指令和局部指令。)</h2> <!-- 局部 --> <div v-clog:abs.a.b="ts"> 此元素带有自定义的局部指令。 </div> <div ref='direct'> 此元素带有自定义的全局指令。 </div> <h2>5.Vue组件(组件是Vue最强大的功能之一,可以扩展HTML元素,封装可重用的代码,分为全局组件和局部组件。)</h2> <h3>5.1 局部组件</h3> <p> <!-- 推荐使用短横线 --> <custom-button text-name="王五"></custom-button> </p> <h3>5.2 全局组件</h3> <p> <!-- 推荐使用短横线 --> <kfc-button ></kfc-button> </p> <h3>5.3 传参问题</h3> <p> <!-- 父组件 -> 子组件通过props定义参数的方式 --> <!-- 只能使用短横线分隔命名法,因为HTML语言的元素属性(attribute)是不敏感大小写的,在浏览器编译时会自动将大写的属性转换为小写。 --> <custom-button :text-name="stu.name"></custom-button><!-- 这个stu为对象,可以调用方法或使用表达式 --> </p> <p> <!-- 子组件 -> 父组件通过$emit自定义事件传递参数的方式 --> <kfc-button @three-click="doComponentParent"></kfc-button> </p> </div> </body> <script type="text/javascript"> /* 全局组件 */ Vue.component('kfc-button',{ template:"<button @click='doThreeClick'>[全局组件]已点击{{count}}次</button>",//模板 data(){//为组件定义data属性必须使用函数方式返回属性,因为组件是多例模式。 return { count:0 } }, methods:{ doThreeClick(){ ++this.count; if(this.count%3===0){ console.log('子组件点击次数是3的倍数:次数为:',this.count); //利用$emit将子组件中的参数传递到父组件 this.$emit('three-click',this.count);//注意组件中定义的事件名称要与标签体中的事件名对应,调用的方法用参数接受传递的值,必须使用短横线分隔命名法 } } } }); var vm = new Vue({ el:'#app', data:{ ts:new Date().getTime(), clas:'cla',//类选择器 syt:{//样式对象 color:'green', fontSize:'25px' }, cname:'red', fsize:'25px', claess:['cl1','cl2'],//一组类样式 msg:'', content: '', bname:'', price:'', mesg:'', cites:[//数组绑定下拉框 {name:'长沙',value:1}, {name:'岳阳',value:2}, {name:'株洲',value:3}, {name:'永州',value:4} ], uname:'', pwd:'', city:'', hobbies:[//绑定爱好复选框 {id:1,name:'游泳'}, {id:2,name:'健身'}, {id:3,name:'游戏'}, {id:4,name:'动漫'} ], hobby:[],//接收爱好数据 sex:'男', textara:'', flag:false,//定义阅读协议变量 stu:{id:1,name:'这里是参数哦'} }, methods:{ doMsg(){ this.msg = this.content; }, doSubmit(){ console.log(this.bname,this.price); }, sendMsg(){ this.msg = this.mesg; }, doRegister(){ let params = { username : this.uname, password : this.pwd, sex : this.sex, city:this.city, hobbies : this.hobby, textara : this.textara }; console.log(params); }, doComponentParent(value){ //子组件传的参数 console.log('【父组件接受参数:】'+value); } }, computed:{//计算 ok(){ return !this.flag; } }, directives:{//自定义局部指令 clog:{//注册指令 bind(el, binding, vnode) {//el:此节点,bingding:指令存储信息的对象,vnode:Vue编译生成的虚拟节点 let s = JSON.stringify; el.innerHTML = 'name: ' + s(binding.name) + '(指令名,不包括v-前缀)<br>' + 'value: ' + s(binding.value) + '(指令绑定的值)<br>' + 'expression: ' + s(binding.expression) + '(字符串形式的指令表达式)<br>' + 'argument: ' + s(binding.arg) + '(传给指令的参数,可选)<br>' + 'modifiers: ' + s(binding.modifiers) + '(包含所有修饰符的对象)<br>' + 'vnode keys(Vue 编译生成的虚拟节点信息。): ' + Object.keys(vnode).join(', '); }, inserted(){ console.log('这个元素被插入父节点!'); }, update(){ console.log('这个元素被更新了!'); }, componentUpdated(){ console.log('这个VNode 及其子 VNode 全部更新后调用。!'); }, unbind(){ console.log('元素已解绑!'); } } }, components:{//局部组件 'custom-button':{//自定义组件必须使用‘-’命名法。 template:"<button @click='doClick'>[局部组件]已点击{{count}}次</button>",//模板 data(){//为组件定义data属性必须使用函数方式返回属性,因为组件是多例模式。 return { count:0 } }, methods:{ doClick(){ ++this.count; console.log(this.textName); } }, props:{ textName:{//参数名 type:[String,Number,Object,Boolean],//可选参数 required:true//必选 }, },//传递参数必须使用驼峰命名法,并且此属性可以接受动态值。 } } }); /* 全局指令 */ Vue.directive('direct',{ inserted(){ console.log('自定义全局指令的元素被插入父节点!'); }, }); </script> </html>