Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式JavaScript框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。
介绍
开发环境
下载开发工具 HBuilderX,点击学习视频下载课程源码,如下图。
第一个 Vue 应用
Vue 实例
数据与方法
生命周期
图中像 beforeCreate 等函数称为生命周期钩子的函数!下面演示了下钩子。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
{{msg}}
</div>
<script type="text/javascript">
// Vue.js 官网 -- API -- 选项/生命周期钩子
var vm = new Vue({
el : "#app",
data : {
msg : "hi vue",
},
//在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。
beforeCreate:function(){
console.log('beforeCreate');
},
/* 在实例创建完成后被立即调用。
在这一步,实例已完成以下的配置:数据观测 (data observer),属性和方法的运算,watch/event 事件回调。
然而,挂载阶段还没开始,$el 属性目前不可见。 */
created :function(){
console.log('created');
},
//在挂载开始之前被调用:相关的渲染函数首次被调用
beforeMount : function(){
console.log('beforeMount');
},
//el 被新创建的 vm.$el 替换, 挂在成功
mounted : function(){
console.log('mounted');
},
//数据更新时调用
beforeUpdate : function(){
console.log('beforeUpdate');
},
//组件 DOM 已经更新, 组件更新完毕
updated : function(){
console.log('updated');
}
});
setTimeout(function(){
vm.msg = "change ......";
}, 3000);
</script>
</body>
</html>
模板语法
插值 {{}}
指令
计算属性
监听属性
<script src="https://how2j.cn/study/vue.min.js"></script>
<style>
table tr td{
border:1px solid gray;
padding:10px;
}
table{
border-collapse:collapse;
width:800px;
table-layout:fixed;
}
tr.firstLine{
background-color: lightGray;
}
</style>
<div id="div1">
<table align="center" >
<tr class="firstLine">
<td>人民币</td>
<td>美元</td>
</tr>
<tr>
<td align="center" colspan="2">
汇率: <input type="number" v-model.number="exchange" />
</td>
</tr>
<tr>
<td align="center">
¥: <input type="number" v-model.number = "rmb" />
</td>
<td align="center">
$: <input type="number" v-model.number = "dollar" />
</td>
</tr>
</table>
</div>
<script>
new Vue({
el: '#div1',
data: {
exchange:6.4,
rmb:0,
dollar:0
},
watch:{
rmb:function(val) {
this.rmb = val;
this.dollar = this.rmb / this.exchange;
},
dollar:function(val) {
this.dollar = val;
this.rmb = this.dollar * this.exchange;
},
}
})
</script>
class 和 style 绑定
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<!-- 绑定 <style><style> 中书写的 CSS 类 -->
<!-- 下面 [] 等价于 {active : isActive, green : isGreen} 是否绑定 active 取决于 isActive-->
<div
class="test"
v-bind:class="[ isActive ? 'active' : '', isGreen ? 'green' : '']"
style="width:200px; height:200px; text-align:center; line-height:200px;">
hi vue
</div>
<!-- 绑定 HTML 内联属性-->
<div
:style="{color:color, fontSize:size, background: isRed ? '#FF0000' : ''}">
hi vue
</div>
</div>
<script type="text/javascript">
var vm = new Vue({
el : "#app",
data : {
isActive : true,
isGreen : true,
color : "#000000",
size : '50px',
isRed : true
}
});
</script>
<style>
.test{font-size:30px;}
.green{color:#0000FF;}
.active{background:#FF9000;}
</style>
</body>
</html>
条件渲染
列表渲染(循环)
事件处理
表单输入双向绑定
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<div id="example-1">
<input v-model="message" placeholder="edit me">
<p>Message is: {{ message }}</p>
<textarea v-model="message2" placeholder="add multiple lines"></textarea>
<p style="white-space: pre-line;">{{ message2 }}</p>
<br />
<div style="margin-top:20px;">
<input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
<label for="jack">Jack</label>
<input type="checkbox" id="john" value="John" v-model="checkedNames">
<label for="john">John</label>
<input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
<label for="mike">Mike</label>
<br>
<span>Checked names: {{ checkedNames }}</span>
</div>
<div style="margin-top:20px;">
<input type="radio" id="one" value="One" v-model="picked">
<label for="one">One</label>
<br>
<input type="radio" id="two" value="Two" v-model="picked">
<label for="two">Two</label>
<br>
<span>Picked: {{ picked }}</span>
</div>
<button type="button" @click="submit">提交</button>
</div>
</div>
<script type="text/javascript">
var vm = new Vue({
el : "#app",
data : {
message : "test",
message2 :"hi",
checkedNames : ['Jack', 'John'],
picked : "Two"
},
methods: {
submit : function () {
// 点击提交按钮,此处就可以收集表单里的各个值,完成表单提交功能
}
}
});
</script>
<style type="text/css">
</style>
</body>
</html>
过滤器
单个过滤器
<script src="https://how2j.cn/study/vue.min.js"></script>
<style>
table tr td{
border:1px solid gray;
padding:10px;
}
table{
border-collapse:collapse;
width:800px;
table-layout:fixed;
}
tr.firstLine{
background-color: lightGray;
}
</style>
<div id="div1">
<table align="center" >
<tr class="firstLine">
<td>输入数据</td>
<td>过滤后的结果</td>
</tr>
<tr>
<td align="center">
<input v-model= "data" />
</td>
<td align="center">
{{ data|capitalize }}
</td>
</tr>
</table>
</div>
<script>
new Vue({
el: '#div1',
data: {
data:''
},
filters:{
capitalize:function(value) {
if (!value) return '' //如果为空,则返回空字符串
value = value.toString()
return value.charAt(0).toUpperCase() + value.substring(1)
}
}
})
</script>
多个过滤器
<script src="https://how2j.cn/study/vue.min.js"></script>
<style>
table tr td{
border:1px solid gray;
padding:10px;
}
table{
border-collapse:collapse;
width:800px;
table-layout:fixed;
}
tr.firstLine{
background-color: lightGray;
}
</style>
<div id="div1">
<table align="center" >
<tr class="firstLine">
<td>输入数据</td>
<td>过滤后的结果</td>
</tr>
<tr>
<td align="center">
<input v-model= "data" />
</td>
<td align="center">
{{ data|capitalize|capitalizeLastLetter }}
</td>
</tr>
</table>
</div>
<script>
new Vue({
el: '#div1',
data: {
data:''
},
filters:{
capitalize:function(value) {
if (!value) return '' //如果为空,则返回空字符串
value = value.toString()
return value.charAt(0).toUpperCase() + value.substring(1)
},
capitalizeLastLetter:function(value) {
if (!value) return '' //如果为空,则返回空字符串
value = value.toString()
return value.substring(0,value.length-1)+ value.charAt(value.length-1).toUpperCase()
}
}
})
</script>
全局过滤器
<script src="https://how2j.cn/study/vue.min.js"></script>
<style>
table tr td{
border:1px solid gray;
padding:10px;
}
table{
border-collapse:collapse;
width:800px;
table-layout:fixed;
}
tr.firstLine{
background-color: lightGray;
}
</style>
<div id="div1">
<table align="center" >
<tr class="firstLine">
<td>输入数据</td>
<td>过滤后的结果</td>
</tr>
<tr>
<td align="center">
<input v-model= "data" />
</td>
<td align="center">
{{ data|capitalize|capitalizeLastLetter }}
</td>
</tr>
</table>
</div>
<script>
Vue.filter('capitalize', function (value) {
if (!value) return ''
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
})
Vue.filter('capitalizeLastLetter', function (value) {
if (!value) return '' //如果为空,则返回空字符串
value = value.toString()
return value.substring(0,value.length-1)+ value.charAt(value.length-1).toUpperCase()
})
new Vue({
el: '#div1',
data: {
data:''
}
})
</script>
组件
局部组件
<script src="https://how2j.cn/study/vue.min.js"></script>
<style>
div.product{
float:left;
border:1px solid lightGray;
width:200px;
margin:10px;
cursor: pointer;
}
</style>
<div id="div1">
<product></product>
<product></product>
<product></product>
</div>
<script>
new Vue({
el: '#div1',
components:{
'product':{
template:'<div class="product" >MAXFEEL休闲男士手包真皮手拿包大容量信封包手抓包夹包软韩版潮</div>'
}
}
})
</script>
全局组件
<script src="https://how2j.cn/study/vue.min.js"></script>
<style>
div.product{
float:left;
border:1px solid lightGray;
width:200px;
margin:10px;
cursor: pointer;
}
</style>
<div id="div1">
<product></product>
<product></product>
<product></product>
</div>
<script>
Vue.component('product', {
template: '<div class="product" >MAXFEEL休闲男士手包真皮手拿包大容量信封包手抓包夹包软韩版潮</div>'
})
new Vue({
el: '#div1'
})
</script>
参数
<script src="https://how2j.cn/study/vue.min.js"></script>
<style>
div.product{
float:left;
border:1px solid lightGray;
width:200px;
margin:10px;
cursor: pointer;
}
</style>
<div id="div1">
<product name="MAXFEEL休闲男士手包真皮手拿包大容量信封包手抓包夹包软韩版潮"></product>
<product name="宾度 男士手包真皮大容量手拿包牛皮个性潮男包手抓包软皮信封包"></product>
<product name="唯美诺新款男士手包男包真皮大容量小羊皮手拿包信封包软皮夹包潮"></product>
</div>
<script>
Vue.component('product', {
props:['name'],
template: '<div class="product" >{{name}}</div>'
})
new Vue({
el: '#div1'
})
</script>
动态参数
<script src="https://how2j.cn/study/vue.min.js"></script>
<style>
div.product{
float:left;
border:1px solid lightGray;
width:200px;
margin:10px;
cursor: pointer;
}
</style>
<div id="div1">
组件外的值:<input v-model="outName" ><br>
<product v-bind:name="outName"></product>
</div>
<script>
Vue.component('product', {
props:['name'],
template: '<div class="product" >{{name}}</div>'
})
new Vue({
el: '#div1',
data:{
outName:'产品名称'
}
})
</script>
自定义事件
<script src="https://how2j.cn/study/vue.min.js"></script>
<style>
div.product{
float:left;
border:1px solid lightGray;
width:200px;
margin:10px;
cursor: pointer;
}
</style>
<div id="div1">
<product name="MAXFEEL休闲男士手包真皮手拿包大容量信封包手抓包夹包软韩版潮" sale="10" ></product>
<product name="宾度 男士手包真皮大容量手拿包牛皮个性潮男包手抓包软皮信封包" sale="20" ></product>
<product name="唯美诺新款男士手包男包真皮大容量小羊皮手拿包信封包软皮夹包潮" sale="30" ></product>
</div>
<script>
Vue.component('product', {
props:['name','sale'],
template: '<div class="product" v-on:click="increaseSale">{{name}} 销量: {{sale}} </div>',
methods:{
increaseSale:function(){
this.sale++
}
}
})
new Vue({
el: '#div1'
})
</script>
遍历 json 数组
<script src="https://how2j.cn/study/vue.min.js"></script>
<style>
div.product{
float:left;
border:1px solid lightGray;
width:200px;
margin:10px;
cursor: pointer;
}
</style>
<div id="div1">
<product v-for="item in products" v-bind:product="item"></product>
</div>
<script>
Vue.component('product', {
props:['product'],
template: '<div class="product" v-on:click="increaseSale">{{product.name}} 销量: {{product.sale}} </div>',
methods:{
increaseSale:function(){
this.product.sale++
}
}
})
new Vue({
el: '#div1',
data:{
products:[
{"name":"MAXFEEL休闲男士手包真皮手拿包大容量信封包手抓包夹包软韩版潮","sale":"18"},
{"name":"宾度 男士手包真皮大容量手拿包牛皮个性潮男包手抓包软皮信封包","sale":"35"},
{"name":"唯美诺新款男士手包男包真皮大容量小羊皮手拿包信封包软皮夹包潮","sale":"29"}
]
}
})
</script>
参考资料
[1] Vue.js 官方教程
[2] HOW2J.CN