vue---计算属性和监听属性,组件化开发之局部和全局组件和组件通信,ref属性,数据总线,动态组件和slot插槽
作者:互联网
计算属性和监听属性
计算属性
computed 对象写函数,函数就可以当属性使用。
计算属性只有在它的相关依赖发生改变时才会重新求值。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
<input type="text" v-model="myText" > {{myText.substr(0,1).toUpperCase()+myText.substr(1)}}
<br>
<input type="text" v-model="myText2" > {{getname()}} // 函数
<br>
<input type="text" v-model="myText3"> {{getName}} // 计算属性
</div>
</body>
<script>
var vm=new Vue({
el:'#app',
data:{
myText:'',
myText2:'',
myText3:'',
},
methods:{
getname(){
return this.myText2.substr(0,1).toUpperCase()+this.myText2.substr(1)
}
},
computed:{
getName() {
return this.myText3.substr(0,1).toUpperCase()+this.myText3.substr(1)
// 返回什么,属性就得到什么
}
}
})
</script>
</html>
监听属性
watch对象中写函数,函数名就是data中得变量名,只要这个变量发生变化,就会触发该函数的执行。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<input type="text" v-model="myText"> --->{{myText}}
<hr>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
myText: '',
},
watch:{
myText(val){
console.log('执行了',val)
}
}
})
</script>
</html>
组件化开发之局部和全局组件
组件是什么?有什么用
扩展 HTML 元素,封装可重用的代码,目的是复用。例如:有一个轮播,可以在很多页面中使用,一个轮播有js,css,html。组件把js,css,html放到一起,有逻辑,有样式,有html。
定义全局组件
Vue.component('Child', {
template: `
<div>
<button @click="handleClick" v-model="myText">点我看美女</button>
</div>`,
data() {
return {
myText: ''
}
},
methods: {
handleClick() {
alert('美女')
}
}
})
定义局部组件
写在Vue实例或者组件实例中。
components:{
zaoan:{
template:`<div>
<h1>我是局部组件</h1>
<button @click="handleClick" >点我看美女</button>
</div>`,
methods: {
handleClick(){
alert("我是局部组件 看美女!")
}
},
}
}
注意
-1. 自定义组件需要有一个root element,一般包裹在一个div中
-2. 父子组件的data,methods是无法共享
-3. 组件可以有data,methods,computed....,但是data 必须是一个函数
组件间通信之父传子---自定义属性
第一步:在子组件上定义一个属性例如:myname=""
第二步:给属性添加一个变量,把变量存放在父组件data里,:myname="name"
第三步:在组件加上props:['添加的属性名',],然后就可以在子组件里调用属性了。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.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="handleClick">点我看美女</button>
<br>
<input type="text" v-model="myText">
</div>`,
data() {
return {
myText: '',
}
},
methods: {
handleClick() {
alert('美女')
}
},
props:['myname',]
})
// 局部组件只能在局部使用
var vm = new Vue({
el: '#app',
data: {
name:'lqz'
},
})
</script>
</html>
属性验证:
可以验证自定义的属性传入值的类型,如果类型对不上虽然还会显示,但报错了。
props: {
'myname': String,
myage: Number
}
组件间通信之子传父(自定义事件)
第一步:在子组件里自定义一个事件,绑定一个函数,函数是写在父组件的methods里。eg:@myevent="handleEvent"
第二步:在子组件内部创建一个可以触发通信事件的函数,在函数体里写上触发自定义事件的方法,携带上要传递的信息。eg: this.$emit('myevent', this.myText)
第三步:把要传递的信息当参数传给父组件里的自定义事件对应的函数,然后执行需要的操作即可。eg:handleEvent(myText) { this.name=myText}。
<!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>子组件中myText的数据是:{{name}}</h1>
<hr>
<Child @myevent="handleEvent"></Child>
</div>
</body>
<script>
//全局组件
Vue.component('Child', {
template: `
<div>
<input type="text" v-model="myText">
<button @click="handleClick">点我把数据传给父亲</button>
<br>
</div>`,
data() {
return {
myText: '',
}
},
methods: {
handleClick() {
// 触发自定义事件myevent,后面有几个参数,就传几个参数,这样就会执行myevent绑定的函数,handleEvent
this.$emit('myevent', this.myText)
}
},
})
// 局部组件只能在局部使用
var vm = new Vue({
el: '#app',
data: {
name:''
},
methods: {
handleEvent(myText) {
this.name=myText
}
}
})
</script>
</html>
ref属性
ref放在普通标签上,拿到的是原生节点,原生dom操作
ref放在组件上,拿到的是组件对象
-通过这种方式实现子传父(this.$refs.mychild.text)
-通过这种方式实现父传子(调用子组件方法传参数)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<!-- <input type="text" ref="pp">-->
<p ref="pp">我是个p</p>
<button @click="handleClick">点我执行函数</button>
<hr>
<Child ref="cc"></Child>
</div>
</body>
<script>
Vue.component('Child',{
template:`<div>
<h1>我是组件</h1>
名字:{{name}}
<br>
年龄:{{age}}
</div>`,
data(){
return {
name:'彭于晏',
age:37
}
},
methods:{
handleClick(aaa){
console.log(this.name,this.age)
}
}
})
var vm = new Vue({
el: '#app',
data: {
},
methods:{
handleClick(){
console.log(this.$refs)
// this.$refs['pp'].value='lqz is handsome'
// this.$refs['pp'].innerText='xxxx'
// alert(this.$refs['cc'].name)
// alert(this.$refs['cc'].age)
//调用子组件的方法
this.$refs['cc'].handleClick('asdfasdfasdfasdf')
}
}
})
</script>
</html>
数据总线
可以实现不同层级的不通的组件通信
用法:
// 1 定义一个数据总线----》本质就是一个vue对象
var bus = new Vue() //new一个vue的实例,就是中央事件总线
// 2 定义两个全局组件
// 其中之1
handleClick() {
// 触发被监听的事件,有值传值
bus.$emit('suibian',this.myText)
}
// 另一个
mounted(){
// 等着,监听,如果谁触发我,我就执行
bus.$on('suibian',(name)=>{
this.myText=name
})
}
案例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<child1></child1>
<hr>
<child2></child2>
</div>
</body>
<script>
// 1 定义一个数据总线----》本质就是一个vue对象
var bus = new Vue() //new一个vue的实例,就是中央事件总线
// 2 定义两个全局组件
Vue.component('child1', {
template: `
<div>
<input type="text" v-model="myText">
<button @click="handleClick">点我</button>
</div>`,
data() {
return {
myText: ''
}
},
methods: {
handleClick() {
// 触发被监听的事件,有值传值
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: {},
})
</script>
</html>
动态组件
通过component配合is属性,决定显示的组件是哪个
keep-alive 保证组件切换走后不被销毁
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.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>
slot插槽
可以通过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>
// 如果只是插单个伪装可以不用指定name
<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>
标签:slot,Vue,name,myText,组件,data,属性 来源: https://www.cnblogs.com/zaoan1207/p/16424822.html