文章目录
一、了解Vue.js
- Vue 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。
- Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。
- JavaScript框架
- 简单Dom操作
- 响应式数据驱动
- 官网:https://doc.vue-js.com/
二、Vue与MVVM
- 数据与视图分离:Vue数据独立在
data
里面,视图在template
中 - 以数据驱动视图,只关心数据的变化,dom操作被封装
- MVC:
Model
数据→View
视图→Controller
控制器 - MVVM:
Model View ViewModel
与Vue 的对应:view
对应template
,vm
对应new Vue({…})
,model
对应data
- 三者的关系:
view
可以通过事件绑定的方式影响model
,model
可以通过数据绑定的形式影响到view
,viewModel
是把model
和view
连起来的连接器
三、第一个Vue程序
步骤:
1.导入Vue.js
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
或
<!-- 生产环境版本,优化了尺寸和速度 -->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
2.创建Vue实例对象,设置el属性和data属性
el:挂载点
- el是用来设置Vue实例挂载(管理)的元素
- 作用范围:el选项命中的元素及其内部的后代元素
- 可以使用其他的选择器,建议使用ID选择器
- 处理作用在div标签上还可以作用在其他双标签上,不能是html和body
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
</script>
3.使用简洁的模板语法把数据渲染在页面上
<div id="app">
{{ message }}
</div>
4.小结
完整代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
{{ message }}
</div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
</script>
</body>
</html>
我们可以修改message的值来修改页面的内容:
- vue的7个属性
- el属性: 用来指示vue编译器从什么地方开始解析 vue的语法,可以说是一个占位符。
- data属性: 用来组织从view中抽象出来的属性,可以说将视图的数据抽象出来存放在data中。
- template属性: 用来设置模板,会替换页面元素,包括占位符
- methods属性: 放置页面中的业务逻辑,js方法一般都放置在methods中
- render属性: 创建真正的Virtual Dom
- computed属性: 用来计算
- watch属性: watch:function(new,old){} 监听data中数据的变化 两个参数,一个返回新值,一个返回旧值。
四、Vue语法
指令式渲染
v-text
:不能解析标签v-html
:可以解析标签
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<span v-text="text"></span>
<span v-html="text"></span>
</div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
text: '<h2>Hello<h2>'
}
})
</script>
</body>
</html>
插值表达式
{{data中的数据}}
v-text
和表达式的区别:
- 默认的
v-text
没有闪烁的问题,插值表达式有 - v-text会默认覆盖元素中原来的内容
v-cloak
<span v-cloak>{{msg}}</span>
v-cloak
能够解决插值表达式闪烁的问题:它首先会把设置了v-cloak
的标签元素隐藏dispaly:none;
,当加载完毕之后,元素身上的v-cloak
就会消失。
v-show
<span v-show="false">{{msg}}</span>
v-show
:改变css样式中display
属性,true
表示block,false
表示none
v-bind
绑定
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<span v-bind:title="message">
鼠标悬停几秒钟查看此处动态绑定的提示信息!
</span>
</div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
</script>
</body>
</html>
判断
v-if
和v-else
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<h2 v-if="ok">YES</h2>
<h2 v-else>NO</h2>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
ok: true
}
});
</script>
</body>
</html>
v-if
、v-else-if
和v-else
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<h2 v-if="type==='A'">A</h2>
<h2 v-else-if="type==='B'">B</h2>
<h2 v-else>C</h2>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
type: 'A'
}
});
</script>
</body>
</html>
循环
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<li v-for="(item,index) in items">
{{item.message}}---{{index}}
</li>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
items: [
{message: '简介'},
{message: '数据'},
{message: 'Hello'}
]
}
});
</script>
</body>
</html>
绑定事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<button v-on:click="sayHi">按钮</button>
</div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
message: '好好学习'
},
methods: { //方法必须定义在Vue的Methods对象中
sayHi: function () {
alert(this.message);
}
}
})
</script>
</body>
</html>
双向绑定
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<input type="text" v-model="message">{{message}}
</div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
message: '123'
}
})
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
性别:
<input type="radio" name="radiosex" value="男" v-model="sex">
<input type="radio" name="radiosex" value="女" v-model="sex">
<!--在这里显示选择了哪一个-->
<p>
性别选择了:{{sex}}
</p>
</div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
sex: ''
}
})
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
下拉框:
<select v-model="selected">
<option value="" disabled>--请选择--</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<span>值:{{selected}}</span>
</div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
selected: ''
}
})
</script>
</body>
</html>
五、组件
基本格式:
Vue.component("组件名",{
props: ['参数'],
template: '<li>{{参数}}</li>'
});
-
如果不需要传递参数,只是简单的组件复用,可以去掉
props
-
要用
v-bind:参数名="data"
来绑定参数的值为data属性中的值 -
注意
template:
中的容器只有一个父元素,不能有多个,可以用一个div包裹。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<hello v-for="item in items" v-bind:hi="item" ></hello>
</div>
<script type="text/javascript">
Vue.component("hello",{
props: ['hi'],
template: '<li>{{hi}}</li>'
});
var vm = new Vue({
el: '#app',
data: {
items: ['JAVA','HTML','PHP'],
}
})
</script>
</body>
</html>
六、计算属性
methods和computed
computed
会基于响应数据缓存,methods
不会缓存- diff之前先看data里面的数据是否发生变化,如果没有变化
computed
的方法不会被执行,但methods
里面的方法会执行
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<p>当前时间:{{currentTime()}}</p>
<p>当前时间:{{currentTime2}}</p>
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
msg: 'Hello'
},
methods: {
currentTime: function () {
return Date.now();//返回当前时间
}
},
computed: {
currentTime2: function () {
return Date.now();//返回当前时间
}
}
})
</script>
</body>
</html>
七、插槽
- 插槽就是子组件中的提供给父组件使用的一个占位符,用
<slot></slot>
表示,父组件可以在这个占位符中填充任何模板代码,如 HTML、组件等,填充的内容会替换子组件的<slot></slot>
标签。 - 测试:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<div>
<todo>
<slot1 slot="slot1" v-bind:item="item"></slot1>
<slot2 slot="slot2" v-for="i in item2" v-bind:item2="i"></slot2>
</todo>
</div>
</div>
<script type="text/javascript">
Vue.component('todo',{
template: '<div>' +
'<slot name="slot1"></slot>' +
'<ul>' +
'<slot name="slot2"></slot>' +
'</ul>' +
'</div>'
});
Vue.component('slot1',{
props: ['item'],
template: '<p>{{item}}</p>'
});
Vue.component('slot2',{
props: ['item2'],
template: '<li>{{item2}}</li>'
});
var vm = new Vue({
el: '#app',
data: {
item: '课程',
item2: ['PHP','JAVA','JS']
}
})
</script>
</body>
</html>
八、自定义事件
父组件使用props
传递数据给子组件,子组件通过自定义事件跟父组件通信。
this.$emit('自定义事件的名称',自定义事件处理程序需要的参数1,参数2,参数3);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<div>
<todo>
<slot1 slot="slot1" v-bind:item="item"></slot1>
<!-- v-bind:props:给子组件传值 -->
<!-- v-on:自定义事件 子组件事件绑定父组件事件 -->
<slot2 slot="slot2" v-for="(i,index) in item2" v-bind:item2="i"
v-bind:index="index" v-on:remove="removeItem(index)"></slot2>
</todo>
</div>
</div>
<script type="text/javascript">
Vue.component('todo',{
template: '<div>' +
'<slot name="slot1"></slot>' +
'<ul>' +
'<slot name="slot2"></slot>' +
'</ul>' +
'</div>'
});
Vue.component('slot1',{
props: ['item'],
template: '<p>{{item}}</p>'
});
Vue.component('slot2',{
props: ['item2','index'],
//只能绑定当前组件的方法
template: '<li>{{index}}---{{item2}} <button @click="remove(index)">删除</button></li>',
methods: {
remove: function (index) {
this.$emit('remove',index);
}
}
});
var vm = new Vue({
el: '#app',
data: {
item: '课程',
item2: ['PHP','JAVA','JS']
},
methods: {
removeItem: function (index) {
console.log(this.item2[index]+"已删除");
this.item2.splice(index,1);//删除数组中的第index个
}
}
})
</script>
</body>
</html>
九、Axios异步通信
-
测试
(1)新建一个data.json数据:
{
"name":"高朗",
"url": "https://blog.csdn.net/qq_43466788",
"page": "1",
"isNonProfit":"true",
"address": {
"street": "含光门",
"city":"陕西西安",
"country": "中国"
},
"links": [
{
"name": "CSDN",
"url": "https://blog.csdn.net/"
},
{
"name": "4399",
"url": "https://www.4399.com/"
},
{
"name": "百度",
"url": "https://www.baidu.com/"
}
]
}
(2)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.0/axios.js"></script>
</head>
<body>
<div id="app">
<span>{{info.name}}</span>
<a v-bind:href="info.url">博客地址</a>
<span>{{info.page}}</span>
<span>{{info.isNonProfit}}</span>
<span>{{info.address.country}}</span>
<div v-for="(link,index) in info.links">
<p v-text="index"></p>
<span v-text="link.name"></span>
<a v-bind:href="link.url" v-text="link.url"></a>
</div>
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data(){
return{
info: {
//请求的返回参数合适,必须和 json字符串一样
name: null,
url: null,
page: null,
isNonProfit: null,
address: {
street: null,
city: null,
country: null
},
links: [
{
name: null,
url: null
},
{
name: null,
url: null
},
{
name: null,
url: null
}
]
},
}
},
mounted(){ //钩子函数 链式编程
axios.get('../data.json').then(response=>(this.info=response.data));
}
})
</script>
</body>
</html>