监听事件
- v-on 监听事件,v-on 缩写为 @
- 事件冒泡
- 事件修饰符 阻止冒泡 .stop
- 事件修饰符 优先触发 .capture
- 事件修饰符 只有自己能触发,子元素无法触发.self
- 事件修饰符 只能提交一次 .once
- 事件修饰符 阻止提交 .prevent
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>监听事件</title>
<script src="js/vue.min.js"></script>
<style type="text/css">
*{
margin: 0 auto;
text-align: center;
line-height: 40px;
}
</style>
</head>
<body>
<div id="div1">
一共点击了{{clickNumber}}次!
<!-- v-on 缩写@ -->
<button @click="count">点击</button>
<hr>
<span>事件冒泡</span>
<div style="background: green" @click="doc('father')">
father
<div style="background: blue" @click="doc('me')">
me
<div style="background: red" @click="doc('son')">
son
</div>
</div>
</div>
<hr>
<span>事件修饰符 阻止冒泡 .stop</span>
<div style="background: green" @click.stop="doc('father')">
father
<div style="background: blue" @click.stop="doc('me')">
me
<div style="background: red" @click.stop="doc('son')">
son
</div>
</div>
</div>
<hr>
<span>事件修饰符 优先触发 .capture 当冒泡中包含此事件,先触发此事件</span>
<div style="background: green" @click="doc('father')">
father
<div style="background: blue" @click.capture="doc('me')">
me
<div style="background: red" @click="doc('son')">
son
</div>
</div>
</div>
<hr>
<span>事件修饰符 只有自己可以触发 .self</span>
<div style="background: green" @click="doc('father')">
father
<div style="background: blue" @click.self="doc('me')">
me
<div style="background: red" @click="doc('son')">
son
</div>
</div>
</div>
<hr>
<span>事件修饰符 只能触发一次 .once</span>
<div style="background: green" @click="doc('father')">
father
<div style="background: blue" @click.once="doc('me')">
me
<div style="background: red" @click="doc('son')">
son
</div>
</div>
</div>
<hr>
<span>事件修饰符 阻止提交,不会跳转 .prevent</span><br>
<a href="http://www.baidu.com" @click="doc('doc')" >正常的链接 http://www.baidu.com</a><br>
<a href="http://www.baidu.com" @click.prevent="doc('doc')" >prevent doc()之后的链接 http://www.baidu.com</a><br>
<a href="http://www.baidu.com" @click.prevent >纯prevent之后的链接 http://www.baidu.com</a><br>
<form @submit="doc('doc')" action="http://www.baidu.com">
<button type="submit">正常的form</button>
</form>
<form @submit.prevent="doc('doc')" action="http://www.baidu.com">
<button type="submit">prevent doc()之后的form</button>
</form>
<form @submit.prevent action="http://www.baidu.com">
<button type="submit">纯prevent之后的form</button>
</form>
</div>
<script>
new Vue({
el:'#div1',
data:{
clickNumber:0
},
methods:{
count:function () {
this.clickNumber++;
},
doc:function (msg) {
alert(msg);
}
}
})
</script>
</body>
</html>
条件语句
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>条件语句</title>
<script src="js/vue.min.js"></script>
</head>
<body>
<div id="div1">
<button @click="toggle">切换隐藏显示</button>
<div v-if="show">这一条是看得见的</div>
<hr>
<button @click="choujiang">抽奖</button>
<div v-if="show2">中奖了</div>
<div v-else>谢谢回顾</div>
<hr>
<button @click="suangua"> 算卦? </button>
<div v-if="number>98"> 神仙</div>
<div v-else-if="number>95"> 国家领导人</div>
<div v-else-if="number>90"> 大富商</div>
<div v-else-if="number>80"> 大企业主</div>
<div v-else-if="number>70"> 演艺明星</div>
<div v-else-if="number>60"> 小企业主</div>
<div v-else-if="number>50"> 普通公务员</div>
<div v-else-if="number>40"> 小个体户</div>
<div v-else-if="number>30"> 血汗工厂工人</div>
<div v-else-if="number>20"> 偏远山区农民</div>
<div v-else> 流浪汉</div>
</div>
<script>
new Vue({
el:'#div1',
data:{
show:true,
show2:false,
number:0
},
methods:{
toggle:function () {
this.show = !this.show;
},
choujiang:function () {
this.show2=Math.random()<0.5
},
suangua:function () {
this.number=Math.random()*100
}
}
})
</script>
</body>
</html>
循环语句
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>循环语句</title>
<script src="js/vue.min.js"></script>
</head>
<body>
<div id="div1">
<table>
<tr>
<th>name</th>
<th>hp</th>
</tr>
<tr v-for="hero in heros">
<td>{{hero.name}}</td>
<td>{{hero.hp}}</td>
</tr>
</table>
<hr>
<table>
<tr>
<th>no</th>
<th>name</th>
<th>hp</th>
</tr>
<tr v-for="hero,index in heros">
<td>{{index+1}}</td>
<td>{{hero.name}}</td>
<td>{{hero.hp}}</td>
</tr>
</table>
<hr>
<div v-for="i in 10">
{{i}}
</div>
</div>
<script>
var data = [
{name:"盖伦",hp:341},
{name:"提莫",hp:225},
{name:"安妮",hp:427},
{name:"死歌",hp:893}
];
new Vue({
el:'#div1',
data:{
heros:data
}
})
</script>
</body>
</html>
属性绑定
- v-bind 做属性绑定
- v-bind:href 简写成 :href
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>属性绑定</title>
<script src="js/vue.min.js"></script>
</head>
<body>
<div id="div1">
<!-- v-bind 简写: -->
<a :href="page" :style="style">百度</a>
</div>
<script>
new Vue({
el:'#div1',
data:{
page:'http://www.baidu.com',
style:'color: red'
}
})
</script>
</body>
</html>
双向绑定
- v-model 双向绑定
- 多种风格数据的绑定
- 修饰符
- 修饰符 .lazy
- 修饰符 .number
- 修饰符 .trim
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>双向绑定</title>
<script src="js/vue.min.js"></script>
</head>
<body>
<div id="div1">
<table border="1">
<tr>
<td>视图类型</td>
<td>输入数据</td>
<td>绑定到Vue上的数值</td>
</tr>
<tr>
<td>单行文本</td>
<td>
<input v-model="input" placeholder="输入数据">
</td>
<td><p>{{ input }}</p></td>
</tr>
<tr>
<td>多行文本</td>
<td>
<textarea v-model="textarea" placeholder="输入数据"></textarea>
</td>
<td><p>{{ textarea }}</p></td>
</tr>
<tr>
<td>单个复选框</td>
<td>
<input type="checkbox" id="checkbox" v-model="checked">
</td>
<td><p>{{ checked }}</p></td>
</tr>
<tr>
<td>单个复选框</td>
<td>
默认值是true或者false,也可以修改为自定义的值<br>
<input type="checkbox" id="toggle" true-value="yes" false-value="no" v-model="toggle">
</td>
<td><p>{{ toggle }}</p></td>
</tr>
<tr>
<td>多个复选框</td>
<td>
<input type="checkbox" id="teemo" value="teemo" v-model="checkedes">
<label for="teemo">teemo</label>
<input type="checkbox" id="gareen" value="gareen" v-model="checkedes">
<label for="gareen">gareen</label>
<input type="checkbox" id="annie" value="annie" v-model="checkedes">
<label for="annie">annie</label>
</td>
<td><p>{{ checkedes }}</p></td>
</tr>
<tr>
<td>单选按钮</td>
<td>
<input type="radio" id="one" value="One" v-model="radio">
<label for="one">One</label>
<br>
<input type="radio" id="two" value="Two" v-model="radio">
<label for="two">Two</label>
</td>
<td><p>{{ radio }}</p></td>
</tr>
<tr>
<td>单选选择框</td>
<td>
<select v-model="selected" size="5">
<option disabled value="">请选择</option>
<option>AD</option>
<option>AC</option>
<option>ADC</option>
</select>
</td>
<td><p>{{ selected }}</p></td>
</tr>
<tr>
<td>
多选选择框
</td>
<td>
(通过ctrl或者shift进行多选)<br>
<select v-model="selecteds" multiple size="5">
<option disabled value="">请选择</option>
<option>AD</option>
<option>AC</option>
<option>ADC</option>
</select>
</td>
<td><p>{{ selecteds }}</p></td>
</tr>
</table>
<hr>
<table border="1">
<tr>
<td>视图类型</td>
<td>输入数据</td>
<td>绑定到Vue上的数值</td>
</tr>
<tr>
<td>在失去焦点的时候,才会进行数据绑定了</td>
<td>
<input v-model.lazy="input" placeholder="输入数据">
</td>
<td><p>{{ input }}</p></td>
</tr>
</table>
<hr>
<table border="1">
<tr>
<td>视图类型</td>
<td>输入数据</td>
<td>绑定到Vue上的数值</td>
<td>数值类型</td>
</tr>
<tr>
<td>
通过.number方式确保获取到的是数字类型
</td>
<td>
<input v-model="input1" type="number" placeholder="输入数据">
</td>
<td>
<p>{{ input1 }}</p>
</td>
<td>
<p>{{ typeof input1 }}</p>
</td>
</tr>
<tr>
<td>
单行文本2
</td>
<td>
<input v-model.number="input2" type="number" placeholder="输入数据">
</td>
<td>
<p>{{ input2 }}</p>
</td>
<td>
<p>{{ typeof input2 }}</p>
</td>
</tr>
</table>
<hr>
<table border="1" >
<tr>
<td>视图类型</td>
<td>输入数据</td>
<td>绑定到Vue上的数值</td>
</tr>
<tr>
<td>
trim 去掉前后的空白
</td>
<td>
<input v-model.trim="input" placeholder="输入数据">
</td>
<td>
<p>"{{ input }}"</p>
</td>
</tr>
</table>
</div>
<script>
new Vue({
el:'#div1',
data:{
input:'',
input1:'',
input2:'',
textarea:'',
checked:'',
checkedes:[],
radio:'',
selected:'',
selecteds:[],
toggle:'',
}
})
</script>
</body>
</html>
计算属性
- computed
- computed 和 methods 的区别:
computed 是有缓存的,只要没有变化,会直接返回以前计算出来的值,而不会再次计算。 这样如果是复杂计算,就会节约不少时间。而methods每次都会调用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>计算属性</title>
<script src="js/vue.min.js"></script>
</head>
<body>
<div id="div1">
<h4>model</h4>
<span>美元汇率:{{exchange}}</span><br>
¥ <input v-model="rmb"> <br> $: {{rmb/exchange}}
<hr>
<h4>computed</h4>
<span>美元汇率:{{exchange}}</span><br>
¥ <input v-model="rmb"> <br> $: {{dollar}}
<hr>
<h4>methods</h4>
<span>美元汇率:{{exchange}}</span><br>
¥ <input v-model="rmb"> <br> $: {{getDollar()}}
</div>
<script>
new Vue({
el:'#div1',
data:{
exchange:6.8702,
rmb:0
},
computed:{
dollar:function () {
return this.rmb/this.exchange
}
},
methods:{
getDollar:function () {
return this.rmb/this.exchange
}
}
})
</script>
</body>
</html>
监听属性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>监听属性</title>
<script src="js/vue.min.js"></script>
</head>
<body>
<div id="div1">
<h4>watch</h4>
<span>美元汇率:{{exchange}}</span><br>
¥: <input v-model.number="rmb"> <br>
$: <input v-model.number="dol"> <br>
</div>
<script>
new Vue({
el:'#div1',
data:{
exchange:6.8702,
rmb:0,
dol:0
},
watch:{
rmb:function (val) {
this.rmb=val;
this.dol=this.rmb/this.exchange;
},
dol:function (val) {
this.dol=val;
this.rmb=this.dol*this.exchange;
}
}
})
</script>
</body>
</html>
过滤器
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>过滤器</title>
<script src="js/vue.min.js"></script>
</head>
<body>
<div id="div1">
多个过滤器: <input v-model="data"/> {{ data|cap|capL }}
全局过滤器: <input v-model="data"/> {{ data|glCap|glCapL }}
</div>
<script>
//全局过滤器
Vue.filter('glCap', function (value) {
if (!value) return '';
value = value.toString();
return value.charAt(0).toUpperCase() + value.slice(1)
});
Vue.filter('glCapL', 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:''
},
filters:{
cap:function(value) {
if (!value) return ''; //如果为空,则返回空字符串
value = value.toString();
return value.charAt(0).toUpperCase() + value.substring(1)
},
capL:function(value) {
if (!value) return ''; //如果为空,则返回空字符串
value = value.toString();
return value.substring(0,value.length-1)+ value.charAt(value.length-1).toUpperCase()
}
}
})
</script>
</body>
</html>
组件
- 局部组件
- 全局组件
- 参数
- 动态参数
- 自定义事件
- 遍历 json 数组
- 最开始效果步骤里的代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>组件</title>
<script src="js/vue.min.js"></script>
</head>
<body>
<div id="div1">
<prod></prod>
<prod></prod>
<glprod></glprod>
<glprod></glprod>
<glprod2 msg="gl休闲包2"></glprod2>
<hr>
动态参数: <input v-model="msg">
<glprod2 :msg="msg"></glprod2>
<hr>
<glprod3 :msg="msg" sale="12"></glprod3>
<hr>
<prod3 :msg="msg" sale="13" @increment="increment" @increment2="increment2"></prod3>
</div>
<script>
Vue.component('glprod',{ //名字 不能包含大写字母
template:'<div>gl休闲包</div>'
});
Vue.component('glprod2',{
props:['msg'],
template:'<div>{{msg}}</div>'
});
Vue.component('glprod3',{
props:['msg','sale'],
template:'<div @click="addSale">{{msg}}:{{sale}}</div>',
methods:{
addSale:function(){
this.sale++
}
}
});
new Vue({
el: '#div1',
data:{
msg:''
},
components:{
'prod':{
template:'<div>休闲包</div>'
},
'prod3':{
props:['msg','sale'],
template:'<div @click="addSale">{{msg}}:{{sale}}</div>',
methods:{
addSale:function(){
this.sale++;
this.$emit("increment",this.sale);
this.$emit("increment2");
}
}
}
},methods:{
increment:function(val){
console.log(val);
},
increment2:function(){
console.log('hello');
}
}
})
</script>
</body>
</html>
自定义指令
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>自定义指令</title>
<script src="js/vue.min.js"></script>
</head>
<body>
<div id="div1">
<span v-redpro>hello</span>
<hr>
<h4>带参数的指令</h4>
<span v-redpro2="{color:'green',text:'Pro+'}">hello</span>
<hr>
<h4>钩子函数</h4>
<div v-xart:hello.x.y="{a:'b'}"></div>
</div>
<script>
Vue.directive('redpro',function (el) {
el.innerHTML = el.innerHTML+' Pro';
el.style.color = 'red';
});
Vue.directive('redpro2',function (el, binding) {
el.innerHTML = el.innerHTML + 'Pro' + binding.value.text;
el.style.color = binding.value.color;
});
Vue.directive('xart',{
bind:function (el, binding, vnode) {
var s = JSON.stringify;
el.innerHTML =
'name: ' + s(binding.name) + '<br>' + //指令的名字 xart
'value: ' + s(binding.value) + '<br>' + //指令的value {"a":"b"}
'expression: ' + s(binding.expression) + '<br>' + // 指令表达式 {a:'b'}
'argument: ' + s(binding.arg) + '<br>' + // 指令的参数 hello
'modifiers: ' + s(binding.modifiers) + '<br>' + // 一个包含修饰符的对象 .x.y
'vnode keys: ' + Object.keys(vnode).join(', ') //虚拟节点
},
update:function (newValue, oldValue) {
// 值更新时的工作
// 也会以初始值为参数调用一次
},
unbind:function () {
// 清理工作
// 例如,删除 bind() 添加的事件监听器
}
});
new Vue({
el:'#div1'
})
</script>
</body>
</html>
路由 vue-router
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vue-router</title>
<script src="js/vue.min.js"></script>
<script src="js/vue-router.min.js"></script>
<style>
#pro div{
width: 500px;
height: 500px;
}
</style>
</head>
<body>
<div id="app">
<div>
<router-link to="/home">首页</router-link>
<router-link to="/product">用户</router-link>
<router-link to="/setting">设置</router-link>
</div>
<div id="pro">
<router-view></router-view>
</div>
</div>
<script>
//声明组件模版
var home = {template:'<div style="background: red">首页内容</div>'};
var user = {template:'<div style="background: green">用户内容</div>'};
var setting = {template:'<div style="background: yellow">设置内容</div>'};
// 定义路由
var routes = [
{path:'/',redirect:'/home'}, //默认渲染
{path:'/home',component:home},
{path:'/product',component:user},
{path:'/setting',component:setting}
];
var router = new VueRouter({
routes:routes
});
new Vue({
el:'#app',
router:router //router:router 可写为 router
})
</script>
</body>
</html>
fetch.js (一种 ajax 框架)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>fetch</title>
<script src="js/fetch.min.js"></script>
</head>
<body>
<div id="div1">
</div>
<script>
var url = 'http://static.how2j.cn/study/json.txt';
fetch(url).then(function (res) {
res.json().then(function (jsonObj) {
var jString = JSON.stringify(jsonObj);
document.getElementById("div1").innerText = "通过fetch获取到的json数据:"+jString;
}).catch(function (err) {
console.log(err)
})
})
</script>
</body>
</html>
axios.js (一种 ajax 框架)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>axios</title>
<script src="js/axios.min.js"></script>
</head>
<body>
<div id="div1"></div>
<script>
var url = 'http://static.how2j.cn/study/json.txt';
axios.get(url).then(function (res) {
var jsonObj = res.data;
var jString = JSON.stringify(jsonObj);
document.getElementById('div1').innerText = "通过 axios 获取到的json数据:"+jString;
})
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>axios</title>
<script src="js/vue.min.js"></script>
<script src="js/axios.min.js"></script>
<script src="js/fetch.min.js"></script>
</head>
<body>
<div id="div1">
<table border="1">
<tr v-for="hero in heros">
<td>{{hero.name}}</td>
<td>{{hero.hp}}</td>
</tr>
<tr v-for="hero in heros2">
<td>{{hero.name}}</td>
<td>{{hero.hp}}</td>
</tr>
</table>
</div>
<script>
// [
// {"name":"gareen","hp":"355"},
// {"name":"teemo","hp":"287"},
// {"name":"annie","hp":"420"}
// ]
var url = 'jsons.txt';
new Vue({
el:'#div1',
data:{
heros:[],
heros2:[]
},
mounted:function () { //加载成功
that = this;
axios.get(url).then(function (res) {
var jsonObj = res.data;
that.heros2 = jsonObj;
// var jString = JSON.stringify(jsonObj);
//document.getElementById('div1').innerText = "通过 axios 获取到的json数据:"+jString;
});
fetch(url).then(function (res) {
res.json().then(function (jsonObject) {
that.heros = jsonObject
}).catch(function (err) {
console.log(err);
})
})
}
})
</script>
</body>
</html>
crud
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>crud</title>
<script src="js/vue.min.js"></script>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
</head>
<body>
<div id="div1">
<table id="heroListTable">
<thead>
<tr>
<th>name</th>
<th>hp</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="hero in heros">
<td>{{hero.name}}</td>
<td>{{hero.hp}}</td>
<td>
<a href="#nowhere" @click="edit(hero)">编辑</a>
<a href="#nowhere" @click="deleteHero(hero.id)">删除</a>
</td>
</tr>
<tr>
<td>
name:<input type="text" v-model="heroAdd.name"><br>
hp:<input type="number" v-model="heroAdd.hp"><br>
<button @click="add">增加</button>
</td>
<td></td>
</tr>
</tbody>
</table>
<div id="divUpdate">
name:
<input type="text" v-model="heroUpdate.name" />
<br>
hp:
<input type="number" v-model="heroUpdate.hp" />
<input type="hidden" v-model="heroUpdate.id" />
<br>
<button type="button" @click="update">修改</button>
</div>
</div>
<script>
$("#divUpdate").hide();
var data = {
heros: [
{ id: 1, name: '盖伦', hp: 318},
{ id: 2, name: '提莫', hp: 320},
{ id: 3, name: '安妮', hp: 419},
{ id: 4, name: '死歌', hp: 325},
{ id: 5, name: '米波', hp: 422},
],
heroAdd: { id: 0, name: '', hp: '0'},
heroUpdate: { id: 0, name: '', hp: '0'},
updateObj:{ id: 0, name: '', hp: '0'}
};
var maxId = 5;
for (var i = 0;i<data.heros.length;i++){
if (data.heros[i].id>maxId)
maxId = this.heros[i].id;
}
new Vue({
el:'#div1',
data:data,
methods:{
add:function (ev) {
maxId++;
this.heroAdd.id = maxId;
if (this.heroAdd.name.length==0){
this.heroAdd.name="name#"+this.heroAdd.id;
}
this.heros.push(this.heroAdd);
this.heroAdd={ id: 0, name: '', hp: '0'};
},
deleteHero:function (id) {
for (var i=0;i<this.heros.length;i++){
if (this.heros[i].id===id){
this.heros.splice(i,1) //(index,要删除的数量)
}
}
},
edit: function (hero) {
$("#heroListTable").hide();
$("#divUpdate").show();
var copy = JSON.parse(JSON.stringify(hero));
this.heroUpdate = hero;
},
update:function(){
//因为v-model,已经同步修改了,所以只需要进行恢复显示就行了
$("#heroListTable").show();
$("#divUpdate").hide();
}
}
})
</script>
</body>
</html>