So interesting !
It's very good !
...
Vue.js
什么是Vue.js
- Vue.js 是目前最火的一个前端框架,React 是最流行的一个前端框架.都可以进行手机app开发,vue需要借助于Weex
- vue,angular,react 前端三大主流框架
- Vue.js 是一套构建用户界面的框架,只关注视图层,容易上手
框架和库的区别
- 框架: 是一套完整的解决方案;对项目的侵入性较大,项目如果需要更换框架,则需要重新架构整个项目
- 库(插件): 提供某一个小功能,对项目的侵入性较小,如果某个库无法完成某些需求,可以很容易切换到其他库实现需求
Node(后端) 中的 MVC 与 前端中的 MVVM 之间的区别
- MVC 是后端的分层开发概念
- MVVM 是前端视图层的概念主要关注于 视图层分离,也就是说:MVVM把前端的视图层,分为了 三部分Model,View,VM ViewModel
Vue常用指令
var app = new Vue({
el: '#app',//id为app的'对象'
data: {
name: 'A',//'对象'的属性
}
})
//{{}}用来获取对象值
{{name}}
<script src="../lib/vue.js"></script>
<script src="js/main.js"></script>
1.v-for
var app = new Vue({
el: '#app',
data: {
//foodList: ['葱','姜','蒜'],
foodList: [
{
name: '葱',
price: 10,
discount: .8,
},
{
name: '姜',
price: 100,
discount: .5,
},
{
name: '蒜',
price: 105,
//discount: .6,
},
],
},
});
<div id="app">
<ul>
<li v-for="food in foodList">{{food.name}}:${{food.discount ? food.price * food.discount : food.price}}</li>
</ul>
</div>
2.v-bind
var app = new Vue({
el: '#app',
data: {
url: 'https://baidu.com',
klass: 'btn btn-default',
isActive: true,
},
});
<style>
.active {
background: red;
}
</style>
<div id="app">
<!-- v-bind:class 相当于 :class-->
<a v-bind:class="{active: isActive}" v-bind:href="url">点我</a>
</div>
3.v-on
var app = new Vue({
el: '#app',
data: {
},
methods: {
onClick: function () {
console.log('clicked');
},
onEnter: function () {
console.log('mouse enter');
},
onOut: function () {
console.log('mouse leave');
},
onSubmit: function () {
//e.preventDefault();
console.log('submitted');
},
onKeyup: function () {
//e.preventDefault();
console.log('key pressed');
},
onEnter: function () {
//e.preventDefault();
console.log('key enter');
}
}
});
<div id="app">
<button v-on="{mouseenter: onEnter, mouseleave: onOut}" v-on:click="onClick">点我</button>
<!--<form action="" v-on:submit="onSubmit($event)">-->
<!--<form action="" v-on:keyup="onKeyup" v-on:submit.prevent="onSubmit()">-->
<form action="" v-on:keyup.enter="onEnter" v-on:submit.prevent="onSubmit()">
<!--v-on: 相当于 @-->
<input type="text">
<button type="submit">提交</button>
</form>
</div>
4.v-model
- 修饰符
var app = new Vue({
el: '#app',
data: {
name: 'whh',
},
methods: {
},
});
<div id="app">
<input type="text" v-model="name">
<input type="text" v-model.lazy="name"><!--lazy 懒惰一下,当鼠标拿开更新-->
<input type="text" v-model.trim="name"><!--trim 去掉数据中所有空格-->
<input type="text" v-model.number="name"><!--number 输出类型为number-->
{{name}}
</div>
- 在其他元素及类型上的用法
var app = new Vue({
el: '#app',
data: {
//sex: 'female',
//quxiang: ['male'],
//article: 'Mr. Johnson had never been up in an aerophane before and he had read a lot about air accidents, so one day when a friend offered to take him for a ride in his own small phane, Mr. ',
from: '',
dest: '',
},
methods: {
},
});
<div id="app">
<!--<label>-->
<!--男-->
<!--<input v-model="sex" value="male" type="radio">-->
<!--</label>-->
<!--<label>-->
<!--女-->
<!--<input v-model="sex" value="female" type="radio">-->
<!--</label><br>-->
<!--{{sex}}-->
<!--<br>-->
<!--<label>-->
<!--男-->
<!--<input v-model="quxiang" value="male" type="checkbox">-->
<!--</label>-->
<!--<label>-->
<!--女-->
<!--<input v-model="quxiang" value="female" type="checkbox">-->
<!--</label><br>-->
<!--{{quxiang}}-->
<!--<textarea v-model="article"></textarea>-->
<div>你来自哪里?</div>
<select v-model="from">
<option value="1">王家沟</option>
<option value="2">北京</option>
</select>
{{from}}
<div>你要去哪里?</div>
<select v-model="dest" multiple>
<option value="1">王家沟</option>
<option value="2">北京</option>
</select>
{{dest}}
</div>
5.v-if //控制流指令
计算属性
var app = new Vue({
el: '#app',
data: {
math: 90,
physics: 80,
english: 30,
},
methods: {
},
computed: {
sum: function () {
return parseFloat(this.math + this.physics + this.english);
},
average: function () {
return Math.round(this.sum / 3);
},
},
});
<div id="app">
<table border="1">
<thead>
<th>学科</th>
<th>分数</th>
</thead>
<tbody>
<tr>
<td>数学</td>
<!--<td>{{math}}</td>-->
<td><input type="text" v-model.number="math"></td>
</tr>
<tr>
<td>物理</td>
<!--<td>{{physics}}</td>-->
<td><input type="text" v-model.number="physics"></td>
</tr>
<tr>
<td>英语</td>
<!--<td>{{english}}</td>-->
<td><input type="text" v-model.number="english"></td>
</tr>
<tr>
<td>总分</td>
<!--<td>{{math + physics + english}}</td>-->
<td>{{sum}}</td>
</tr>
<tr>
<td>平均分</td>
<!--<td>{{Math.round((math + physics + english) / 3)}}</td>-->
<td>{{average}}</td>
</tr>
</tbody>
</table>
</div>
组件
1.全局及局部组建
//组件
Vue.component('alert',{//01类似全局
template: '<button @click="on_click">弹弹弹</button>',
methods:{
on_click: function () {
alert('Yo.all');
}
}
});
//类似封装
var alert_comonent = {
template: '<button @click="on_click">弹弹弹</button>',
methods:{
on_click: function () {
alert('Yo.1.1');
}
}
}
var app = new Vue({
el: '#seg1',
components: {//02类似局部
//组件
alert: {
template: '<button @click="on_click">弹弹弹</button>',
methods:{
on_click: function () {
alert('Yo.1');
}
}
}
},
data: {
//属性
},
methods: {
//事件
},
computed: {
//计算属性
},
});
new Vue({
el: '#seg2',//用的是全局
});
new Vue({
el: "#seg3",//用的是局部封装
components: {//02类似局部
//组件
alert: alert_comonent,
},
})
<div id="seg1">
<alert></alert>
</div>
<div id="seg2">
<alert></alert>
</div>
<div id="seg3">
<alert></alert>
</div>
2.配置组建
//两种方案 一种如下注释几行,另一种在html中写
Vue.component('like', {
// template:
// `
// <button :class="{liked: liked}" @click="toggle_like()">
// 👍 {{like_count}}
// </button>
// `,
template: '#like_component_tpl',
data: function () {
return {
like_count: 10,
liked: false,
}
},
methods: {
toggle_like: function () {
if (!this.liked){
this.like_count++;
}else{
this.like_count--;
}
this.liked = !this.liked;
}
}
});
new Vue({
el: '#app',
});
<div id="app">
<like></like>
</div>
<template id="like_component_tpl">
<button :class="{liked: liked}" @click="toggle_like()">
👍 {{like_count}}
</button>
</template>
3.组件通信
3.1父子通信
//Vue.component('alert',{
Vue.component('user',{
//template: '<button @click="on_click">弹弹弹</button>',
template: '<a :href="\'/user/\'+username">{{username}}</a>',
//props: ['msg'],
props: ['username'],
methods:{
//on_click: function () {
// alert(this.msg);
//}
}
});
new Vue({
el: '#app',
});
<div id="app">
<!--<alert msg="Yoooooo"></alert>-->
<user username="whh"></user>
</div>
3.2子父通信*
Vue.component('balance',{
template:`
<div>
<show @show-balance="show_balance"></show>//show_balace() 不加括号 默认传几个参数
<div v-if="show">
您的余额:
</div>
</div>
`,
data: function () {
return {
show: false
};
},
methods: {
show_balance: function (data) {
this.show = true;
console.log('data:', data);
}
}
});
Vue.component('show',{
template: '<button @click="on_click()">显示余额</button>',
methods: {
on_click() {
this.$emit('show-balance', {a: 1, b: 2});//这边传的值 相当于 传给data
}
}
});
new Vue({
el: '#app',
});
<div id="app">
<balance></balance>
</div>
3.3任意及平行组件间通信*
var Event = new Vue();
Vue.component('huahua',{
template: `
<div>
我说:<input @keyup="on_change" v-model="i_said" type="text"/>
</div>
`,
data: function () {
return {
i_said: '',
}
},
methods: {
on_change: function () {
Event.$emit('huahua-said-something',this.i_said)
}
}
});
Vue.component('shuandan',{
template: `<div>花花说:{{huahua_said}}</div>`,
data: function () {
return {
huahua_said: '',
}
},
mounted: function () {
var me = this;
Event.$on('huahua-said-something', function (data) {
//console.log('data:', data);
me.huahua_said = data;
})
}
});
new Vue({
el: '#app',
});
过滤器
Vue.filter('meter',function (val,unit) {
val = val || 0; //如果 val 不为空 显示val
unit = unit || 'm';
//return Math.round(val /1000) + unit;
return (val /1000).toFixed(2) + unit;
});
Vue.filter('currency',function (val,unit) {
val = val || 0; //如果 val 不为空 显示val
unit = unit || '元';
return val+unit;
});
new Vue({
el: '#app',
data: {
price: 10,
length: 10,
}
});
<div id="app">
<div>
<input v-model="length" type="text">mm
{{length | meter}}
</div>
<hr>
<div>
<input v-model="price" type="text">
{{ price | currency('USD') }}
</div>
</div>
自定义指令
1.基础配置
Vue.directive('pin', function (el, binding) {
var pinned = binding.value;
//console.log(pinned);
if(pinned){
el.style.position = 'fixed';
el.style.top = '10px';
el.style.left = '10px';
}else{
el.style.position = 'static';
}
});
new Vue({
el: '#app',
data: {
card1: {
pinned: false,
},
card2: {
pinned: false,
}
},
});
<div id="app">
<div v-pin="card1.pinned" class="card">
<button @click="card1.pinned = !card1.pinned">钉住/取消</button>
mwy
</div>
<div v-pin="card2.pinned" class="card">
<a href="#" @click="card2.pinned = !card2.pinned">pin it</a>
dzz
</div>
sksksksdfa sf asf sf asf
</div>
2.配置传参及修饰符
Vue.directive('pin', function (el, binding) {
var pinned = binding.value;
//console.log(pinned);
var position = binding.modifiers; //modifiers 是用 . 传参
//console.log(position);
var warning = binding.arg; //arg 是用 : 传参
if(pinned){
el.style.position = 'fixed';
for(var key in position){
if(position[key]) {
el.style[key] = '10px';
}
}
if (warning === 'true') {
el.style.background = 'yellow';
}
}else{
el.style.position = 'static';
}
});
new Vue({
el: '#app',
data: {
card1: {
pinned: false,
},
card2: {
pinned: false,
}
},
});
<div id="app">
<div v-pin:true.bottom.right="card1.pinned" class="card">
<button @click="card1.pinned = !card1.pinned">钉住/取消</button>
mwy
</div>
<div v-pin.bottom.left="card2.pinned" class="card">
<a href="#" @click="card2.pinned = !card2.pinned">pin it</a>
dzz
</div>
sksksksdfa sf asf sf asf sdafasfasfasf
</div>
混合 mixins
没用minxins时 //很多重复内容
Vue.component('tooltip',{
//提示框
template:`
<div>
<span @mouseenter="show" @mouseleave="hide">bys</span>
<div v-if="visible">
daizhouzhoushilaji dalaji
</div>
</div>
`,
methods: {
show: function () {
this.visible = true;
},
hide: function () {
this.visible = false;
}
},
data: function () {
return {
visible: false,
}
}
});
Vue.component('popup',{
//弹出层
template: `
<div>
<button @click="toggle">Popup</button>
<div v-if="visible">
<span @click="hide">X</span>
<h4>title</h4>
mwy&dzz
</div>
</div>
`,
methods: {
toggle: function () {
this.visible = !this.visible;
},
hide: function () {
this.visible = false;
}
},
data: function () {
return {
visible: false,
}
},
});
new Vue({
el: '#app',
data: {
},
});
<div id="app">
<popup></popup>
<hr>
<tooltip></tooltip>
</div>
用了之后👇 //自己领悟
var base = {
methods: {
show: function () {
this.visible = true;
},
hide: function () {
this.visible = false;
},
toggle: function () {
this.visible = !this.visible; //每点击一次按钮 值变反
}
},
data: function () {
return {
visible: false,
}
}
}
Vue.component('tooltip',{
//提示框
template:`
<div>
<span @mouseenter="show" @mouseleave="hide">bys</span>
<div v-if="visible">
daizhouzhoushilaji dalaji
</div>
</div>
`,
mixins: [base],
data: function () { //在这边重新定义 visible值 覆盖 mixins中的值 =默认打开
return {
visible: true,
}
}
});
Vue.component('popup',{
//弹出层
template: `
<div>
<button @click="toggle">Popup</button>
<div v-if="visible">
<span @click="hide">X</span>
<h4>title</h4>
mwy&dzz
</div>
</div>
`,
mixins: [base]
});
new Vue({
el: '#app',
data: {
},
});
<div id="app">
<popup></popup>
<hr>
<tooltip></tooltip>
</div>
插槽 slots
<style>
.panel{
max-width: 300px;
border: 1px solid #999;
margin-bottom: 15px;
}
.panel > * {
padding:15px;
}
.panel .title{
border-bottom: 1px solid #999;
}
.panel .footer{
border-top: 1px solid #999;
}
</style>
原
Vue.component('panel',{
template: '#panel-tpl',
});
new Vue({
el: '#app',
data: {
},
});
<div id="app">
<panel></panel>
</div>
<template id="panel-tpl">
<div class="panel">
<div class="title">Yo.</div>
<div class="content">
ds sdf sdf<br>
sdfsf,<br>
手动阀十分
</div>
<div class="footer">more</div>
</div>
</template>
后
Vue.component('panel',{
template: '#panel-tpl',
});
new Vue({
el: '#app',
data: {
},
});
<div id="app">
<panel>
<div slot="title">
Yo.
</div>
<div slot="content">
Young yo yo
</div>
<!--<div slot="footer">-->
<!--<!–more..–>-->
<!--</div>-->
</panel>
<panel>Young yo yo1</panel>
</div>
<template id="panel-tpl">
<div class="panel">
<div class="title">
<slot name="title"></slot>
</div>
<div class="content">
<slot name="content"></slot>
</div>
<div class="footer">
<slot name="footer">more..*</slot>
</div>
</div>
</template>