VUE学习三:双向绑定指令(v

导言
let、const和var的区别(涉及块级作用域)
JavaScript 中双引号、单引号和反引号的区别
一、01-v-model使用
1. 01-v-model的基本使用.html
v-mode指令 大多用在表单上进行双向绑定
{
{message}}
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
}
})
2. 02-v-model的原理.html
v-model: 双向绑定
v-bind: 单向绑定,data数据传递到页面。 input事件: 监听用户输入的数据传递到data中
{
{message}}
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
},
methods: {
valueChange(event) {
// event 不需要传参,会自动传值
console.log(event)
// event.target.value 表单中的输入值
this.message = event.target.value;
}
}
})
3. 03-v-model结合radio类型.html
男
女
您选择的性别是: {
{sex}}
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
sex: '女'
}
})
4. 04-v-model结合checkbox类型.html
1.checkbox单选框: 对应 Boolean类型
同意协议
您选择的是: {
{isAgree}}
2.checkbox多选框: 对应 数组类型
篮球
足球
乒乓球
羽毛球
您的爱好是: {
{hobbies}}
值绑定: 从data 中获取数据进行 展示
{
{item}}
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
isAgree: false, // 单选框
hobbies: [], // 多选框,
originHobbies: ['篮球', '足球', '乒乓球', '羽毛球', '台球', '高尔夫球']
}
})
5. 05-v-model结合select类型.html(下拉多选有问题)
1.选择一个:字符串类型
您选择的水果是: {
{fruit}}
2.选择多个:数组类型
您选择的水果是: {
{fruits}}
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
fruit: '香蕉',
fruits: []
}
})
6. 06-v-model修饰符的使用.html
1.修饰符: lazy: 点击回车的时候 会进行 实时绑定
{
{message}}
2.修饰符: number: v-model默认绑定为 string类型, number改变类型
{
{age}}-{
{typeof age}}
3.修饰符: trim :去掉表单中输入的两边的空格
您输入的名字:{
{name}}
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
age: 0,
name: ''
}
})
var age = 0
age = '1111'
age = '222'
二、02-组件化开发
1. 01-组件化的基本使用.html
创建组件构造器对象 Vue.extend({})
注册(全局)组件:Vue.component('my-cpn', cpnC)
// ES6语法:定义字符串的 单引号、双引号 和 `` 的区别
const a = '12' +
'34';
const b = `we
qw`;
// 1.创建组件构造器对象
const cpnC = Vue.extend({
template: `
我是标题
我是内容, 哈哈哈哈
我是内容, 呵呵呵呵
})
// 2.注册组件
Vue.component('my-cpn', cpnC)
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
}
})
2. 02-全局组件和局部组件.html
下面的不显示,说明 局部组件 只能使用在挂载的地方
// 1.创建局部组件构造器
const cpna = Vue.extend({
template: `
我是标题a: 局部组件
我是内容a,哈哈哈哈啊
`
})
// 2. 全局组件
const cpnb = Vue.extend({
template: `
我是标题b: 全局组件
我是内容,哈哈哈哈啊
`
})
// 3.注册组件(全局组件, 意味着可以在多个Vue的实例下面使用)
Vue.component('cpnb', cpnb)
// 疑问: 怎么注册的组件才是局部组件了?
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
},
// 局部组件定义的位置
components: {
// cpnA 使用组件时的标签名
cpna: cpna
}
})
const app2 = new Vue({
el: '#app2'
})
3. 03-父组件和子组件.html
// 1.创建第一个组件构造器(子组件)
const cpnC1 = Vue.extend({
template: `
我是标题1: 子组件
我是内容, 哈哈哈哈
`
})
// 2.创建第二个组件构造器(父组件)
const cpnC2 = Vue.extend({
template: `
我是标题2: 父组件
我是内容, 呵呵呵呵
`,
components: {
cpn1: cpnC1
}
})
// root组件
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
},
components: {
cpn2: cpnC2
}
})
4. 04-组件(全局和局部)的语法糖注册方式.html
// 1.全局组件注册的语法糖
// 1.创建组件构造器
// const cpn1 = Vue.extend({
// template: `
//
//
我是标题1
//
我是内容, 哈哈哈哈
//
// `
// })
// 2.注册全局组件
Vue.component('cpn1', {
template: `
我是标题1: 全局组件
我是内容, 哈哈哈哈
`
})
// 2.注册局部组件的语法糖
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
},
components: {
'cpn2': {
template: `
我是标题2: 局部组件
我是内容, 呵呵呵
`
}
}
})
5. 05-组件模板的分离写法.html
我是标题: script标签 创建的模版-全局组件
我是内容,哈哈哈
我是标题: template标签 创建的模版-全局组件
我是内容,呵呵呵
// 2.注册一个全局组件
Vue.component('cpn1', {
template: '#cpn1'
})
Vue.component('cpn2', {
template: '#cpn2'
})
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
}
})
6. 06-组件中的数据存放问题.html
{
{title}}
我是全局组件 模版中的数据,呵呵呵
// 1.注册一个全局组件
Vue.component('cpn', {
template: '#cpn',
data() {
return {
title: 'abc'
}
}
})
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
// title: '我是标题'
}
})
7. 07-组件中的data为什么是函数.html
为什么data在组件中必须是一个函数呢?
首先,如果不是一个函数,Vue直接就会报错。
其次,原因是在于Vue让每个组件对象都返回一个新的对象,因为如果是同一个对象的,组件在多次使用后会相互影响。
全局组件-模版中-当前计数: {
{counter}}
// 1.注册组件
const obj = {
counter: 0
}
/*
* 为什么data在组件中必须是一个函数呢?
* 1. 首先,如果不是一个函数,Vue直接就会报错。
* 2. 其次,原因是在于Vue让每个组件对象都返回一个新的对象,因为如果是同一个对象的,组件在多次使用后会相互影响。
* */
Vue.component('cpn', {
template: '#cpn',
// data() {
// return {
// counter: 0
// }
// },
data() {
return obj
},
methods: {
increment() {
this.counter++
},
decrement() {
this.counter--
}
}
})
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
}
})
// const obj = {
// name: 'why',
// age: 18
// }
//
// function abc() {
// return obj
// }
//
// let obj1 = abc()
// let obj2 = abc()
// let obj3 = abc()
//
// obj1.name = 'kobe'
// console.log(obj2);
// console.log(obj3);
8. 08-组件通信-父组件向子组件传递数据.html
正确写法, 使用第一种 props写法: 使用 v-bind 进行传值
如果不加 v-bind, 下面这个会将 message、movies 作为 字符串传递给 cmessage、movies 属性
正确写法, 使用第二种 props写法, cmessage 没传值, 使用的是默认值
- {
{item}}
{
{cmessage}}
// 父传子: props: properties
const cpn = {
template: '#cpn',
// 第一种写法
// props: ['cmovies', 'cmessage'],
// 第二种写法
props: {
// 1.类型限制
// cmovies: Array,
// cmessage: String,
// 2.提供一些默认值, 以及必传值
cmessage: {
type: String,
default: 'aaaaaaaa',
required: true // 为true时,必须要传,不传则报错
},
// 类型是对象或者数组时, 默认值必须是一个函数
cmovies: {
type: Array,
default() {
return []
}
}
},
data() {
return {}
},
methods: {
}
}
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
movies: ['海王', '海贼王', '海尔兄弟']
},
components: {
cpn
}
})
9. 09-组件通信-父传子(props中的驼峰标识).html
{
{cInfo}}
{
{childMyMessage}}
const cpn = {
template: '#cpn',
props: {
cInfo: {
type: Object,
default() {
return {}
}
},
childMyMessage: {
type: String,
default: ''
}
}
}
const app = new Vue({
el: '#app',
data: {
info: {
name: 'why',
age: 18,
height: 1.88
},
message: 'aaaaaa'
},
components: {
cpn
}
})
10. 10-组件通信-子传父(自定义事件).html
/*
* 1.子组件
* */
const cpn = {
template: '#cpn',
data() {
return {
categories: [
{id: 'aaa', name: '热门推荐'},
{id: 'bbb', name: '手机数码'},
{id: 'ccc', name: '家用家电'},
{id: 'ddd', name: '电脑办公'},
]
}
},
methods: {
btnClick(item) {
console.log(item);
// 发射事件: 自定义事件, item:为参数, item-click:事件名称
this.$emit('item-click', item)
}
}
}
/*
* 2.父组件
* */
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
},
components: {
cpn
},
methods: {
cpnClick(item) {
console.log('cpnClick', item);
}
}
})
11. 11-组件通信-父子组件通信案例(props实现).html
12. 12-组件通信-父子组件通信案例(watch实现).html
:number2="num2" @num1change="num1change" @num2change="num2change"/>
props:{
{number1}}
data:{
{dnumber1}}
props:{
{number2}}
data:{
{dnumber2}}
const app = new Vue({
el: '#app',
data: {
num1: 1,
num2: 0
},
methods: {
num1change(value) {
this.num1 = parseFloat(value)
},
num2change(value) {
this.num2 = parseFloat(value)
}
},
components: {
cpn: {
template: '#cpn',
props: {
number1: Number,
number2: Number,
name: ''
},
data() {
return {
dnumber1: this.number1,
dnumber2: this.number2
}
},
watch: {
dnumber1(newValue) {
this.dnumber2 = newValue * 100;
this.$emit('num1change', newValue);
},
dnumber2(newValue) {
this.number1 = newValue / 100;
this.$emit('num2change', newValue);
}
}
}
}
})
13. 13-组件访问-父访问子-$children-$refs.html
我是一个演员
const app = new Vue({
el: '#app',
data: {},
methods: {
btnClink() {
// 父组件 访问 子组件
/*
* 1. $children
* */
console.log('this:', this)
console.log('this.$children:', this.$children)
console.log('-------------------')
this.$children[0].showMessage();
for (let c of this.$children) {
console.log('c.name: ', c.name)
c.showMessage()
}
this.$children[1].name; // 这样可以指定某个组件对象,但是不固定,所以这样不好
/*
* 2. $ref => 对象类型,默认是一个空的对象 ref='bbb
* */
console.log(this.$refs.aaa.name)
}
},
components: {
cpn: {
template: '#cpn',
props: {},
data() {
return {
name: '我是子组件的 name'
}
},
methods: {
showMessage() {
console.log('子组件方法-showMessage');
}
}
}
}
})
14. 14-组件访问-子访问父-$parent-$root.html
我是cpn组件
我是ccpn组件
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
},
components: {
cpn: {
template: '#cpn',
data(){
return {
name: '我是ccpn组件的 name'
}
},
methods: {
btnClink(){
console.log('btnClink');
}
},
components: {
ccpn: {
template: '#ccpn',
methods: {
btnClick(){
// 1. 访问父组件 $parent
console.log('this.$parent: ', this.$parent);
console.log('this.$parent.name: ', this.$parent.name);
console.log('------------------------');
// 2. 访问根组件$root
console.log('this: ', this);
console.log('this.$root: ', this.$root);
console.log('this.$root.message: ', this.$root.message);
}
}
}
}
}
}
})
三、03-组件化高级
1. 01-slot-插槽的基本使用.html
插槽的基本使用
插槽的默认值 button3.如果有多个值, 同时放入到组件进行替换时, 一起作为替换元素
我是传过来的:呵呵呵
p元素
我是组件
我是组件, 哈哈哈
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
},
components: {
cpn: {
template: '#cpn'
}
}
})
2. 02-slot-具名插槽的使用.html
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
},
components: {
cpn: {
template: '#cpn'
}
}
})
3. 03-什么是编译的作用域.html
我是子组件
我是内容, 哈哈哈
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
isShow: true
},
components: {
cpn: {
template: '#cpn',
data() {
return {
isShow: false,
names: [1, 2, 3, 4]
}
}
},
}
})
4. 04-作用域插槽的案例.html
{
{slot.data.join(' - ')}}
{
{slot.data.join(' * ')}}
- {
{item}}
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
},
components: {
cpn: {
template: '#cpn',
data() {
return {
pLanguages: ['JavaScript', 'C++', 'Java', 'C#', 'Python', 'Go', 'Swift']
}
}
}
}
})