MVVM模式通过视图与模型的双向绑定简化前端操作,渐进式框架
vue前端框架,是一个js文件;下载js文件并在页面中引用
vue.js下载方式:
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<script src="vue/vue-2.6.10.js">script>
head>
<body>
<div id="app">
<h2>{{name}}程序员h2>
<input type="text" v-model="num">
<button v-on:click="num++">点击button>
<h2>数量为{{num}}h2>
div>
<script>
var app = new Vue({
el:"#app", <!--要渲染的页面元素为 app-->
data:{
name:"Java",
num:1
}
});
script>
body>
html>
创建实例可以指定模板id、数据和方法
在实例化、模板渲染过程中操作可以使用钩子函数
钩子函数:是在Vue实例生命周期过程中的不同阶段,钩子函数通过一些特定的函数对vue实例进行操作。
具体生命周期及钩子函数请参考:https://blog.csdn.net/focusmickey/article/details/108750466
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<script src="vue/vue-2.6.10.js">script>
head>
<body>
<div id="app">
信息是:{{msg}}
div>
<script type="text/javascript">
var app = new Vue({
el:"#app",
data:{
msg:""
},
<!--钩子函数 created() -->
created(){
this.msg= "Vue实例初始化msg为空,通过created()钩子函数进行操作赋值";
console.log(this); <!--打印出this,应该是vue实例对象-->
}
});
script>
body>
html>
Vue的指令:v-
插值格式:
{{表达式}}
在网速较慢时,可能会出现原始的 {{}} ,加载完毕后才会显示正确数据。插值闪烁
v-text,v-html可以解决插值闪烁
还可以将数据输出到元素内部,如果有html代码,v-text普通文本输出,v-html会将html标签渲染。
单向绑定将数据输出到页面
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<script src="vue/vue-2.6.10.js">script>
head>
<body>
<div id="app">
{{msg}} <br>
v-text:<span v-text="msg">span><br>
v-html:<span v-html="msg">span><br>
div>
<script type="text/javascript">
var app = new Vue({
el:"#app",
data:{
msg:"Vue
"
}
});
script>
body>
html>
双向绑定:视图和模型中数据相互影响
可使用的元素有:
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<script src="vue/vue-2.6.10.js">script>
head>
<body>
<div id="app">
<input type="checkbox" value="0" v-model="lag">0<br>
<input type="checkbox" value="1" v-model="lag">1<br>
<input type="checkbox" value="2" v-model="lag">2<br>
<input type="radio" value="4" v-model="rad">4<br>
{{lag.join(",")}}
div>
<script type="text/javascript">
var app = new Vue({
el:"#app",
data:{
lag:[],
}
});
script>
body>
html>
页面元素绑定事件
格式:
v-on:事件名="js片段或函数名"
v-on:click='add'
@事件名="js片段或函数名"
@click='add'
事件修饰符:
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<script src="vue/vue-2.6.10.js">script>
head>
<body>
<div id="app">
<button v-on:click="num++">增加button>
<button @click="dec">减少button>
num = {{num}} <br>
事件冒泡测试<br>
<div style="background-color: lightgreen; width: 100px; height: 100px;" @click="print('div被点击')">
<button @click.stop="print('button被点击')">点我button>
div>
<br>阻止默认事件的发生--事件修饰符 不会进行跳转了<br>
<div>
<a href="https://www.baidu.com" @click.prevent="print('点击了超链接')">百度a>
div>
div>
<script type="text/javascript">
var app = new Vue({
el:"#app",
data:{
num:1
},
methods:{
//递减
dec(){
this.num--;
},
//打印
print(str){
console.log(str);
}
}
});
script>
body>
html>
数组、对象遍历
可以在vue实例化的时候指定要遍历的数据,通过v-for在模板中遍历显示数据。一般情况下,要遍历的数据可以通过钩子函数created发送异步请求获取数据
格式:
//遍历数组
v-for="item in items"
v-for="(user, index) in users" //index索引号
//遍历对象
v-for="value in object"
v-for="(value,key) in object"
v-for="(value,key,index) in object"
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<script src="vue/vue-2.6.10.js">script>
head>
<body>
<div id="app">
<ul>
<li v-for="(user,index) in users">
{{index}}--{{user.name}}--{{user.age}}--{{user.gender}}
li>
ul>
<hr>
<ul>
<li v-for="(value,key,index) in person">
{{index}}--{{key}}--{{value}}
li>
ul>
div>
<script type="text/javascript">
var app = new Vue({
el:"#app",
data:{
users:[
{"name":"张三","age":10,"gender":"男"},
{"name":"李四","age":11,"gender":"女"},
{"name":"王五","age":12,"gender":"男"}
],
person:{"name":"对象","addres":"上海","age":20}
}
});
script>
body>
html>
key是唯一标识,key一般使用在遍历完后,又增、减集合元素
<ul><li v-for="(item,index) in items" :key="index">li> ul>
通过判断实现内容的隐藏
格式:
v-if="布尔表达式"
v-show="布尔表达式"
v-else 元素必须紧跟在带 v-if 或者 v-else-if 的元素的后面,否则它将不会被识别。
v-if在条件不满足时,元素不存在
v-show条件不满足时,只是对条件进行隐藏
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<script src="vue/vue-2.6.10.js">script>
head>
<body>
<div id="app">
<button @click="show=!show">点击button>
<h2 v-if="show">
Vue!
h2>
<hr>
<ul>
<li v-for="(user,index) in users" v-if="user.gender=='男'" style="background-color: lightgreen">
{{index}}--{{user.name}}--{{user.age}}--{{user.gender}}
li>
<li v-else style="background-color: red">
{{index}}--{{user.name}}--{{user.age}}--{{user.gender}}
li>
ul>
<hr>
<h2 v-show="show">
v-show
h2>
div>
<script type="text/javascript">
var app = new Vue({
el:"#app",
data:{
show:true,
users:[
{"name":"张三","age":10,"gender":"男"},
{"name":"李四","age":11,"gender":"男"},
{"name":"王五","age":12,"gender":"女"}
]
}
});
script>
body>
html>
在元素的属性上使用vue实例的数据
<img src=" " height=" " />
如果src和height属性不想写死,而是通过获取vue实例中数据属性值,使用v-bind
格式:
<img v-bind:src="vue实例中数据属性名" :height="vue实例中数据属性名" />
可以直接 : 简写
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<script src="vue/vue-2.6.10.js">script>
<style type="text/css">
div{
width: 100px;
height: 100px;
color: yellow;
}
.red{
background-color: red;
}
.green{
background-color: green;
}
style>
head>
<body>
<div id="app">
<button @click="color='red'">红色button>
<button @click="color='green'">绿色button>
<div :class="color">
v-bind: 简写 :
div>
<hr>
<button @click="bool=!bool">切换颜色button>
<div :class="{red:bool,green:!bool}">
clss属性的特殊用法
div>
div>
<script type="text/javascript">
var app = new Vue({
el:"#app",
data:{
color:"red",
bool:true
}
});
script>
body>
html>
日期的毫秒值进行格式化(yyyy-MM-dd)字符串,使用computed计算属性中的方法进行处理
计算属性的方法必须有返回值
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<script src="vue/vue-2.6.10.js">script>
head>
<body>
<div id="app">
<h2>
日期为:{{day}}
h2>
div>
<script type="text/javascript">
var app = new Vue({
el:"#app",
data:{
daynum:2429032123201
},
computed:{
day(){
const d = new Date(this.daynum);
return d.getFullYear() +"-"+(d.getMonth()+1)+"-"+d.getDay();
}
}
});
script>
body>
html>
可以用在插值或制定表达式复杂的时候,可以把属性数据经过方法处理之后返回
vue实例中数据属性,在页面中修改而产生了变化,可以通过watch监控获取改变前后的值
如果修改的是对象属性,可以开启深度监控获取修改后最新的对象数据。如;person.name
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<script src="vue/vue-2.6.10.js">script>
head>
<body>
<div id="app">
<input type="text" v-model="message">
<hr>
<input type="text" v-model="person.name">
<hr>
<input type="text" v-model="person.age"><button @click="person.age++">+button>
<br>
<h2>
姓名:{{person.name}};年龄:{{person.age}}
h2>
div>
<script type="text/javascript">
var app = new Vue({
el:"#app",
data:{
message:"0",
person:{"name":"lisi","age":13}
},
watch:{
//监控数据属性
message(oldVlue,newVlue){ //监控变量的方法名要和数据属性变量名一致
console.log("new:"+newVlue);
console.log("old:"+oldVlue);
},
//对象监控
person: { //与对象属性名一致
//需开启深度监控:监控对象属性变化
deep:true,
//handler方法 obj可以获取到最新属性数据
handler(obj){
console.log("name:"+obj.name + " age:" + obj.age);
}
}
}
});
script>
body>
html>
watch使用场景:可以监视视图中数据变化而做出响应。如:下拉框列表中,选择了对应的下拉框选项之后,要根据最新的值去加载一些其他数据。
在大型应用开发的时候,页面可以划分成很多部分。往往不同的页面,也会有相同的部分。例如可能会有相同的头部
导航。
但是如果每个页面都独自开发,这无疑增加了开发的成本。所以会把页面的不同部分拆分成独立的组件,然后在不同
页面就可以共享这些组件,避免重复开发。
组件其实也是一个Vue实例,因此它在定义时也会接收:data、methods、生命周期函数等。
全局组件定义完毕,任何vue实例都可以直接在HTML中通过组件名称来使用组件了。
data的定义方式比较特殊,必须是一个函数。
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<script src="vue/vue-2.6.10.js">script>
head>
<body>
<div id="app">
<counter>counter>
div>
<script type="text/javascript">
//定义组件
const count = {
template:"", //模板
data(){ //data定义方式是一个函数
return {num:0}
}
};
//全局注册组件:在所有vue实例中都可以使用
//参数1:组件名 参数2:具体组件
//Vue.component("counter",count);
var app = new Vue({
el:"#app",
//局部注册 //这个counter组件只能在当前的Vue实例中使用
components:{
counter:count
}
});
script>
body>
html>
全局注册:在所有vue实例中都可以使用。eg:头部导航菜单
局部注册:组件只能在当前的Vue实例中使用
各个组件之间以嵌套的关系组合在一起,那么这个时候不可避免的会有组件间通信的需求。
传递普通字符串:
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<script src="vue/vue-2.6.10.js">script>
head>
<body>
<div id="app">
<introduce :title="msg">introduce>
div>
<script type="text/javascript">
//定义组件
const introduce = {
template: "{{title}}
>",
//定义接收父组件的属性
props:["title"]
};
//全局注册组件
Vue.component("introduce",introduce);
var app = new Vue({
el:"#app",
data:{
msg:"父组件的msg内容"
}
});
script>
body>
html>
传递数组或者对象:
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<script src="vue/vue-2.6.10.js">script>
head>
<body>
<div id="app">
<my-list :items="lessons">my-list>
div>
<script type="text/javascript">
//定义组件
const myList = {
template:`
- {{item.id}}--{{item.name}}
`,
//定义接收父组件的属性
props:{
items:{
//数据类型:数组-Array;对象--Object
type:Array,
default:[]
}
}
};
var app = new Vue({
el:"#app",
data:{
msg:"父组件msg属性数据",
lessons:[
{"id":1,"name":"lisi"},
{"id":2,"name":"zs"},
{"id":3,"name":"ww"}
]
},
components:{
myList //组件名和定义的名称一样可简写
}
});
script>
body>
html>
default,如果是对象则需要写成方法的方式返回默认值。如:
default(){
return {"xxx":"默认值"};
}
点击按钮改变父组件中的数据
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>子组件向父组件通信title>
<script src="vue/vue-2.6.10.js">script>
head>
<body>
<div id="app">
<counter @plus="numPlus" @reduce="numReduce" :snum="num">counter>
<h2>{{num}}h2>
div>
<script type="text/javascript">
//定义组件
const counter = {
<!--只能有一个根元素,所以用 div对其进行包裹-->
template:`
`,
props:["snum"],
methods: {
incrnum(){
//调用父组件中的方法
return this.$emit("plus"); //有数据需要接受的话 this.$emit("plus",123); 相应的定义方法中要有形参
},
decrnum(){
return this.$emit("reduce");
}
}
};
var app = new Vue({
el:"#app",
data:{
num:0
},
components:{
counter
},
methods:{
numPlus(){
this.num++;
},
numReduce(){
this.num--;
}
}
});
script>
body>
html>
发送异步请求获取数据,
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<script src="vue/vue-2.6.10.js">script>
<script src="vue/axios.min.js">script>
head>
<body>
<div id="app">
<ul>
<li v-for="user in users">{{user.id}}--{{user.name}}li>
ul>
div>
<script type="text/javascript">
var app = new Vue({
el:"#app",
data: {
users:[]
},
create(){
//钩子函数,初始化数据
axios.get("data.json").then(res=>{
console.log(res);
app.users = res.date; //在axios回调函数中不能用 this,表示窗口
}).catch(err=>alert(err));
}
});
script>
body>
html>
注意:如果不是一个服务器可能会出现跨域请求
跨域:在前端js中发送异步请求,请求的地址与当前服务器ip或者端口号不同都是跨域请求,在服务器端配置@CrossOrigin