Vuejs 的入门
Day one
1. 简单认识
- 读音 / vju/
- 渐进式
- 响应式(页面内容随数据的改变而改变)
2. Vue的安装
3. Hello Vuejs
<body>
<div id="app">{{message}}{{name}}</div>
</body>
<script src="../js/vue.js"></script>
<script>
// 以前是命令式编程(编程范式)
// let 变量/ const常量
// 声明式的
const app = new Vue({
el: "#app", // 用于挂载要管理的元素
data: { //定义数据
message: "你好",
name: "lisi",
}
})
</script>
4. 列表展示
<body>
<ul id="app">
<li v-for="item in movies">{{item}}</li>
</ul>
</body>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
movies: ["123", "海王", "星际穿越"],
},
})
</script>
5. 计数器(理解事件)
<body>
<div id="app">
<h1>当前计数:{{count}}</h1>
<!-- <button v-on:click="count++">+</button>
<button v-on:click="count--">-</button> -->
<button v-on:click="add">+</button>
<button @click="sub">-</button>
</div>
</body>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
count: 1,
},
methods: {
add: function() {
this.count++;
},
sub: function() {
this.count--;
}
}
})
</script>
6. Vue的MVVM
Model ViewModel View
开发中什么时候称为方法,什么时候称为函数?
在类里的函数为方法。
7. Vue的生命周期
开发阶段的版本:debug
应用阶段的版本:release
8. github打开慢的问题
将其添加到hosts文件中(位置:C:\Windows\System32\drivers\etc),找到hosts文件,用记事本打开,在文本的最后添加:
140.82.114.3 github.com
199.232.5.194 github.global.ssl.fastly.net
185.199.108.153 github.github.io
185.199.109.153 github.github.io
185.199.110.153 github.github.io
185.199.111.153 github.github.io
9. Mustache(胡须)语法
{{}}:双大括号
<body>
<div id="app">
{{message}} 实现message数据展示
{{firstName + "·" +lastName}} 实现字符串拼接
{{count*2}} 实现简单计算
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
message: "你好呀",
count: 1,
firstName: "kobe",
lastName: "bryant"
}
})
</script>
</body>
10. v-once
<body>
<div id="app">
<h1 v-for="item in array">{{message}}</h1>
<!-- 在修改app.message属性后不改变 -->
<h1 v-once>{{message}}</h1>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
message: "你好呀",
}
})
</script>
</body>
11. v-html
<body>
<div id="app">
<h1>{{url}}</h1>
<h1 v-html="url"></h1>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
message: "你好呀",
url: '<a href="http://www.baidu.com">百度一下</a>'
}
})
</script>
</body>
12. v-text(不灵活,不经常用)
<body>
<div id="app">
<h1>{{url}}</h1>
<h1 v-text="url"></h1>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
message: "你好呀",
url: '<a href="http://www.baidu.com">百度一下</a>'
}
})
</script>
</body>
13. v-pre
<body>
<div id="app">
<h1>{{url}}</h1>
<h1 v-pre>{{url}}</h1>不做解析输出{{url}}
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
message: "你好呀",
url: '<a href="http://www.baidu.com">百度一下</a>'
}
})
</script>
</body>
14. v-cloak(斗篷)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
[v-cloak] {
display: none;
}
</style>
</head>
<body>
<!--再加上v-cloak之后,
在vue解析完成之前div会拥有v-cloak属性,
在解析完成之后会删除所有的属性
配合style样式可以实现页面没有被渲染的情况
-->
<div id="app" v-cloak>
<h1>{{url}}</h1>
<h1 v-cloak>{{url}}</h1>
</div>
<script src="../js/vue.js"></script>
<script>
setTimeout(function() {
const app = new Vue({
el: "#app",
data: {
message: "你好呀",
url: '<a href="http://www.baidu.com">百度一下</a>'
}
})
}, 1000);
</script>
</body>
</html>
15. v-bind(动态绑定)
<body>
<div id="app">
<a v-bind:href="ahref"><img v-bind:src="imgUrl" alt=""></a>
</div>
<script src="./../js/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
imgUrl: "https://img-home.csdnimg.cn/images/20201103102506.gif",
ahref: "https://marketing.csdn.net/p/407e01fd3fb945407effee4d6c1af75e?utm_source=toolbar_logo&spm=1001.2101.3001.4476"
}
})
</script>
</body>
v-bind的语法糖 :
<body>
<div id="app">
<a :href="ahref"><img :src="imgUrl" alt=""></a>
</div>
<script src="./../js/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
imgUrl: "https://img-home.csdnimg.cn/images/20201103102506.gif",
ahref: "https://marketing.csdn.net/p/407e01fd3fb945407effee4d6c1af75e?utm_source=toolbar_logo&spm=1001.2101.3001.4476"
}
})
</script>
</body>
15. v-bind(class的动态绑定对象形式)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.active {
color: red;
font-size: large;
}
</style>
</head>
<body>
<div id="app">
<div class="title" :class="{active: isactive, line: isline}">{{message}}</div>
<button @click="toggle">按钮</button>
</div>
<script src="./../js/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
message: "你好锕",
isactive: true,
isline: true,
},
methods: {
toggle: function() {
this.isactive = !this.isactive;
}
}
})
</script>
</body>
</html>
16. v-bind(数组和方法的形式)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.active {
color: red;
font-size: large;
}
</style>
</head>
<body>
<div id="app">
<div class="title" :class="[active, line]">{{message}}</div>
<div class="title" :class="getClasses()">{{message}}</div>
</div>
<script src="./../js/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
message: "你好锕",
active: 'active',
line: 'line',
},
methods: {
getClasses: function() {
return [this.active, this.line]
}
}
})
</script>
</body>
</html>
17. style的对象绑定
<body>
<div id="app">
<h2 :style="{fontSize: '80px', backgroundColor: 'red'}">{{message}}</h2>
</div>
<script src="./../js/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
message: "你好锕"
}
})
</script>
</body>
17. style的数组绑定
<body>
<div id="app">
<!-- 数组中存的是对象 -->
<h2 :style="[baseStyle]">{{message}}</h2>
</div>
<script src="./../js/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
message: "你好锕",
baseStyle: {
backgroundColor: 'red'
},
}
})
</script>
</body>
18. 计算属性
<body>
<div id="app" v-cloak>
<div class="title" :class="">{{firstName}} {{Lastname}}</div>
<div class="title" :class="">{{firstName+' '+Lastname}}</div>
<div class="title" :class="">{{getFullName()}}</div>
<div class="title" :class="">{{FullName}}</div>
</div>
<script src="./../js/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
firstName: 'li',
Lastname: 'Perry',
},
computed: {
FullName: function() {
return this.firstName + ' ' + this.Lastname;
},
},
methods: {
getFullName: function() {
return this.firstName + ' ' + this.Lastname;
}
}
})
</script>
</body>
19. 计算属性复杂操作+es6 for操作
<body>
<div id="app" v-cloak>
<h1>总价格:{{allprice}}</h1>
</div>
<script src="./../js/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
books: [{
id: 110,
name: 'a',
price: 119,
}, {
id: 111,
name: 'b',
price: 105,
}, {
id: 112,
name: 'c',
price: 106,
}, {
id: 113,
name: 'd',
price: 198,
}, {
id: 114,
name: 'e',
price: 89,
}, ]
},
computed: {
allprice: function() {
let s = 0;
for (let i = 0; i < this.books.length; i++) {
s += this.books[i].price;
}
return s;
},
},
})
</script>
</body>
<script>
let book = ['a', 'b', 'c'];
for (let i in book) {
console.log(i);
console.log(book[i]);
}//简写的 for 循环
for (let j of book) {
console.log(j);
}//j代表book[i],即每一个数组元素
</script>
Day two
1. 计算属性的setter和getter
<body>
<div id="app">
<h1>{{FullName}}</h1>
</div>
<script src="../../js/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
firstName: 'li',
LastName: 'Perry',
},
computed: {
FullName: {
// 如果没有set就只是只读属性,要是有set才能进行修改
set: function(newValue) {
const names = newValue.split(' ');
this.firstName = names[0];
this.LastName = names[1];
},
get: function() {
return this.firstName + ' ' + this.LastName;
},
}
},
})
</script>
</body>
2. 事件监听 v-on 的参数问题
<body>
<div id="app">
<button v-on:click="btnClick">button1</button>
<button v-on:click="btnClick1(123, $event)">button2</button>
</div>
<script src="../../js/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
counter: 0,
},
methods: {
btnClick() { //不传参数的话
console.log(event); //就是网页事件触发产生的对象
},
btnClick1(count, eve) { //传参数的话
console.log(count, eve); //$event就是网页事件触发产生的对象important
}
}
})
</script>
</body>
3. v-on 的修饰符问题
<body>
<div id="app">
<div @click="divClick()">
aaaaaaaaa
<!-- .stop修饰符的使用,阻止冒泡 -->
<button @click.stop="btnClick()">btn</button>
</div>
<!-- 阻止默认事件 -->
<form action="baidu">
<input type="submit" value="提交" @click.prevent="submitClick">
</form>
<!-- 监听某个键盘键的点击(回车键) -->
<input type="text" @keyup.enter="keyUp">
<!-- .once修饰符的使用 -->
<button @click.once="btn2Click">btn</button>
</div>
<script src="../../js/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
},
methods: {
divClick() { //不传参数的话
console.log('divClick'); //就是网页事件触发产生的对象
},
btnClick() { //传参数的话
console.log('btnClick'); //$event就是网页事件触发产生的对象important
},
submitClick() {
console.log('submitClick');
},
keyUp() {
console.log('keyUp');
},
btn2Click() {
console.log('btn2Click');
}
}
})
</script>
</body>
</html>
4. v-if 和 v-else-if 和 v-else
<body>
<div id="app" v-cloak>
<p v-if="score>=90">优秀</p>
<p v-else-if="score>=80">良好</p>
<p v-else-if="score>=60">合格</p>
<p v-else>不及格</p>
</div>
<script src="../../js/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
score: 90,
},
})
</script>
</body>
5. v-if 和 v-show
<body>
<div id="app" v-cloak>
<div v-if="isshow">
{{message}}
</div>
<div v-show="isshow">
{{message}}
</div>
</div>
<script src="../../js/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
message: "你好啊",
isshow: "true",
},
})
</script>
</body>
6. v-for 遍历数组
<body>
<div id="app" v-cloak>
<ul>
<li v-for="(item,index) in names">{{index+1}}.{{item}}</li>
</ul>
</div>
<script src="../../js/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
names: ['kobe', 'james', 'perry']
},
})
</script>
</body>
6. v-for 遍历对象
<body>
<div id="app" v-cloak>
<ul>
<!-- 第一个参数是值,第二个参数是键,第三个是序号-->
<li v-for="(value,key,index) in info">{{key+":"+value}}</li>
</ul>
</div>
<script src="../../js/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
info: {
name: 'perry',
age: 18,
height: 1.88,
}
},
})
</script>
</body>
7. v-for插入数据更高效的写法 key
diff算法,不懂原理
<body>
<div id="app" v-cloak>
<ul>
<li v-for="item in names" :key="item">{{item}}</li>
</ul>
</div>
<script src="../../js/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
names: ['kobe', 'james', 'perry']
},
})
</script>
</body>
8. 数组中能够触发响应式的方法
这些操作可以触发响应式
push
pop
shift
unshift
sort
reverse
注意:通过索引值改变数组中的元素不会触发响应式,可用splice方法代替
Daythree(impotent!!!)
1. fliter map reduce的使用
<script>
const nums = [1, 3, 4, ];
// let newnums = nums.filter((value, index, array) => {
// return value < 100;
// })
// console.log(newnums);
// let newnums = nums.map((value, index, array) => {
// return value * 10;
// })
// console.log(newnums);
// let newnums = nums.reduce((pre, cur, index, array) => {
// return pre + cur;
// }, 0)
// let newnums = nums.reduce((preV, cur, index, array) => {
// console.log(preV, cur);
// return preV * cur;
// }, 1)
// //如果没有设置初始值那么默认从1开始,即pre=a[0];cur=a[1]
// console.log(newnums);
let names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];
let nameNum = names.reduce((pre, cur) => {
if (cur in pre) {
pre[cur]++;
console.log(pre[cur]);
} else {
pre[cur] = 1;
console.log(pre);
}
return pre;
}, {})
console.log(nameNum); //{Alice: 2, Bob: 1, Tiff: 1, Bruce: 1}
</script>
2. v-model对radio,checkbox,和 select的配合
- radio
<body>
<div id='app' v-cloak>
<!-- 如果说使用了v-model那么可以去掉name属性 -->
<input type="radio" id="male" name="sex" value="男" v-model="sex">
<label for="male">男</label>
<input type="radio" id="famale" name="sex" value="女" v-model="sex">
<label for="famale">女</label>
<h2>{{sex}}</h2>
</div>
<script src='../../js/vue.js'></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
sex: '男',
// 默认checked属性就直接在双向绑定的数据中填写初始value
},
})
</script>
</body>
2.checkbox
<div id='app'>
<!-- 例一 -->
<label>
<input type="checkbox" v-model="isagree">同意协议
</label>
<h2>您选择的是:{{isagree}}</h2>
<button :disabled="!isagree">btn</button>
<!-- 例一 -->
<!-- 例二 -->
<label>
<input type="checkbox" name="hobbies" value="篮球" v-model="hobbies">篮球
</label>
<label>
<input type="checkbox" name="hobbies" value="乒乓球" v-model="hobbies">乒乓球
</label>
<label>
<input type="checkbox" name="hobbies" value="羽毛球" v-model="hobbies">羽毛球
</label>
<label>
<input type="checkbox" name="hobbies" value="排球" v-model="hobbies">排球
</label> {{hobbies}}
<!-- 例二 -->
</div>
<script src='../../js/vue.js'></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
isagree: 'true',
hobbies: [],
},
})
</script>
</body>
- select
<body>
<div id='app'>
<!-- multiple属性是用来多选的 -->
<!-- option属性不经常用 -->
<select name="abc" id="" v-model="fruits" multiple size="">
<option value="apple">apple</option>
<option value="banana">banana</option>
<option value="strawbrrey">strawbrrey</option>
<option value="perper">perper</option>
</select>
<h2>您选择的水果是:{{fruits}}</h2>
</div>
<script src='../../js/vue.js'></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
fruit: 'banana',
fruits: [],
},
})
</script>
</body>
3. v-model值绑定
<body>
<div id='app'>
<label v-for="item in originhobbies">
<input type="checkbox" :value="item" name="hobbies">{{item}}
</label>
</div>
<script src='../../js/vue.js'></script>
<script>
const app = new Vue({
el: '#app',
data: {
originhobbies: ['篮球', '足球', '排球', '羽毛球', '乒乓球'],
},
})
</script>
</body>
4. 修饰符的使用
<body>
<div id='app'>
<!-- lazy修饰符 -->
<!-- 在敲回车或者失去焦点时进行改动,不会那么频繁 -->
<input type="text" v-model.lazy="message">
<h1>{{message}}</h1>
<!-- number修饰符 -->
<!-- 解决在input中输入的数字都是字符串类型的问题 -->
<input type="text" v-model.number="age"> {{typeof age}}
<!-- trim修饰符 -->
<!-- 解决输入时首尾多余的空格 -->
<br>
<input type="text" v-model.trim.lazy="name">姓名是:{{name}}
</div>
<script src='../../js/vue.js'></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
age: 0,
name: "",
},
})
</script>
</body>
5. 注册组件的基本步骤
组件的使用分成三个步骤
- 创建组件构造器
- 注册组件
- 使用组件
<body>
<div id='app'>
<!-- 3.使用组件 -->
<my-cpn></my-cpn>
<my-cpn></my-cpn>
<my-cpn></my-cpn>
<div>
<my-cpn></my-cpn>
</div>
</div>
<script src='../../js/vue.js'></script>
<script>
// 1. 创建组件构造器对象
const cpnC = Vue.extend({
template: `
<div>
<h1>我是标题</h1>
<p>我是内容</p>
</div>`
})
// 2. 注册组件
// 标签名和构造器构造的对象
Vue.component('my-cpn', cpnC)
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
},
})
</script>
</body>
6. 全局局部组件
- Vue.component(“cpn”, cpnC); //全局属性,全局注册组件
- 直接挂载到某个实例中则是局部组件
<body>
<div id='app'>
<cpn></cpn>
</div>
<div id='app1'>
<cpn></cpn>
</div>
<script src='../../js/vue.js'></script>
<script>
// 1. 创建组件构造器对象
const cpnC = Vue.extend({
template: `
<div>
<h1>我是标题</h1>
<p>我是内容</p>
</div>`
});
// 2. 注册组件
// 标签名和构造器构造的对象,用component构建的都是全剧组件
// Vue.component("cpn", cpnC); //全局属性,全局注册组件
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
},
// 局部注册组件
components: {
// cpn 使用组件是的标签名
// cpnC 组件构造器创建的对象
cpn: cpnC,
}
});
const app1 = new Vue({
el: '#app1',
data: {
message: '你好啊',
},
});
</script>
</body>
7. 父子组件
<body>
<div id='app'>
<cpn2></cpn2>
<!-- 如果没有全局注册那么这里是不能使用的 -->
<cpn1></cpn1>
</div>
<script src='../../js/vue.js'></script>
<script>
// 构造
const cpnC1 = Vue.extend({
template: `
<div>
<h1>我是标题</h1>
<p>我是内容hahaha</p>
</div>`
})
// 构造
const cpnC2 = Vue.extend({
template: `
<div>
<h1>我是标题</h1>
<p>我是内容heheh</p>
<cpn1></cpn1> <!-- 可以在cpn2中使用cpn1,即cpn2是cpn1的父组件-->
</div>`,
components: {
cpn1: cpnC1, //在cpn2中注册cpn1
}
})
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
},
components: {
cpn2: cpnC2, //在app中注册
}
})
</script>
</body>
8. 组件语法糖
借用第7个的例子
<body>
<div id='app'>
<cpn2></cpn2>
<!-- 如果没有全局注册那么这里是不能使用的 -->
<cpn1></cpn1>
</div>
<script src='../../js/vue.js'></script>
<script>
// 组件的根,root
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
},
components: {
// 直接将需要用extend创建的对象放到这里,省去了构造器的创建
cpn2: {
template: `
<div>
<h1>我是标题</h1>
<p>我是内容heheh</p>
<cpn1></cpn1> <!-- 可以在cpn2中使用cpn1,即cpn2是cpn1的父组件-->
</div>`,
components: {
cpn1: {
template: `
<div>
<h1>我是标题</h1>
<p>我是内容hahaha</p>
</div>`
}, //在cpn2中注册cpn1
}
}, //在app中注册
}
})
</script>
</body>
9. 模板分离
方法1. <script type="text/x-template" id="cpn1"> </script>
方法2.
<template id="cpn">
<!-- 必须将所有的放在一个div里面 -->
<div>
<h1>head1</h1>
<p>contain</p>
</div>
</template>
<body>
<div id='app'>
<cpn></cpn>
</div>
<!-- 方法一 -->
<script type="text/x-template" id="cpn1">
<div>
<!-- 必须将所有的放在一个div里面,不然只显示第一个盒子-->
<h1>text/x-template</h1>
<p>contain</p>
</div>
</script>
<!-- 方法二 -->
<template id="cpn">
<!-- 必须将所有的放在一个div里面 -->
<div>
<h1>head1</h1>
<p>contain</p>
</div>
</template>
<script src='../../js/vue.js'></script>
<script>
Vue.component('cpn', {
template: '#cpn1', //分离后显得简洁许多
components: {
}
})
const app = new Vue({
el: '#app',
data: {
message: '你好吗!',
},
})
</script>
</body>
10. 组件中的数据存放
组件内部是不能访问vue实例的数据的
// 组件对象中有data属性
// 组件的原型都是指向Vue的,所以说vue有的它组件都有
Vue.component('cpn', {
template: '#cpn', //分离后显得简洁许多
// 这个data应该是一个function并返回一个实例的值 !important
data() {
return {
title: 'title'
}
}
})
11. 关于组件数据要用data,计时器案例告诉你
<body>
<div id='app'>
<cpn></cpn>
<cpn></cpn>
<cpn></cpn>
</div>
<template id="cou">
<div>
<h1>当前计数:{{counter}}</h1>
<button @click="increment">+</button>
<button @click="decrement">-</button>
</div>
</template>
<script src='../../js/vue.js'></script>
<script>
// 如果将obj提出来并在 data 中返回 obj 则是每次返回同一个obj导致所有的组件的数据改变
const obj = {
counter: 0,
}
Vue.component('cpn', {
template: "#cou",
data() {
// return obj;
return { //这样返回的obj每一次都是不同的,所以相互之间是不会别影响的
counter: 0,
};
},
methods: {
increment() {
this.counter++;
},
decrement() {
this.counter--;
}
}
})
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
},
})
</script>
</body>
12. 父子组件之间的通讯(父传子)
<body>
<div id='app'>
<cpn :cmovies="movies" :cmessage="message"></cpn>
</div>
<template id="cpn">
<div>
<h1>{{cmessage}}</h1>
<p>456</p>
<ul>
<li v-for="item in cmovies">{{item}}</li>
</ul>
</div>
</template>
<script src='../../js/vue.js'></script>
<script>
const cpn = {
template: '#cpn',
// props: ['cmovies'], // 利用数组进行传值
// 利用对象进行传值(可限制的东西更多,类型,默认值,)
props: {
// 1.
// cmovies: String, //限制String类型
// 2.
// cmovies: [String, Array], //限制是String或Array类型
cmovies: {
type: Array,
default () {
return []; //如果是数组或者对象那么只能用函数返回的形式
},
validator(value) {
return ['海王', '海贼王', '疯狂原始人'].indexOf(value) !== -1; //如果验证成功返回true,
}
},
cmessage: {
type: String, //限制类型
default: '', //默认值
required: true, //这个数据是必须要传入的
}
},
}
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
movies: ['海王', '海贼王', '疯狂原始人'],
},
components: {
'cpn': cpn,
}
})
</script>
</body>
13. 父子传值时驼峰标识问题
即:使用v-bind进行绑定的时候,vue不识别驼峰标识的变量名
<body>
<div id='app'>
<!-- 在传入时,v-bind是不支持驼峰的,只能用 - 代替 -->
<cpn :c-info="info" :c-message="message"></cpn>
</div>
<template id="cpn">
<div>
<h1>head</h1>
<!-- 使用时只能用驼峰命名来使用,即验证时定义的名称来使用 -->
<p>{{cInfo}}</p>
<p>{{cMessage}}</p>
</div>
</template>
<script src='../../js/vue.js'></script>
<script>
const cpnC = {
template: '#cpn',
props: {
// 在验证要传入的数据的时候使用驼峰命名法。在传入时,v-bind是不支持驼峰的,只能用 - 代替
// cMessage: String,
cInfo: {
type: Object,
default () {
return {};
}
},
cMessage: {
type: String,
default: '',
}
}
}
const app = new Vue({
el: '#app',
data: {
info: {
name: 'perry',
age: 18,
height: 1.80,
},
message: '你好锕',
},
components: {
cpn: cpnC,
}
})
</script>
</body>
14. 父子组件的通讯(子传父)
<body>
<div id='app'>
<!-- 自定义事件的默认传值为$emit的第二个参数 -->
<cpn @itemclick="btnclick"></cpn>
</div>
<template id='cpn'>
<div>
<button v-for="item in categories"
@click="btnclick(item)">{{item}}</button>
</div>
</template>
<script src='../../js/vue.js'></script>
<script>
const cpnC = {
template: '#cpn',
data() {
return {
categories: [{
id: 'aaa',
name: '热门推荐'
}, {
id: 'bbb',
name: '手机数码'
}, {
id: 'ccc',
name: '家用家电'
}, {
id: 'ddd',
name: '电脑办公'
}, ]
}
},
methods: {
btnclick(item) {
this.$emit('itemclick', item); //自定义事件,事件名称叫itemclick
}
}
}
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
},
methods: {
btnclick(item) {
console.log(item);
}
},
components: {
cpn: cpnC,
}
})
</script>
</body>
15. 父子组件的访问方式(父问子)
父组件访问子组件:使用 $children 或 $refs
<body>
<div id='app'>
<cpn1></cpn1>
<cpn1></cpn1>
<p>在组件上添加一个类似id的东西:ref="id"</p>
<cpn1 ref="aaa"></cpn1>
<button @click="btnclick">btn</button>
</div>
<template id='cpn'>
<div>
<p>我是子组件</p>
</div>
</template>
<script src='../../js/vue.js'></script>
<script>
const cpnC1 = {
template: '#cpn',
methods: {
showMessage() {
console.log('showMessage1');
}
},
data() {
return {
name: 'nameSon',
}
}
}
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
},
methods: {
btnclick() {
console.log(this.$children);//直接在父组件中访问子组件对象
this.$children[0].showMessage();
// for (let i of this.$children) {
// console.log(i);
// }
console.log(this.$refs.aaa.name);
}
},
components: {
cpn1: cpnC1,
}
})
</script>
</body>
子组件方法父组件:使用 $parent
子组件直接访问跟:使用 $root
<body>
<div id='app'>
<cpn></cpn>
</div>
<template id='cpn'>
<div>
我是子组件
<button @click='btnclick'>按钮</button>
<ccpn></ccpn>
</div>
</template>
<template id='ccpn'>
<div>
我是子子组件
<button @click='btnclick'>按钮</button>
</div>
</template>
<script src='../../js/vue.js'></script>
<script>
const cpnC = {
template: '#cpn',
methods: {
btnclick() {
// 1. 访问父组件
console.log(this.$parent);
}
},
components: {
ccpn: {
template: "#ccpn",
methods: {
btnclick() {
// 1. 访问父组件
console.log(this.$parent);
console.log(this.$root.messages);
}
}
},
}
}
const app = new Vue({
el: '#app',
data: {
messages: '你好锕!',
},
components: {
cpn: cpnC,
},
})
</script>
</body>
Day four
1. 插槽的基本使用
- 插槽的基本使
<slot></slot>
- 插槽的默认值
<slot><button>btn</button></slot>
- 如果插槽中插入多个元素,都显示
<body>
<div id='app'>
<cpn>
<i>hahah</i>
<p>ppppppp</p>
<div>div</div>
</cpn>
<cpn><i>12</i></cpn>
<cpn><i>32</i></cpn>
<cpn></cpn>
<cpn></cpn>
<cpn></cpn>
<cpn></cpn>
</div>
<template id='cpn'>
<div>
<h1>123</h1>
<p>cpn er </p>
<slot><button>btn</button></slot>
</div>
</template>
<script src='../../js/vue.js'></script>
<script>
const cpnC = {
template: '#cpn',
}
const app = new Vue({
el: '#app',
components: {
cpn: cpnC,
}
})
</script>
</body>
2. 具名插条
<body>
<div id='app'>
<cpn><span slot="mid">标题</span></cpn>
<cpn>
<button slot="left">返回</button>
</cpn>
</div>
<template id='cpn'>
<div>
<h1>123</h1>
<p>cpn er </p>
<slot name="left"><span>左边</span></slot>
<slot name="mid"><span>中间</span></slot>
<slot name="right"><span>右边</span></slot>
<slot>hahah</slot>
<slot>heheh</slot>
<!-- 没有名字的传进来的如果也没有名字那么就都替换 -->
</div>
</template>
<script src='../../js/vue.js'></script>
<script>
const cpnC = {
template: '#cpn',
}
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
},
components: {
cpn: cpnC,
}
})
</script>
</body>
3. 编译的作用域
<body>
<div id='app'>
<!--在哪里面用找哪个,这个cpn在vue里面注册的,所以是在vue里被使用-->
<cpn v-show="isshow"></cpn>
</div>
<template id='cpn'>
<div>
<h2>我是子组件</h2>
<p>我是内容</p>
<!--这个是是组件中的内容所以 isshow 为 false-->
<button v-show="isshow">btn</button>
</div>
</template>
<script src='../../js/vue.js'></script>
<script>
const cpnC = {
template: '#cpn',
data() {
return {
isshow: false, //组件里面
}
}
}
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
isshow: true, //实例里面
},
components: {
cpn: cpnC,
}
})
</script>
</body>
4. 作用域插条
<body>
<div id='app'>
<cpn></cpn>
<cpn>
<!-- 这个scope是自己命名的 -->
<template slot-scope='scope'>
<span v-for="item in scope.data">{{item}}/</span></br>
<span>{{scope.data.join(' - ')}}</span>
</template>
</cpn>
<cpn></cpn>
</div>
<template id='cpn'>
<div>
<!-- 这个data是自己命名的 -->
<slot :data="movies">
<ul><li v-for="item in movies">{{item}}</li></ul>
</slot>
</div>
</template>
<script src='./../js/vue.js'></script>
<script>
const cpnC = {
template: '#cpn',
data() {
return {
movies: ['海王', '哈利破特', '哪吒'],
}
}
}
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
},
components: {
cpn: cpnC,
}
})
</script>
</body>