Vue
前端三大框架
Angular
国外的,笨重,做大项目的,更新迭代速度很快,程序员学习成本高,几乎不使用
React
擅长做移动端
Vue
轻巧,集Angular与React的优点
Vue介绍
Vue为 Js渐进式框架:
在一个页面中,小到一个变量,大到整个页面,均可以由Vue控制,Vue也可以控制整个项目
可以独立完成前后端分离式项目的JavaScript框架
Vue实现仅一次引入就可以控制整个项目:
单页面应用
可以完全脱离服务器端,以前端代码复用的方式渲染整个页面:组件化开发
Vue的优点
1、单页面:高效
2、虚拟DOM:页面缓存
3、数据的双向绑定:数据具有监听机制
4、数据驱动:从数据出发,不是从DOM出发
Vue的使用
1.下载vue.js:https://vuejs.org/js/vue.js
2.在要使用vue的html页面通过script标签引入
3.在html中书写挂载点的页面结构,用id表示
4.在自定义的script标签实例化Vue对象,传入一个大字典
5.在字典中通过 el与挂载点页面结构绑定,data为其通过数据
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>使用Vue</title>
</head>
<body>
<div id="app">
<!-- {{ vue变量 }} 插值表达式 -->
<h1>{{ h1_msg }}</h1>
<h2>{{ h2_msg }}</h2>
</div>
</body>
<script src="js/vue.js"></script>
<script>
let app = new Vue({
el: '#app', // 挂载点
data: { // 为挂载点的页面结构提高数据
h1_msg: 'h1的内容',
h2_msg: 'h2的内容',
}
})
</script>
</html>
Vue完成简单的事件
<body>
<div id="app">
<h1 v-on:click="clickAction">
h1的内容是{{ msg }}
</h1>
</div>
</body>
<script src="js/vue.js"></script>
<script>
let app = new Vue({
el:"#app",
data:{
msg:"ymg是个dsb"
},
methods:{ // 为挂载点提供事件的
clickAction: function () {
alert(123)
}
}
})
</script>
Vue操作简单样式
<body>
<div id="app">
<p v-on:click:"btnClick" v-bind:style="v_style">
点击这个p标签文字颜色变为绿色
</p>
<div v-on:click:"btnClick" v-bind:style="v_style">
点击这个div标签文字颜色变为绿色
</div>
</div>
</body>
<script src="js/vue.js"></script>
<script>
let app = new Vue({
el:'#app',
data:{
v_style:{
color:"black"
}
},
methods: {
btnClick: function () {
// this.$data.v_style.color = "green"
this.v_style.color = "green" // 可以直接拿到v_style的,也可以一层层往下拿到v_style
}
}
})
</script>
小结
1、Vue通过 v-* 指令来控制标签
2、vue通过 变量 来驱动页面
指令
文本指令
<body>
<div id="app">
<!-- 插值表达式就是 v_text -->
<p>{{ msg1 }}</p>
<p v-text="msg2"></p>
<!-- 可以解析html标签 -->
<p v-html="msg3"></p>
<!-- 必须赋初值,渲染的结果便永远不会发生变化 -->
<P v-once="msg3" v-on:click="action">
{{ msg3 }}
</P>
</div>
</body>
<script src="js/vue.js"></script>
<script>
let app = new Vue({
el:"#app",
data:{
msg1:"**msg1**"
msg2:"<b>**msg2**</b>",
msg3:"<b>**msg3**</b>",
},
methods:{
action:function () {
// this.$data.msg3 = "<b>**msg3**</b>"
this.msg3 = "<b>**new msg3**</b>"
}
}
})
</script>
事件指令
<body>
<div id="app">
<!-- v-on:事件名="函数名" 可以简写为=> @事件名="函数名" ( v-on: => @ ) -->
<P v-on:click="action1">
{{ msg[0] }}
</P>
<p @click="action2">
{{ msg[1] }}
</p>
<!-- 事件的传参 -->
<ul>
<li @click="liAction(100)">列表项1</li>
<li @click="liAction(200)">列表项2</li>
<li @click="liAction(300)">列表项3</li>
</ul>
<!-- 鼠标时间的对象:直接写函数名,默认将鼠标事件对象传入参数 -->
<div @click="func1">func1</div>
<!-- 鼠标事件的对象:一旦添加(),就必须手动传参,事件对象就不会默认传入了,需要用$event传入鼠标事件 -->
<div @click="func2($event, 'abc')">func2</div>
</div>
</body>
<script src="js/vue.js"></script>
<script>
let app = new Vue({
el:"#app",
data:{
msg:[111,222]
},
methods:{
action1:function(){
alert(this.msg[0])
},
action2:function(){
alert(this.msg[1])
},
liAction:function(num, msg){
console.log(num);
console.log(msg)
},
func1:function(ev){
console.log(ev)
},
func2:function(ev, msg){
console.log(ev);
console.log(msg)
}
}
})
</script>
属性指令
<head>
<meta charset="UTF-8">
<title>title</title>
<style>
.rDiv {
width: 100px;
height: 100px;
background-color: red;
}
.gDiv {
width: 200px;
height: 50px;
background-color: green;
}
.br {
border-radius: 50%;
}
</style>
</head>
<body>
<div id="app">
<!-- 属性指令:用vue绑定属性,将属性内容交给vue处理 -->
<!-- 语法: v-bin:属性名='变量' (可以简写: v-bind => :) -->
<p class="" style="" v-bind:owen="oo" :jason="jj"></p>
<!-- class属性 -->
<p :class="c1" @click="action1"></p>
<!-- 多类名 -->
<p :class="[c1, c2]"></p>
<!-- 'br'固定写死的数据,不再是变量 -->
<p :class="[c1, 'br']"></p>
<!-- style 属性 -->
<!-- 一个变量:该变量值为{},{}内部完成一个个属性的设置 -->
<p class="gDiv" :style="s1">
12345
</p>
<!-- 一个{}:{}内一个个属性由一个个变量单独控制 -->
<p class="gDiv" :style="{fonSize:fs, color:c}">
67890
</p>
</div>
</body>
<script src="js/vue.js"></script>
<script>
let app = new Vue({
el:"#app",
data:{
oo:"owen",
jj:"jason",
c1:"rDiv",
c2:"br",
s1:{
// "font-size":"30px"
fontSize:"30px",
color:"pink"
},
fs:"30px",
c:"orange"
},
methods:{
action1:function(){
if (this.c1 == "rDiv"){
this.c1 = "gDiv"
} else {
this.c1 = "rDiv"
}
}
}
})
</script>
表单指令
<div id="app">
<!-- v-model针对于表单元素 -->
<form action="" method="get">
<!-- 1、双向绑定:服务于文本输入框 -->
<!-- v-model存储的值为输入框的value值 -->
<div>
<input type="text" name="usr" v-model="in_val">
<input type="password" name="ps" v-model="in_val" >
<textarea name="info" v-model="in_val"></textarea>
</div>
<!-- 2、单选框 -->
<div>
<!-- 单选框是以name进行分组,同组中只能发生单选 -->
<!-- v-model存储的值为单选框的value值 -->
男:<input type="radio" name="sex" value="男" v-model="ra_val">
女:<input type="radio" name="sex" value="女" v-model="ra_val">
{{ ra_val }}
</div>
<!-- 3、单一复选框 -->
<!-- v-model存储的值为true|false -->
<!-- 或者为自定义替换的值 -->
<div>
<input type="checkbox" v-model='sin_val' true-value="选中" false-value="未选中" />
{{ sin_val }}
</div>
<!-- 4、多复选框 -->
<!-- v-model存储的值为存储值多复选框value的数组 -->
<div>
<input type="checkbox" value="喜好男的" name="cless" v-model='more_val' />
<input type="checkbox" value="喜好女的" name="cless" v-model='more_val' />
<input type="checkbox" value="不挑" name="cless" v-model='more_val' />
{{ more_val }}
</div>
</form>
</div>
<script type="text/javascript">
new Vue({
el: '#app',
data: {
in_val: '',
// 默认值可以决定单选框默认选项
ra_val: '男',
// 默认值为true,单一复选框为选中,反之false为不选中
sin_val: '',
// 数组中存在的值对应的复选框默认为选中状态
more_val: ['喜好女的','不挑']
}
})
</script>
条件指令
<meta charset="UTF-8">
<style>
.div {
width: 100px;
height: 100px;
background-color: greenyellow;
border-radius: 50%;
}
</style>
<div id="app">
<!-- 条件指令 v-show | v-if-->
<!-- v-show:消失是以 display: none渲染 -->
<div class="div" v-show="s1"></div>
<div class="div" v-show="s1"></div>
<!-- v-if:消失时不会被渲染渲染,所以建议建立缓存, 用key属性 -->
<div class="div" v-if="s2" key="div1"></div>
<div class="div" v-if="s2" key="div2"></div>
</div>
</body>
<script src="js/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
s1: false,
// s2: false 没写默认为false
}
})
</script>
<meta charset="utf-8">
<style>
ul li {
border: 1px solid black;
width: 60px;
float: left;
}
ul {
list-style: none;
}
ul:after {
content: "";
display: block;
clear: both;
}
.wrap {
width: 500px;
height: 200px;
}
.red { background-color: red; }
.blue { background-color: blue; }
.green { background-color: green; }
</style>
<div id="app">
<!-- v-if v-else-if v-else 案例 -->
<ul>
<li @click="changeWrap(0)">red</li>
<li @click="changeWrap(1)">green</li>
<li @click="changeWrap(2)">blue</li>
</ul>
<!-- red页面逻辑结构 -->
<div class="wrap red" v-if="tag == 0" key="aaa"></div>
<!-- green页面逻辑结构 -->
<div class="wrap green" v-else-if="tag == 1" key="bbb"></div>
<!-- blue页面逻辑结构 -->
<div class="wrap blue" v-else key="ccc"></div>
<!-- v-if相关分支操作,在未显示情况下,是不会被渲染到页面中 -->
<!-- 通过key全局属性操作后,渲染过的分支会建立key对应的缓存,提高下一次渲染速度 -->
</div>
<script src="js/vue.js"></script>
<script type="text/javascript">
new Vue({
el: "#app",
data: {
tag: 0,
},
methods: {
changeWrap (num) {
this.tag = num;
}
}
})
</script>
<div id="app">
<p v-if="r1" key="p_r1">if条件</p>
<p v-show="r2">show条件</p>
<!--{{ num + 1 - 5 * 2 + '好的' }}-->
<ul>
<!--v-else会默认与v-if等有条件的分支绑定-->
<!--v-else-if必须由条件才和有条件v-if分支绑定-->
<li v-if="tag == 1">111</li>
<li v-else-if="tag == 2">222</li>
<li v-else>333</li>
</ul>
<ul>
<li @click="action('a')">a</li>
<li @click="action('b')">b</li>
<li @click="action('c')">c</li>
</ul>
<ul>
<li v-show="flag == 'a'">aaa</li>
<li v-show="flag == 'b'">bbb</li>
<li v-show="flag == 'c'">ccc</li>
</ul>
</div>
<script src="js/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
num: 10,
r1: false,
r2: false,
tag: 2,
flag: 'a'
},
methods: {
action: function (s) {
this.flag = s
}
}
})
</script>
循环指令
<div id="app">
<p>{{ nums[2] }}</p>
<ul>
<!-- 只遍历值 -->
<li v-for="num in nums">{{ num }}</li>
</ul>
<ul>
<!-- 值与索引 -->
<li v-for="(num, index) in nums">{{ num }} {{ index }}</li>
</ul>
<ul>
<!-- 值,键,索引 -->
<li v-for="(v, k, i) in people">{{ v }} {{ k }} {{ i }}</li>
</ul>
</div>
<script src="js/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
nums: [5, 3, 2, 1, 4],
people: {
'name': 'Owen',
'age': 17.5,
'gender': 'others'
}
}
})
</script>
评论案例
<style>
span {
margin-left: 100px;
cursor: pointer;
color: green;
}
span:hover {
color: red;
}
</style>
<div id="app">
<p>
<input type="text" v-model="val">
<button @click="add">评论</button>
</p>
<ul>
<li v-for="(info, i) in infos">
{{ info }}
<span @click="del(i)">x</span>
</li>
</ul>
</div>
<script src="js/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
infos: [], // 管理所有留言
val: '' // 管理当前留言
},
methods: {
del: function (i) {
// splice: 从哪个索引开始 操作的位数 操作成的结果(可变长)
this.infos.splice(i, 1) // 删除留言
},
add: function () {
let val = this.val;
if (val) {
this.infos.splice(0, 0, val); // 留言
this.val = '' // 输入框置空
}
}
}
})
</script>
解决插值表达式符号冲突
<div id="app">
${ msg }
</div>
<script src="js/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
msg: '12345'
},
delimiters: ['${', '}']
})
</script>
总结
指令:
文本:{{}} v-text v-html v-once
属性:v-bind:href | :href :class='c1' :class='[c1, c2]' :style='s1'
(s1={color: "red"})
事件:v-on:click | @click @click="action" @click="action(msg)" @click="action($event)"
表单:v-model
条件:v-show v-if v-else-if v-else
循环:v-for="(value, index) in list" v-for="(value, key, index) in dict"
成员:
el:挂载点
data:数据
methods:方法
computed:计算 -- 监听方法内所有的变量,返回值给绑定的变量,该变量无需在data中声明
watch:监听 -- 监听绑定的变量,绑定的变量必须在data中声明