VUE学习
1. Vue.js
-
渐进式
Vue被设计成自底向上逐层应用(模块组合式)
-
核心库
只关心视图层:(HTML+CSS+JS):给用户看和刷新后台给的数据
-
第三方库
网络通信(axios(实现ajax))、页面跳转(router)、状态管理(vuex)
-
vue-ui
element-ui、iview
-
WebPack
模块打包器,打包,压缩,合并及顺序加载。
2. MVVM 模式
3. 单向绑定v-bind
使用v-bind进行单向绑定,同时可以使用:作为v-bind的简写
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="app">
<!-- v-开头的都是指令,有vue提供的特殊属性 -->
<!-- 绑定标签使用v-bind,非标签使用{{message}} -->
<span v-bind:title = "message">
<!-- 注意v-bind是单项绑定 -->
鼠标停在这儿看看动态绑定的提示信息
</span>
<!-- v-bind的简写格式 -->
<input type="text" :value="message">
</div>
<script>
let vm = new Vue(
{
el:"#app",
data:{
message:"hello1",
}
}
);
</script>
</body>
</html>
4.双向绑定
使用v-model进行双向绑定
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="app">
<!-- v-开头的都是指令,有vue提供的特殊属性 -->
<!-- 绑定标签使用v-bind,非标签使用{{message}} -->
<span v-bind:title = "message">
<!-- 注意v-bind是单项绑定 -->
鼠标停在这儿看看动态绑定的提示信息
</span>
<input type="text" v-model="message">
</div>
<script>
let vm = new Vue(
{
el:"#app",
data:{
message:"hello1",
}
}
);
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="app">
<!-- v-model 双向绑定,案例演示 -->
<!-- v-model的相关属性 .lazy失去焦点时有反应, .number只留数字, .trim去除首尾空格 -->
<input type="text" v-model.lazy="message_1">
<h3>{{message_1}}</h3>
<p>爱好
<input type="checkbox" v-model="message_2" value="篮球"/> 篮球
<input type="checkbox" v-model="message_2" value="羽毛球"/> 羽毛球
<input type="checkbox" v-model="message_2" value="排球"/> 排球
</p>
{{message_2}}
<p>最喜欢哪个?
<input type="radio" v-model="message_3" value="篮球"/> 篮球
<input type="radio" v-model="message_3" value="羽毛球"/> 羽毛球
<input type="radio" v-model="message_3" value="排球"/> 排球
</p>
{{message_3}}
</div>
<script>
let vm = new Vue(
{
el:"#app",
data:{
message_1:"hello",
message_2:[],
message_3:"",
}
}
);
</script>
</body>
</html>
5. 事件绑定
使用v-on 绑定事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="app">
<!-- 使用v-on 绑定事件 -->
<button v-on:click="clickMe">点击我</button>
</div>
<script>
let vm = new Vue(
{
el:"#app",
data:{
num: 1
},
methods: {
clickMe: function(){
this.num+=1;
alert(this.num)
}
},
}
);
</script>
</body>
</html>
6. v-show v-if v-html 功能演示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="app">
<!-- v-html中的内容会当作时html代码进行执行 -->
<div v-html='url'></div>
<!-- v-show的div中的内容会一直存在,但是false时不显示 -->
<div v-show= 'isShow'>看到我了?</div>
<!-- v-if的div中的内容不会一直存在,当为true时才会生成 -->
<div v-if= 'isHave'>看到我了?</div>
<!-- 使用v-on 绑定事件 -->
<button v-on:click="clickMe">点击我</button>
</div>
<script>
let vm = new Vue(
{
el:"#app",
data:{
url:"<h1>Hello<h1>",
num: 1,
isShow: false,
isHave: false
},
methods: {
clickMe: function(){
this.isShow = !this.isShow;
this.isHave = !this.isHave;
}
},
}
);
</script>
</body>
</html>
7. v-if 条件判断
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="app">
<h3 v-if="type==='L'">L</h3>
<h3 v-else-if="type==='XL'">XL</h3>
<h3 v-else>XXXL</h3>
</div>
<script>
let vm = new Vue(
{
el:"#app",
data:{
type:'xXL',
url:"<h1>Hello<h1>",
num: 1,
isShow: false,
isHave: false
},
methods: {
clickMe: function(){
this.isShow = !this.isShow;
this.isHave = !this.isHave;
}
},
}
);
</script>
</body>
</html>
8.v-for
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="app">
<h3 v-if="type==='L'">L</h3>
<h3 v-else-if="type==='XL'">XL</h3>
<h3 v-else>XXXL</h3>
<li v-for="(item, index) in items">
{{item}}
</li>
</div>
<script>
let vm = new Vue(
{
el:"#app",
data:{
type:'xXL',
url:"<h1>Hello<h1>",
num: 1,
isShow: false,
isHave: false,
items: [1,2,3]
},
methods: {
clickMe: function(){
this.isShow = !this.isShow;
this.isHave = !this.isHave;
}
},
}
);
</script>
</body>
</html>
9. axios 网络请求
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
</head>
<body>
<div id="app">
<h3 v-if="type==='L'">L</h3>
<h3 v-else-if="type==='XL'">XL</h3>
<h3 v-else>XXXL</h3>
<li v-for="(item, index) in items">
{{item}}
</li>
<h3>我的年龄是{{age}}</h3>
</div>
<script>
let vm = new Vue(
{
el:"#app",
data:{
type:'xXL',
url:"<h1>Hello<h1>",
num: 1,
isShow: false,
isHave: false,
items: [1,2,3],
age:0
},
methods: {
clickMe: function(){
this.isShow = !this.isShow;
this.isHave = !this.isHave;
}
},
<!-- mounted是钩子函数(生命周期中的函数) 自动调用-->
mounted() {
axios.get('/data.json').then(
response=>{
console.log(response.data)
this.age = response.data.age
}
);
},
}
);
</script>
</body>
</html>
10.vue 生命周期
一个完整的生命周期:
(1)开始创建
(2)初始化数据
(3)编译模板
(4)挂载DOM
(5)渲染
(6)更新
(7)卸载
11. 计算属性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
</head>
<body>
<div id="app">
<h3 v-if="type==='L'">L</h3>
<h3 v-else-if="type==='XL'">XL</h3>
<h3 v-else>XXXL</h3>
<li v-for="(item, index) in items">
{{item}}
</li>
<h3>我的年龄是{{age}}</h3>
<h3>当前时间{{getTime}}</h3>
</div>
<script>
let vm = new Vue(
{
el:"#app",
data:{
type:'xXL',
url:"<h1>Hello<h1>",
num: 1,
isShow: false,
isHave: false,
items: [1,2,3],
age:0
},
methods: {
clickMe: function(){
this.isShow = !this.isShow;
this.isHave = !this.isHave;
}
},
mounted() {
axios.get('/data.json').then(
response=>{
console.log(response.data)
this.age = response.data.age
}
);
},
// 计算属性,重复调用内容不会改变,调用方式,直接使用属性名不需要加上()
computed:{
getTime:function(){
this.num;
return Date.now()
}
},
}
);
</script>
</body>
</html>
12. 组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
</head>
<body>
<div id="app">
<abar></abar>
</div>
<script>
Vue.component(
'commonchild',{
template:`<div><h3>commonChild</h3></div>`
}
);
//组件的声明和vue的创建是齐平的
Vue.component(
'abar',{
template:`
<div>
<h1>abar</h1>
<button v-on:click="clickMe">点击我</button>
<commonchild></commonchild>
<abarchild></abarchild>
</div>
`,
data() { //这里的data不能写属性
return {
}
},
methods: {
clickMe(){
alert("abar")
}
},
components:{ // 局部定义子组件,只能在父组件中进行调用
'abarchild':{
template:`<div><h2>hello abarchild</h2></div>`
}
}
}
)
let vm = new Vue(
{
el: "#app",
data:{
},
methods: {
},
}
);
</script>
</body>
</html>
13. 父组件传递数据到子组件
使用组件中的props属性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
</head>
<body>
<div id="app">
<abar thename = '主页' :show='true'></abar>
<abar thename = '个人' :show='false'></abar>
</div>
<script>
Vue.component(
'commonchild',{
template:`<div><h3>commonChild</h3></div>`
}
);
//组件的声明和vue的创建是齐平的
Vue.component(
'abar',{
template:`
<div>
<h1>{{thename}}</h1>
<button v-if='show' v-on:click="clickMe">点击我</button>
<commonchild></commonchild>
<abarchild></abarchild>
</div>
`,
data() { //这里的data不能写属性
return {
}
},
methods: {
clickMe(){
alert("abar")
}
},
props:{ // 接受父组件传进来的属性
thename:String,
show:Boolean,
},
components:{ // 局部定义子组件,只能在父组件中进行调用
'abarchild':{
template:`<div><h2>hello abarchild</h2></div>`
}
}
}
)
let vm = new Vue(
{
el: "#app",
data:{
},
methods: {
},
}
);
</script>
</body>
</html>
14.子组件传递数据到父组件
使用emit内置函数,子组件可以将数据传送到父组件中
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
</head>
<body>
<div id="app">
<abar thename = '主页' :show='true' @b_event='receive($event)'></abar>
<abar thename = '个人' :show='false'></abar>
{{show}}
</div>
<script>
Vue.component(
'commonchild',{
template:`<div><h3>commonChild</h3></div>`
}
);
//组件的声明和vue的创建是齐平的
Vue.component(
'abar',{
template:`
<div>
<h1>{{thename}}</h1>
<button v-if='show' v-on:click="clickMe">点击我</button>
<commonchild></commonchild>
<abarchild></abarchild>
</div>
`,
data() { //这里的data不能写属性
return {
}
},
methods: {
clickMe(){
alert("abar")
// 使用emit 传递消息
this.$emit('b_event', 'Hello')
}
},
props:{ // 接受父组件传进来的属性
thename:String,
show:Boolean,
},
components:{ // 局部定义子组件,只能在父组件中进行调用
'abarchild':{
template:`<div><h2>hello abarchild</h2></div>`
}
}
}
)
let vm = new Vue(
{
el: "#app",
data:{
show:[],
},
methods: {
// 定义一个接收消息的方法
receive(e){
this.show.push(`父组件收到消息${e}`)
}
},
}
);
</script>
</body>
</html>
15. ref 组件
ref组件一般来说,可以理解为对元素的重命名,通过他可以获取标签节点或者组件对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
</head>
<body>
<div id="app">
<!-- ref 放在标签上,获取的是原生节点 -->
<input type="text" ref="bar_ref" />
<button v-on:click="clickMe">父组件</button>
<!-- ref放组件上,拿到的是组件对象 -->
<abar ref="abar_ref"></abar>
</div>
<script>
//创建组件
Vue.component(
"abar",{
template:`
<div>
<button v-on:click="clickMe">点击我</button>
</div>`,
methods:{
clickMe(){
console.log(this)
}
},
data(){
return{
message:"123"
}
}
}
)
let vm = new Vue(
{
el:"#app",
data() {
return {
message:"123"
}
},
methods: {
clickMe(){
// 通过$refs直接获取标签节点
console.log(this.$refs.bar_ref.value)
// 通过$refs直接获取组件对象
console.log(this.$refs.abar_ref.message)
}
},
}
);
</script>
</body>
</html>
16. 事件总线
17.动态组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
</head>
<body>
<div id="app">
<ul>
<li><a @click="who='home'">首页</a></li>
<li><a @click="who='news'">新闻</a></li>
<li><a @click="who='blog'">博客</a></li>
</ul>
<!-- keep-alive是用来保存组件的状态 -->
<keep-alive>
<!-- 切换组件 -->
<component :is="who"></component>
</keep-alive>
</div>
<script>
let vm = new Vue({
el:"#app",
data() {
return {
who:'home'
}
},
components:{
'home':{
template:'<h1>这是首页</h1>'
},
'news':{
template:'<h1>这是新闻</h1>'
},
'blog':{
template:'<h1>这是博客</h1>'
}
}
});
</script>
</body>
</html>
18. slot 插槽
(1)slot基础
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
</head>
<body>
<div id="app">
<abar>
<!-- 组件中的html的代码是不起作用的,要想起作用 -->
<div><h1>abar</h1></div>
</abar>
</div>
<script>
Vue.component('abar',{
template:`
<div>
<slot></slot>
<h1>上面是插槽</h1>
</div>
`
});
let vm = new Vue({
el:"#app",
data() {
return {
}
}
});
</script>
</body>
</html>
(2) 有名插槽
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
</head>
<body>
<div id="app">
<abar>
<!-- 有名插槽-->
<div slot="slot1"><h1>abar</h1></div>
<div slot="slot2"><h1>slot2</h1></div>
</abar>
</div>
<script>
Vue.component('abar',{
template:`
<div>
<slot name="slot1"></slot>
<h1>上面是插槽</h1>
<slot name="slot2"></slot>
</div>
`
});
let vm = new Vue({
el:"#app",
data() {
return {
}
}
});
</script>
</body>
</html>
(3) 插槽的嵌套和传参