今日内容概要
- 计算属性
- 监听属性
- 组件介绍和定义
- 父子通信之父传子
- 父子通信之子传父
- ref属性
- 动态组件
- 插槽
- vue-cli
今日内容详细
计算属性
我们可以通过计算属性computed
来缓存计算,什么意思呢?
在Vue中我们可以使用插值来展示数据,插值的普通函数,只要页面一刷新,函数就会重新运算,不管和函数有关没关的值都会变,函数也会重新计算,导致运行效率降低;
那么我们可以将自定义函数写在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="name">--->{{handleUpper()}}
<hr>
<input type="text" v-model="name2">--->{{upper}}
</div>
</body>
<script>
let vm = new Vue({
el: '#app',
data: {
name: '',
name2: ''
},
methods: {
handleUpper() {
// 只要页面刷新就会变化
console.log('我执行了')
return this.name.slice(0, 1).toUpperCase() + this.name.slice(1)
}
},
computed: {
upper() {
// 只有涉及到计算属性中使用的变量发生变化,它才重新运算
console.log('计算属性我执行了')
return this.name2.slice(0, 1).toUpperCase() + this.name2.slice(1)
}
}
})
</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">
<p><input type="text" v-model="search" placeholder="请输入要搜索的内容"></p>
<ul>
<li v-for="item in newdataList">{{item}}</li>
</ul>
</div>
</body>
<script>
let vm = new Vue({
el: '#app',
data: {
search: '',
dataList: [
'a',
'at',
'atom',
'be',
'beyond',
'cs',
'csrf',
'd',
'dddd',
],
},
computed: {
newdataList(){
// 计算属性一定要return,因为计算属性的值就是咱们return的值
return this.dataList.filter(item => item.indexOf(this.search) >= 0)
}
}
})
</script>
</html>
监听属性
watch
来设置监听属性,监听一个属性的变化,只要它发生变化,就执行一个函数
代码演示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
<span>
<button @click="type='人文'">人文</button> |
<button @click="type='社科'">社科</button> |
<button @click="type='地理'">地理</button>
</span>
<br>
{{type}}
</div>
</body>
<script>
let vm = new Vue({
el: '#app',
data: {
type:'人文',
},
watch:{
type(val){
console.log('修改后变成了,',val)
console.log('向后端加载数据了')
}
}
})
</script>
</html>
组件介绍和定义
介绍:扩展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">
<h1>全局组件</h1>
<child></child>
<hr>
<h1>局部组件</h1>
<wjl></wjl>
</div>
</body>
<script>
// 定义全局组件(必须在一个标签)组件有自己的数据,方法,生命周期
let obj = {
template: `
<div>
<button>后退</button>
{{title}}
<button @click="handleClick">前进</button>
</div>
`,
data() {
return {
title: '标题'
}
},
methods: {
handleClick() {
alert('前进')
}
}
}
Vue.component('child', obj)
// 局部组件
let wjl = {
template: `
<div>
<h2>我是wjl组件</h2>
{{ name }}
<child3></child3>
<child></child>
</div>
`,
data() {
return {
name: 'wjl'
}
},
components: {
'child3': {
template: `
<div>
<h2>我是wjl组件内的组件</h2>
</div>
`,
}
}
}
let vm = new Vue({
el: '#app',
data: {},
components: {
wjl
}
})
</script>
</html>
父子通信之父传子
组件间data数据不共享,数据传递,如果我们想从父组件传递到子组件数据通过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">
<h1>自定义属性实现父子通信</h1>
{{name}}
<wjl :myname="name"></wjl>
</div>
</body>
<script>
let wjl = {
template: `
<div>
<h1>我是wjl组件</h1>
{{ myname }}
</div>`,
// props: ['myname'], props也可以写成数组的形式,不带验证功能
props: {
myname: String,
},
created() {
console.log(typeof this.myname)
}
}
let vm = new Vue({
el: '#app',
data: {
name: '刘亦菲'
},
components: {
wjl
}
})
</script>
</html>
父子通信之子传父
ps:Vue内置的对象都以$xx出现
我们可以通过自定义事件来实现子组件向父组件传递数据,在子组件中使用$emit('自定义事件',参数)
来实现
代码演示:
<!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>
父组件中的name值为:{{name}}
<hr>
<wjl @myevnet="handleEvent"></wjl>
<hr>
</div>
</body>
<script>
let wjl = {
template: `
<div>
<h1>我是wjl组件</h1>
<input type="text" v-model="name"> --->{{ name }}
<br>
<button @click="handleSend">点我把name传给父组件</button>
</div>`,
data() {
return {
name: ''
}
},
methods: {
handleSend() {
// alert('我被点了')
// 在这里,触发自定义事件的执行
this.$emit('myevnet', this.name)
}
}
}
let vm = new Vue({
el: '#app',
data: {
name: '刘亦菲'
},
methods: {
handleEvent(name) {
this.name = name
}
},
components: {
wjl
}
})
</script>
</html>
ref属性
# ref属性,vue定义的
1. 放在普通标签上,通过 this.$refs.自定义的名字 取到的是原生的dom对象
使用原生dom操作了(不推荐)
2. 放在组件上,通过 this.$refs.自定义的名字 取到的是vc对象(组件对象)
可以直接使用组件对象上的方法和属性---> 子的数据给了父亲
父组件有个方法执行,需要传参数,传入子组件的数据---> 子的数据给了父亲
拿到子对象直接使用父中的数据修改---> 父的数据给了子
代码演示:
<!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>ref属性放在普通标签上</h1>
<input type="text" ref="myinput" v-model="name">--->{{name}}
<br>
<button @click="handlePrint">点我,打印点东西</button>
<hr>
<h1>ref属性放在组件上</h1>
<wjl ref="mywjl"></wjl>
</div>
</body>
<script>
let wjl = {
template: `
<div>
<button>后退</button>
首页---{{ age }}---{{ show }}
<button @click="handleQJ('迪丽热巴')">前进</button>
</div>`,
data(){
return {
show:true,
age:18,
}
},
methods:{
handleQJ(name){
alert(name)
}
}
}
let vm = new Vue({
el: '#app',
data: {
name: '刘亦菲'
},
methods: {
handlePrint() {
//this.$refs.myinput 原生dom对象
// this.$refs.myinput.value='xxxxxx'
console.log(this.$refs)
// this.$refs.mylqz.age=999
// this.$refs.mylqz.show = false
// this.$refs.mylqz.handleQJ()
// this.name=this.$refs.mylqz.age
this.$refs.mywjl.handleQJ(this.name)
}
},
components: {
wjl
}
})
</script>
</html>
动态组件
动态组件:实现点击不同的连接显示不同的页面,实现跳转,使用component
标签,用is
属性绑定,指定哪个显示哪个
keep-alive
:通过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">
<div>
<span @click="type='home'">首页</span> |
<span @click="type='goods'">商品</span> |
<span @click="type='order'">订单</span>
</div>
<div>
<keep-alive>
<component :is="type"></component>
</keep-alive>
</div>
</div>
</body>
<script>
// 定义三个全局组件
Vue.component('home', {
template: `
<div>
<h1>首页</h1>
</div>`,
})
Vue.component('goods', {
template: `
<div>
<h1>商品</h1>
<input type="text" placeholder="请输入要搜索的商品"> <button>搜索</button>
</div>`,
})
Vue.component('order', {
template: `
<div>
<h1>订单</h1>
</div>`,
})
let vm = new Vue({
el: '#app',
data: {
type: 'home'
},
})
</script>
</html>
插槽
插槽:组件使用slot标签,显示组件标签的内容
具名插槽:通过在标签内使用slot属性指定值,组件内使用solt标签通过name接收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">
<h1>插槽的使用</h1>
<home>
<div>我是div</div>
</home>
<hr>
<goods>
<div slot="bottom">我是底部</div>
<a href="" slot="top">点我看美女</a>
</goods>
</div>
</body>
<script>
Vue.component('home', {
template: `
<div>
<button>后退</button>
<span>首页</span>
<button>前进</button>
<hr>
<slot></slot>
</div>`,
})
Vue.component('goods', {
template: `
<div>
<slot name="top"></slot>
<hr>
<button>后退</button>
<span>首页</span>
<button>前进</button>
<hr>
<slot name="bottom"></slot>
</div>`,
})
let vm = new Vue({
el: '#app',
})
</script>
</html>