1.vue.js是什么
vue.js是一套构建用户界面的渐进式前端框架,它采用自底向上增量开发的设计,核心库只关注视图层。
2.模板语法
1)插值
文本:使用双大括号语法
<span>插入文本{{message}}</span>
当使用v-once时,插入的值为一次性插值,当数据发生变化时,插入的值并不会随着数据的变化而变化。注意:这样插入的值同样会影响到节点上绑定的所有的数据。
原始html:双大括号会将数据解释为普通文本,而非html,在这里使用指令v-html
<body>
<div id="app">
<p>{{rawHtml}}</p>
<p>使用v-html指令<span v-html="rawHtml"></span></p>
</div>
</body>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
var app=new Vue({
el:"#app",
data:{
rawHtml:"<span style='color:red'>html标签中的文本</span>"
}
})
</script>
特性:使用v-bind作用html上的特性
<body>
<div id="app">
<button v-bind:disabled="isButtonDisabled">按钮</button>
</div>
</body>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
var app=new Vue({
el:"#app",
data:{
isButtonDisabled:true ,
}
})
</script>
isButtonDisabled的值为null、undefined或者false时,button中的disabled属性是不会显示在html节点上的。
使用javascript表达式
<p>{{number+3}}</p>
<p>{ok?"yes":"no"}</p>
<p>{message.split("").reverse().join("")}</p>
指令:是带有v-前缀的特殊属性。指令的职责是,当表达式的值改变时,会连带性的影响DOM。
常用的指令有:v-bind v-if v-for v-model v-on等等
有一些指令是可以接受参数的,即参数在指令后面用冒号表示如
<a v-bind:href="url"></a>
<button v-on:click="test"></button>
v-on中的click参数就是dom上监听的事件名。
指令中的修饰符是以半角句号 . 指明的特殊后缀,用于指出一个指令应该以特殊方式绑定。如 .prevent告诉v-on调用event.preventDefalut
缩写:常用的指令如 v-on:click="test" 缩写为 @click="test" v-bind:href="url" 缩写为 :href="url"
3.计算属性和观察者
1)计算属性:对于复杂的逻辑,模板内的表达式会让模板过于沉重难以维护,此时就应该在全局变量vue中声明一个计算属性来进行计算
实例如下,将一个hello这个单词进行反转倒序排列
<body>
<div id="app">
<p>没有添加计算属性前:{{message}}</p>
<p>添加计算属性后:{{reverseMessage}}</p>
</div>
</body>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
var app=new Vue({
el:"#app",
data:{
message:"hello"
},
computed:{
reverseMessage:function(){
return this.message.split("").reverse().join("");
}
}
})
</script>
运行后的结果为:
没有添加计算属性前:hello
添加计算属性后:olleh
2)计算属性的缓存vs方法对于上面的例子使用组件中方法
methods: {
reverseMessage: function () {
return this.message.split('').reverse().join('')
}
}
可以达到和计算属性同样的效果,但是计算属性是基于他们的依赖进行缓存的。计算属性只有在他相关的依赖发生变化时才会进行求值,这就意味着message没有发生变化,reverseMessage会立即返回之前的计算结果,而不必再次执行函数求值。
相比之下,每一进行重新渲染时,调用方法则会再次执行函数求值,而只要计算属性相关的依赖没有发生变化,则会直接返回缓存,对于那些需要缓存的数据有很大的优势。
3)计算属性vs侦听属性
当有一些数据会随着其他数据的变化而变化时,不是使用命令式的watch回调。
使用watch回调实例如下:
<body>
<div id="app">
<p>{{fullName}}</p>
</div>
</body>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
var app=new Vue({
el:"#app",
data:{
firstName:"food",
lastName:"bar",
fullName:"food bar"
},
watch:{
firstName:function(val){
this.fullName=val+" "+this.lastName;
},
lastName:function(val){
this.fullName=this.firstName+" "+val;
}
}
})
</script>
上述代码是命令式且重复的,换用侦听属性实例如下:
<body>
<div id="app">
<p>{{fullName}}</p>
</div>
</body>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
var app=new Vue({
el:"#app",
data:{
firstName:"food",
lastName:"bar",
},
computed:{
fullName:function(){
return this.firstName+" "+this.lastName;
}
}
})
</script>
相比较计算属性要更好一些
4)侦听器
虽然计算属性在大多数情况下更合适,但是有的时候也需要一个自定义的侦听器。着就是为什么Vue通过watch选项提供了一个更加通用的方法来响应数据的变化。当需要在数据变化时执行异步或者开销较大的操作时,这个方法是最有用的。
实例如下
<div id="app">
<p>Do you like me?
<input v-model="question">
</p>
<p>{{answer}}</p>
</div>
</body>
<!-- 因为 AJAX 库和通用工具的生态已经相当丰富,Vue 核心代码没有重复 -->
<!-- 提供这些功能以保持精简。这也可以让你自由选择自己更熟悉的工具。 -->
<script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/lodash@4.13.1/lodash.min.js"></script>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
var app=new Vue({
el:"#app",
data:{
question:"",
answer:"I can not give you a answer"
},
watch:{
question:function(newQuestion){
this.answer="let me thinking..."
this.getAnswer();
}
},
methods: {
// `_.debounce` 是一个通过 Lodash 限制操作频率的函数。
// 在这个例子中,我们希望限制访问 yesno.wtf/api 的频率
// AJAX 请求直到用户输入完毕才会发出。想要了解更多关于
// `_.debounce` 函数 (及其近亲 `_.throttle`) 的知识,
// 请参考:https://lodash.com/docs#debounce
getAnswer: _.debounce(
function () {
if (this.question.indexOf('?') === -1) {
this.answer = 'Questions usually contain a question mark. ;-)'
return
}
this.answer = 'Thinking...'
var vm = this
axios.get('https://yesno.wtf/api')
.then(function (response) {
vm.answer = _.capitalize(response.data.answer)
})
.catch(function (error) {
vm.answer = 'Error! Could not reach the API. ' + error
})
},
// 这是我们为判定用户停止输入等待的毫秒数
500
)
}
})
</script>