第一个vue小程序
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- 根容器 -->
<div id="app">
<h3 :title="message+'哈哈哈哈'">{
{message}}</h3>
<!-- 4、props没有接收的属性会自动赋给组件最外层标签
<h1 style="color: red;">我是一个组件哈哈哈哈</h1>-->
<name style="color:red" :msg="message"></name>
</div>
<!-- CDN引入 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
// 2、全局组件:参数一 组件名字 参数二对象
// 必须组件写在创建实例前边
Vue.component('name', {
template: `<h1>我是一个组件{
{item}}</h1>`, //模板
// 3、组件data不能使用对象,因为组件复用的时候公用一个data,一个修改会引起其他改变
data() {
return {
item: '哈哈哈哈'
}
},
props: {
msg: String
}
})
// 1、new 一个vue实例,参数为对象
let vm = new Vue({
el: '#app', //el指定容器
data: {
//根组件不会被复用,所以data可以为对象
message: 'Hello Word!'
}
})
</script>
</body>
</html>
指令
v-bind:name === :name
v-if v-else-if v-else v-show
v-for
v-on:click === @click
$attrs 用于向父组件向孙子组件传递值或者样式等
- 父组件给子组件传值,若子组件不用props接收,则会变为子组件根元素的属性
- 可使用this.$attrs获取到传递的所有数据集合
//父组件中调用子组件并传递属性
<custom-layout id="custom-layout" @click="changeValue"></custom-layout>
//子组件中调用孙子组件 <main>,并把$attrs传递给main孙子组件,避免了props一层一层向下传递
app.component('custom-layout', {
template: `
<header>...</header>
<main v-bind="$attrs">...</main>
<footer>...</footer>
`
})
插槽
自定义组件
@input:输入框变化就会执行
@change:输入框失焦的时候执行
1. 组件标签上使用 v-model
一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件,但是像单选框、复选框等类型v-model的值会覆盖其标签上的value值:解决方法:添加model选项
<body>
<!-- 根容器 -->
<div id="app">
//1、页面引入name组件,绑定v-model值为变量name,此时如果子组件为input等,则会覆盖其value的值
<name v-model="name"></name>
</div>
<script>
// 2、为了解决以上问题,子组件中需要定义model属性,分别是prop用来接收绑定的值,event用来改变父组件的值
Vue.component('name', {
template: `<input value="我是默认值" @input="change1" :title="name1"/>`, //模板
model: {
prop: 'name1',
event: 'change'
},
// 3、props中必须再传一下name1,否则子组件内部无法获取到name1的值;
props: {
name1: String
},
methods: {
// 4、子组件@input的时候给父组件传递数据
change1() {
this.$emit('change', 'aaaaaaa') //此时name就会变成aaaaaaaa
}
}
})
let vm = new Vue({
el: '#app', //el指定容器
data: {
name: '嘿嘿'
},
})
</script>
</body>
2.在组件上添加原生事件 .native
- 在组件上直接添加原生事件不会执行,添加 .native 修饰符即可执行change方法
- 在组件标签上直接添加属性或样式等,会默认添加给组件的根元素
<name @click.native="change"></name>
3. 子组件某个时机改变父组件的data,修饰符 .async
//子组件change事件里边,向父组件传递值this.son
change() {
this.$emit('update:foo', this.son)
}
// 1、父组件接收并赋值给data中的message
<age @update:foo="val => message = val"></age>
// 2、使用 .async 修饰符如下:
<age :foo.sync="message"></age>
混入Mixins
混入 (mixins): 是一种分发 Vue 组件中可复用功能的非常灵活的方式。混入对象可以包含任意组件选项。
项目中如何使用混入
- 在src目录下创建一个mixins文件夹,文件夹下新建一个myMixins.js文件;
- 定义混入对象
export default {
data(){
return {
msg: 'erwerwe',
form:{
a:'aaa'
}
}
},
filters: {
//过滤器
numToString(value) {
return value.toString();
}
},
created(){
//钩子函数
console.log('这是混入的组件')
},
computed: {
//计算属性
ids() {
return !this.loading
}
},
methods:{
exm(){
console.log('这是混入的exm方法')
},
clickFn(){
console.log(this.msg)
},
// 其它属性方法......
}
}
- 在组件中使用
<script>
//导入js文件
import fun from './mixins/common.js'
export default {
name: "HelloWorld",
mixins:[fun], //混入 fnu对象
created(){
console.log('这是当前组件')
},
data() {
return {
msg: "组件的msg"
}
},
methods:{
buttonClick(){
console.log(this.form.a)
console.log(this.msg)
this.clickFn();
this.exm();
},
exm(){
console.log('这是组件的exm方法')
}
}
}
</script>
全局混入
它将影响每一个之后创建的 Vue 实例
// 为自定义的选项 'myOption' 注入一个处理器。
Vue.mixin({
created: function () {
var myOption = this.$options.myOption
if (myOption) {
console.log(myOption)
}
}
})
new Vue({
myOption: 'hello!'
})
// => "hello!"
合并规则
- 混入中的msg属性,和组件的msg属性冲突,以组件的值优先。
- 同名钩子函数都会调用,混入函数先调用
- 值为对象的选项,如methods,components,directives等,将会合并为一个新对象,如果键名冲突,组件的值优先
与vuex的区别
- vuex:里面的变量在每个组件中均可以使用和修改,在任一组件中修改此变量,其他组件中此变量也会随之修改。
- Mixins:可以定义共用的变量,在每个组件中使用,引入组件中之后,各个变量是相互独立的,值的修改在组件中不会相互影响。
与公共组件的区别
- 组件:在父组件中引入组件,相当于在父组件中给出一片独立的空间供子组件使用,然后根据props来传值,但本质上两者是相对独立的。
- Mixins:则是在引入组件之后与组件中的对象和方法进行合并,相当于扩展了父组件的对象与方法,可以理解为形成了一个新的组件。
Vue.prototype.$eventBus = new Vue();
this.$eventBus.$emit("handler","我是传递的值")
this.$eventBus.$on("handle",(value)=>{
this.value = value;
})