计算属性和监听属性,组件化开发之局部和全局组件,组件间通信之父传子(自定义属性),组件间通信之子传父(自定义事件),ref属性,数据总线,动态组件,slot插槽
1 计算属性和监听属性
1.1 计算属性
1 computed 对象写函数,函数就可以当属性使用
2 计算属性只有在它的相关依赖发生改变时才会重新求值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.0.0/jquery.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.js"></script>
<script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
</head>
<body>
<div id="app">
<input type="text" v-model="myText"> ---->{{myText.substr(0, 1).toUpperCase() + myText.substr(1)}}
<br><br>
<input type="text" v-model="myText1"> ---->{{getText()}}
<br><br>
<input type="text" v-model="myText2"> ---->{{getName()}}
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
myText: '',
myText1: '',
myText2: '',
},
methods: {
getText() {
return this.myText1.substr(0, 1).toUpperCase() + this.myText1.substr(1)
},
},
computed: { //计算属性
getName() {
return this.myText2.substr(0, 1).toUpperCase() + this.myText2.substr(1)
},
},
})
</script>
</html>
重写过滤案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.0.0/jquery.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.js"></script>
<script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
</head>
<body>
<div id="app">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<h1>过滤案例</h1>
<input type="text" v-model="myText">
<hr>
<p v-for="item in newlist">{{item}}</p>
</div>
</div>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
myText: '',
dataList: ['a', 'at', 'atom', 'be', 'beyond', 'cs', 'csrf'],
},
computed: {
newlist() {
return this.dataList.filter(item => {
return item.indexOf(this.myText) >= 0
})
},
},
})
</script>
</html>
1.2 监听属性
1 watch对象中写函数---》函数名就是data中得变量名,只要这个变量发生变化,就会触发该函数的执行
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.0.0/jquery.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.js"></script>
<script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
</head>
<body>
<div id="app">
<input type="text" v-model="myText" placeholder="......">
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
myText: '',
},
watch: {
myText(val) {
alert(val)
},
},
})
</script>
</html>
2 组件化开发之局部和全局组件
# 组件是什么?有什么用
扩展 HTML 元素,封装可重用的代码,目的是复用
-例如:有一个轮播,可以在很多页面中使用,一个轮播有js,css,html
-组件把js,css,html放到一起,有逻辑,有样式,有html
# 定义全局组件
Vue.component('Child', {
template: ``
<div>
<h1>我是一个组件--{{ myText }}</h1>
<button @click="handleClick">点我看美女</button>
<br>
<input type="text" v-model="myText">
<Jason></Jason>
</div>`,
data() {
return {
myText: '',
}
},
methods: {
handleClick() {
alert('美女')
}
},
components: {
Jason: {
template: `
<div>
<h1>我是局部组件--jason</h1>
</div>`,
}
}
})
# 局部组件,写在Vue实力或者组件实例中
components: {
Lqz: {
template: `
<div>
<h1>我是局部组件</h1>
</div>`,
}
}
########################################################################################
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.0.0/jquery.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.js"></script>
<script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
</head>
<body>
<div id="app">
<Child>
</Child>
</div>
</body>
<script>
// 定义全局组件
Vue.component('Child', {
template: `
<div>
<h1>我是一个全局组件{{ myText }}</h1>
<button @click="click1">点完看牛马</button>
<br>
<input type="text" v-model="myText">
<child1></child1>
</div>
`,
data() {
return {
myText: '',
}
},
methods: {
click1() {
alert('🐂🐎')
},
},
components: {
child1: {
template: `
<div>
<h1>我是一个局部组件{{ myText }}</h1>
<input type="tel" v-model="myText">
</div>
`,
data() {
return {
myText: '',
};
},
}
}
})
var vm = new Vue({
el: '#app',
data: {},
methods: {},
computed: {},
})
</script>
</html>
注意
# 1 自定义组件需要有一个root element,一般包裹在一个div中
# 2 父子组件的data,methods是无法共享
# 3 组件可以有data,methods,computed....,但是data 必须是一个函数
3 组件间通信之父传子(自定义属性)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.0.0/jquery.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.js"></script>
<script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
</head>
<body>
<div id="app">
自定义属性: myname
<Child :myname="name"></Child>
</div>
</body>
<script>
// 全局组件
Vue.component('Child', {
template: `
<div>
<h1>我是一个组件--{{ myText }} 父组件传过来的{{ myname }}</h1>
<button @click="click1">点击看牛马</button>
<br>
<input type="text" v-model="myText">
</div>
`,
data() {
return {
myText: '',
};
},
methods: {
click1() {
alert('🐂🐎')
},
},
props: ['myname',]
})
var vm = new Vue({
el: '#app',
data: {
name: 'lcx'
},
methods: {},
})
</script>
</html>
3.1 属性验证
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<h1>父组件中输入值</h1>
名字:<input type="text" v-model="name">
<br>
年龄:<input type="text" v-model.number="age">
<h1>子组件中显示</h1>
<hr>
<Child :myname="name" :myage="age"></Child>
</div>
</body>
<script>
//全局组件
Vue.component('Child', {
template: `
<div>
名字是:{{ myname }}
<br>
年龄是:{{ myage }}
</div>`,
// props:['myname',]
props: {
'myname': String,
myage: Number
}
})
// 局部组件只能在局部使用
var vm = new Vue({
el: '#app',
data: {
name: 'lqz',
age:19
},
})
</script>
</html>
4 组件间通信之子传父(自定义事件)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
{% load static %}
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.0.0/jquery.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.js"></script>
<script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
</head>
<body>
<div id="app">
<h1>子组件中的myText的数据是:{{name}}</h1>
<hr>
<Child @myevent="click2"></Child>
</div>
</body>
<script>
// 全局组件
Vue.component('Child', {
template: `
<div>
<input type="text" v-model="myText">
<button @click="click1">点击向父组件传参数</button>
</div>
`,
data() {
return {
myText: '',
}
},
methods: {
click1() {
this.$emit('myevent', this.myText)
},
},
})
var vm = new Vue({
el: '#app',
data: {
name: ''
},
methods: {
click2(val) {
this.name = val
}
},
})
</script>
</html>
5 ref属性
# ref 属性是什么
ref放在普通标签上,拿到的是原生节点,原生dom操作
ref放在组件上,拿到的是组件对象,
通过这种方式实现子传父(this.$refs.mychild.text)
通过这种方式实现父传子(调用子组件方法传参数)
<p ref='pp'></p>
<Child ref='cc'></Child>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.0.0/jquery.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.js"></script>
<script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
</head>
<body>
<div id="app">
<h1>我是父组件</h1>
<p ref="pp">我是个p标签</p>
<button @click="click1">点我或去子组件data</button>
<p>名字:{{name}},年龄:{{age}}</p>
<hr>
<input type="text" v-model="myText">
<button @click="click2">点击向子组件传值</button>
<hr>
<Child ref="child"></Child>
</div>
</body>
<script>
Vue.component('Child', {
template: `
<div>
<h1>我是子组件</h1>
名字为:{{ name }}
年龄为:{{ age }}
</div>
`,
data() {
return {
name: '张三',
age: 20,
};
},
methods: {
setvalue(val) {
this.name = val
}
},
})
var vm = new Vue({
el: '#app',
data: {
name: '',
age: '',
myText: '',
},
methods: {
click1() {
console.log(this.$refs)
this.name = this.$refs['child'].name
this.age = this.$refs['child'].age
},
click2() {
this.$refs['child'].setvalue(this.myText)
}
},
})
</script>
</html>
6 数据总线
# 不同层级的不通组件通信
-数据总线
-vuex--->状态管理器---》
-cookie,localStorage,sessionStorage
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.0.0/jquery.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.js"></script>
<script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
</head>
<body>
<div id="app">
<child1></child1>
<hr>
<child2></child2>
</div>
</body>
<script>
var bus = new Vue()
Vue.component('child1', {
template: `
<div>
<input type="text" v-model="myText">
<button @click="click1">点我</button>
</div>`,
data() {
return {
myText: '',
};
},
methods: {
click1() {
bus.$emit('suibian', this.myText)
}
},
})
Vue.component('child2', {
template: `
<div>
接受到的数据是:{{ myText }}
</div>`,
data() {
return {
myText: '',
};
},
mounted() {
bus.$on('suibian', (name) => {
this.myText = name
})
},
})
var vm = new Vue({
el: '#app',
data: {},
methods: {},
})
</script>
</html>
7 动态组件
# 通过component配合is属性,决定显示的组件是哪个
# keep-alive 保证组件切换走后不被销毁
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.0.0/jquery.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.js"></script>
<script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
</head>
<body>
<div id="app">
<ul>
<li @click="who='home'">首页</li>
<li @click="who='goods'">商品</li>
<li @click="who='order'">订单</li>
</ul>
<keep-alive>
<component :is="who">
</component>
</keep-alive>
</div>
</body>
<script>
Vue.component('home', {
template: `
<div>
首页
</div>`,
})
Vue.component('goods', {
template: `
<div>
商品
<input type="text">
</div>`,
})
Vue.component('order', {
template: `
<div>
订单
</div>`,
})
var vm = new Vue({
el: '#app',
data: {
who: 'home'
},
})
</script>
</html>
8 slot插槽
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<home>
<div><button>美女</button></div>
</home>
</div>
</body>
<script>
Vue.component('home', {
template: `
<div>
<input type="text">
<hr>
<slot></slot>
<button>点我</button>
</div>`,
})
var vm = new Vue({
el: '#app',
data: {
},
})
</script>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<home>
<div slot="a">我是div</div>
<img src="https://tva1.sinaimg.cn/large/00831rSTly1gd1u0jw182j30u00u043b.jpg" alt="" slot="b">
</home>
</div>
</body>
<script>
Vue.component('home', {
template: `
<div>
<input type="text">
<hr>
<slot name="a"></slot>
navbar
<slot name="b"></slot>
<button>点我</button>
</div>`,
})
var vm = new Vue({
el: '#app',
data: {
},
})
</script>
</html>
本文作者:春游去动物园
本文链接:https://www.cnblogs.com/chunyouqudongwuyuan/p/16424332.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步