好记性不如烂笔头
博客已迁移到CSDN《https://blog.csdn.net/qq_33375499》
最近公司新出一个框架,采用的是前后端分离的开发方式,后端用的是springboot+mybatis(还有额外的zk、缓存、日志等待),前端采用的是vue+es6,由于以前对vue只知其名,不知其意,今天主动去学习了一下vue的基本语法,在此做个记录,方便自己平时查阅及知识分享。如果大家想详细了解,请查阅 https://vuejs.bootcss.com/v2/guide/
vue 的基本语法为:
<div id="app"> ...... </div> Vue({ el:"#app" , ..... })
其中,el中相关联的id为app的节点,我们称之为挂载点,而挂载点中的内容,称为模版(template)。
1 插值
文本设值:使用文本来进行数据绑定最常见的就是使用Mustache语法(双大括号),也称之为插值表达式,如{{msg}}。该语法不能进行HTML内容的设值,所有的内容都会被编译成文本格式。v-text指令同样能够达到相同效果。
HTML设值: 使用 v-html='msg'的方式,将内容输出为真正的HTML。如:
<span v-html="rawHtml"></span>
内嵌表达式:在vue中,对于所有的数据绑定,都提供了JavaScript表达式支持,如:{{msg === 'yes'?'是':'否'}}、{{msg + ',你好!'}}、{{msg.split('').reverse().toString()}}
2 指令
在vue中,指令(Directives)是带有 v- 前缀的特殊特性。指令的职责是,当表达式值改变时,将其产生的连带影响,响应式的作用域DOM。如: v-if='seen' (seen为true时执行)
一些指令能够接收一个参数,在指令名称之后以冒号 表示,如:
// 绑定href属性 v-bind:href='https://www.cnblogs.com/www-123456/' // 绑定click事件 v-on:click='click()'
v-bind:常用于对元素属性的绑定添加。可以缩写为 :href='xxx'
v-click:常用于对元素事件进行绑定添加。可以缩写为 @click='xxx'
3 计算属性
模版内的表达式非常便利,但是放入太多,会使代码变得难以理解,并且不能重用(程序猿都是懒人)。所以,对于任何复杂逻辑,你都应该使用计算属性。
计算属性时基于它们的依赖进行缓存。只有相关依赖发生改变时,它们才会重新求值。这意味这只要值没有改变,多次访问同一个属性值,计算属性会立即返回之前的计算结果,而不必再次执行函数。
<div> <p>{{msg}}</p> <p>{{reversedMsg}}</p> </div> var vm = new Vue({ el: '#app', data: { msg: 'Hello' }, computed: { // 计算属性的 getter reversedMessage: function () { // `this` 指向 vm 实例 return this.msg.split('').reverse().join('') } } })
vue 为计算属性提供了getter、setter。计算属性默认只有getter方法。
computed: { fullName: { // getter get: function () { return this.firstName + ' ' + this.lastName }, // setter set: function (newValue) { var names = newValue.split(' ') this.firstName = names[0] this.lastName = names[names.length - 1] } } }
4 侦听器
通过 vue 的 watch 选项,来相应数据的变化。当要在数据变化时执行异步式或开销较大的操作时,这个方式最有用。如:
<script> var vm= new Vue({ el: '#app', data: { question: '', answer: 'I cannot give you an answer until you ask a question!' }, watch: { // 如果 `question` 发生改变,这个函数就会运行 question: function (newQuestion, oldQuestion) { this.answer = 'Waiting for you to stop typing...' this.debouncedGetAnswer() } } }) </script>
5 class与style绑定
操作元素的class列表和内联样式是数据绑定的一个常见需求。因为他们都为属性。所有可以用 v-bind 来进行绑定: 只需要通过表达式计算出字符串结果即可。使用 v-bind 来对class 和 style 进行绑定是,除了字符串之外,还可以hi对象和数组。如:
v-bind:class="{active:isActive,'text-dange':hasError}" // data为:data():{isActive:true,hasError:false} // 结果为:class='active' v-bind:class="[activeClass, textClass]" v-bind:style="{color:activeColor,fontSize:fonsize}" v-bind:style="styleObj" // data为:data():{styleObj:{color:'red',fontsize:'14px'}}
6 条件渲染
v-if:当值为true时,该元素快渲染
v-else-if:vue 2.1.0新增
v-else
<div v-if="type==='A'">A</div>
<div v-else-if="type==='B'">B</div>
<div v-else>other</div>
v-show:
<div v-show="yes">yes</div>
v-if 是惰性的,只有当条件为true,才会开始渲染条件快。v-show在初始化就进行了渲染,只是切换元素效果进行宣示与隐藏。
7 列表渲染
使用 v-for 指令遍历数组和对象,语法如下:
// items 为一个可遍历对象 v-for="item in items" v-for="(item, index) in items" v-for="item of items" // object为 key/value 格式对象 v-for="value in object" v-for='(key, value) in object'
8 事件处理
v-on:click="count += 1" v-on:click='click()' var vm=new Vue({ el:"#app", data:{count:1} , methods:{ click:function(){ this.count += 1; } } })
事件修饰符:.stop .prevent .capture .self .once .passive
<!-- 阻止单击事件继续传播 --> <a v-on:click.stop="doThis"></a> <!-- 提交事件不再重载页面 --> <form v-on:submit.prevent="onSubmit"></form> <!-- 修饰符可以串联 --> <a v-on:click.stop.prevent="doThat"></a> <!-- 只有修饰符 --> <form v-on:submit.prevent></form> <!-- 添加事件监听器时使用事件捕获模式 --> <!-- 即元素自身触发的事件先在此处理,然后才交由内部元素进行处理 --> <div v-on:click.capture="doThis">...</div> <!-- 只当在 event.target 是当前元素自身时触发处理函数 --> <!-- 即事件不是从内部元素触发的 --> <div v-on:click.self="doThat">...</div> <!-- 点击事件将只会触发一次 --> <a v-on:click.once="doThis"></a> <!-- 滚动事件的默认行为 (即滚动行为) 将会立即触发 --> <!-- 而不会等待 `onScroll` 完成 --> <!-- 这其中包含 `event.preventDefault()` 的情况 --> <div v-on:scroll.passive="onScroll">...</div>
使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用 v-on:click.prevent.self 会阻止所有的点击,而 v-on:click.self.prevent 只会阻止对元素自身的点击。
不要把.passive
和.prevent
一起使用,因为.prevent
将会被忽略,同时浏览器可能会向你展示一个警告。请记住,.passive
会告诉浏览器你不想阻止事件的默认行为。
按键修饰符:.enter .tab .delete .esc .space .up .down .left .right
<!-- 只有在 `keyCode` 是 13 时调用 `vm.submit()` --> <input v-on:keyup.13="submit"> <!-- 同上 --> <input v-on:keyup.enter="submit"> <!-- 缩写语法 --> <input @keyup.enter="submit"> // 可以通过全局 config.keyCodes 对象自定义按键修饰符别名,可以使用 `v-on:keyup.f1` Vue.config.keyCodes.f1 = 112
鼠标按键修饰符:.left .right .middle
8 表单输入绑定
基础语法:
v-model="value1" -> 双向绑定
值绑定:
// 当选中是,vm.toggle == 'yes',当没有选中是 vm.toggle == 'no' <input type="checkbox" v-model="toggle" true-value="yes" false-value="no" />
<input type="radio" id="one" value="One" v-model="picked"> <select v-model="selected"> <option disabled value="">请选择</option> <option>A</option> <option>B</option> <option>C</option>
</select>
修饰符:
<!-- 在“change”时而非“input”时更新 --> <input v-model.lazy="msg" > <!--如果想自动将用户的输入值转为数值类型,可以给 v-model 添加 number 修饰符--> <input v-model.number="age" type="number"> <!--如果要自动过滤用户输入的首尾空白字符,可以给 v-model 添加 trim 修饰符--> <input v-model.trim="msg">
9 组件基础
每一个组件都是一个Vue实例。这句话非常重要。
组件的注册方式分为两种,全局注册、局部注册。
全局注册:注册之后可以用在任何新创建的Vue根实例(new Vue)的模版中。在所有子组件中也是如此。比如:
Vue.component('component-a', { /* ... */ }) Vue.component('component-b', { /* ... */ }) Vue.component('component-c', { /* ... */ }) new Vue({ el: '#app' }) <div id="app"> <component-a></component-a> <component-b>
<component-c></component-c>
</component-b>
</div>
局部注册:通过一个普通的JavaScript对象来定义组件,然后在父组件中使用components 选项来定义你想要使用的组件。注意:局部注册的组件在其子组件中不可用。
var ComponentA = { /* ... */ } var ComponentB = { /* ... */ } var ComponentC = { /* ... */ } new Vue({ el: '#app', components: { 'component-a': ComponentA, 'component-b': ComponentB } })
9.1 传参
父组件向子组件传值是通过属性的方法,即使用父组件的属性,在子组件中通过props来接受。
子组件向父组件传递参数是通过发布订阅方式。子组件发布一个事件(this.$emit(event,arg))。父组件监听子组件方法的事件 @event。
this.$emit(event,arg):绑定一个自定义事件event,当这个语句被执行时,会将参数arg 传递给父组件,父组件通过 @event 监听并接受该参数。
下面是我自己写的一个列子:
<!DOCTYPE html> <html> <head> <title>vue学习</title> <script type="text/javascript" src="./vue.js"></script> </head> <body> <div id="app"> <input type="text" name="text" v-model="inputData" /> <button @click="headearClick">提交</button> <ul> <li v-for="item in list" :title="item">{{item}}</li> </ul> <br /> <br /> 要删除的值:<input type="number" v-model.number="number" /> <component-a :data="number" @delete="headearDelete"></component-a> </div> </body> <script type="text/javascript"> Vue.component("component-a", { props: ["data","index"], template: '<button @click="click" title="删除无序列表中与输入框值相等">删除</button>', methods: { click: function() { this.$emit("delete", this.data); } } }) new Vue({ el: "#app", data: { inputData: "", list: [], number: '' }, methods: { headearClick() { if(this.inputData != ""){ this.list.push(this.inputData); this.inputData = ""; } }, headearDelete(data) { var arr = []; for (var i = 0, len = this.list.length; i < len; i++) { if(data != this.list[i]){ arr.push(this.list[i]); } } this.list = arr; this.number = ''; } } }) </script> </html>
注意:我在该代码中引入了vue.js ,小伙伴们可以在 vue的教程https://cn.vuejs.org/v2/guide/installation.html 中查看下载,即 https://vuejs.org/js/vue.js