摘要:还可以在某个实例中注册只有自己能使用的组件。当在一个组件中,使用了其他自定义组件时,就会利用子组件的属性和事件来和父组件进行数据交流。正确的做法是,在父组件中绑定属性值时,加上修饰符。
2019-06-20更新:
Vue2.6已经更新了关于内容插槽和作用域插槽的API和用法,为了不误导大家,我把插槽的内容删除了。详情请看官网
2018-07-19更新:
更新作用域插槽的属性: scope -> slot-scope;
添加了对象解构。
今天看了下Vue官网上关于组件的教程,感觉内容还挺多,现在把组件中基本的知识梳理一下。
组件的基本使用 注册组件注册组件就是利用Vue.component()方法,先传入一个自定义组件的名字,然后传入这个组件的配置。
Vue.component("mycomponent",{ template: `这是一个自定义组件`, data () { return { message: "hello world" } } })
如上方式,就已经创建了一个自定义组件,然后就可以在Vue实例挂在的DOM元素中使用它。
直接使用Vue.component()创建的组件,所有的Vue实例都可以使用。还可以在某个Vue实例中注册只有自己能使用的组件。
var app = new Vue({ el: "#app", data: { }, components: { "my-component": { template: `模板的要求这是一个局部的自定义组件,只能在当前Vue实例中使用`, } } })
注意:组件的模板只能有一个根元素。下面的情况是不允许的。
template: `组件中的data必须是函数这是一个局部的自定义组件,只能在当前Vue实例中使用`,
可以看出,注册组件时传入的配置和创建Vue实例差不多,但也有不同,其中一个就是data属性必须是一个函数。
这是因为如果像Vue实例那样,传入一个对象,由于JS中对象类型的变量实际上保存的是对象的引用,所以当存在多个这样的组件时,会共享数据,导致一个组件中数据的改变会引起其他组件数据的改变。
而使用一个返回对象的函数,每次使用组件都会创建一个新的对象,这样就不会出现共享数据的问题来了。
关于DOM模板的解析当使用 DOM 作为模版时 (例如,将 el 选项挂载到一个已存在的元素上), 你会受到 HTML 的一些限制,因为 Vue 只有在浏览器解析和标准化 HTML 后才能获取模板内容。尤其像这些元素 在自定义组件中使用这些受限制的元素时会导致一些问题,例如: 自定义组件 也就是说,标准HTML中,一些元素中只能放置特定的子元素,另一些元素只能存在于特定的父元素中。比如table中不能放置div,tr的父元素不能div等。所以,当使用自定义标签时,标签名还是那些标签的名字,但是可以在标签的is属性中填写自定义组件的名字。 应当注意,如果您使用来自以下来源之一的字符串模板,这些限制将不适用:
JavaScript 内联模版字符串
.vue 组件 其中,前两个模板都不是Vue官方推荐的,所以一般情况下,只有单文件组件.vue可以忽略这种情况。 在html中使用元素,会有一些属性,如class,id,还可以绑定事件,自定义组件也是可以的。当在一个组件中,使用了其他自定义组件时,就会利用子组件的属性和事件来和父组件进行数据交流。 如上如所示,父子组件之间的通信就是 props down,events up,父组件通过 属性props向下传递数据给子组件,子组件通过 事件events 给父组件发送消息。 如上代码,
foo是
event-a是子组件定义的一个事件,doThis是父组件的一个方法 过程就是这样: 父组件把baz数据通过prop传递给子组件的foo; 子组件内部得到foo的值,就可以进行相应的操作; 当子组件内部发生了一些变化,希望父组件能知道时,就利用代码触发event-a事件,把一些数据发送出去 父组件把这个事件处理器绑定为doThis方法,子组件发送的数据,就作为doThis方法的参数被传进来 然后父组件就可以根据这些数据,进行相应的操作 Vue组件通过props属性来声明一个自己的属性,然后父组件就可以往里面传递数据。 然后调用该组件 注意,由于HTML特性是不区分大小写的,所以传递属性值时,myMessage应该转换成 kebab-case (短横线隔开式)my-message="hello"。 这里说一下v-bind绑定属性值的一个特性:一般情况下,使用v-bind给元素特性(attribute)传递值时,Vue会将""中的内容当做一个表达式。 上面这样,div元素的attr特性值就是message。 而这样 这里的message应该是Vue实例的data的一个属性,这样div元素的attr特性值就是message这个属性的值。 之所以说是一般情况,是因为class和style特性并不是这样。用v-bind:class和class传入正常的类名,效果是一样的,因为对于这两个特性,Vue采用了合并而不是替换的原则。 根据上面,想要把父组件的属性绑定到子组件,应该使用v-bind,这样,父组件中数据改变时能反映到子组件。
当父组件传递的属性是引用类型时,在子组件中更改相应的属性会导致父组件相应属性的更改。
当父组件传递值为基本类型时,在子组件中更改这个属性会报错。正确的做法是,在父组件中绑定属性值时,加上.sync修饰符。 然后在子组件中改变相应的属性 一般来说,是不建议在子组件中对父组件中传递来的属性进行操作的。如果真的有这种需求,可以这样:
父组件传递了一个基本类型值,那么可以在子组件中创建一个新的属性,并以传递进来的值进行初始化,之后就可以操作这个新的属性了 父组件传递了一个引用类型值,为了避免更改父组件中相应的数据,最好是对引用类型进行复制。复杂的情况,肯定应该是深复制。 同样是上面的原因,静态的给子组件的特性传递值,它都会把他当做一个字符串。 子组件中,特性的值是字符串 "1" 而不是 number 1。如果想传递正确的数值,应该使用v-bind传递,这样就能把传递的值当做一个表达式来处理,而不是字符串。 我们可以给组件的props属性添加验证,当传入的数据不符合要求时,Vue会发出警告。 type 可以是下面原生构造器: String Number Boolean Function Object Array Symbol type 也可以是一个自定义构造器函数,使用 instanceof 检测。 也可以像在html标签中添加data-开头的自定义属性一样,给自定义组件添加任意的属性。而不仅限于data-*形式,这样做的话,Vue会把这个属性放在自定义组件的根元素上。一个自定义组件的模板只能有一个根元素。 如果父组件向子组件的非prop属性传递了值,那么这个值会覆盖子组件模板中的特性。 上面渲染的结果是,div的att属性是helloParent。 上面的渲染结果是,div的类名是class1 class2,行内样式是color:red; background:yellow;。 通过prop属性,父组件可以向子组件传递数据,而子组件的自定义事件就是用来将内部的数据报告给父组件的。 如上所示,共分为以下步骤:
子组件在自己的方法中将自定义事件以及需要发出的数据通过以下代码发送出去 第一个参数是自定义事件的名字 后面的参数是依次想要发送出去的数据
父组件利用v-on为事件绑定处理器 这样,在Vue实例的methods方法中就可以调用传进来的参数了 注意: 在使用v-on绑定事件处理方法时,不应该传进任何参数,而是直接写v-on:myclick="onClick",不然,子组件暴露出来的数据就无法获取到了 如果想在某个组件的根元素上监听一个原生事件。可以使用 .native 修饰 v-on v-model可以对表单控件实现数据的双向绑定,它的原理就是利用了绑定属性和事件来实现的。比如input控件。不使用v-model,可以这样实现数据的双向绑定: 上面的代码同样实现了数据的双向绑定。其本质就是: 把input的value特性绑定到Vue实例的属性text上,text改变,input中的内容也会改变 然后把表单的input事件处理函数设置为Vue实例的一个方法,这个方法会根据输入参数改变Vue中text`的值 相应的,在input中输入内容时,触发了input事件,把event.target.value传给这个方法,最后就实现了改变绑定的数据的效果。 而v-model就是上面这种方式的语法糖,也就是把上面的写法封装了一下,方便我们使用。 理解了v-model的内幕,也就可以把这个效果用在自定义表单组件上了。 默认情况下,一个组件的 v-model 会使用 value 属性和 input 事件,但是诸如单选框、复选框之类的输入类型可能把 value 属性用作了别的目的。model 选项可以回避这样的冲突: 这样设置的话, 上面的代码就等同于 实际使用时,与之前不同的地方是: 把子组件中接收外部数据的prop属性改为checked
向父组件发出事件时,事件类型应改为change
通过使用保留的 也可以直接绑定到组件对象上: 如果把切换出去的组件保留在内存中,可以保留它的状态或避免重新渲染。为此可以添加一个 keep-alive 指令参数: 文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。 转载请注明本文地址:https://www.ucloud.cn/yun/84697.html 摘要:有兴趣的同学可以查看之前发布的文章学习系列一学习实践笔记附学习系列二学习实践笔记附学习系列三和网络传输相关知识的学习实践学习系列四打包工具的使用学习系列五从来聊聊学习系列项目地址项目暂时有点乱,之后会进行整理优化。
上次学习了vue-router的使用,让我能够在各个页面间切换,将页面搭建了起来。这次则要学习vue的状态管理模式——vuex。它类似于redux来应用的全局状态。
注:本... 摘要:执行的时候,会绑定上下文对象为组件实例于是中的就能取到组件实例本身,的代码块顶层作用域就绑定为了组件实例于是内部变量的访问,就会首先访问到组件实例上。其中的获取,就会先从组件实例上获取,相当于。
写文章不容易,点个赞呗兄弟专注 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧研究基于 Vue版本 【2.5.17】
如果你觉得... 摘要:好好打基础,然后多尝试不同风格的框架,因为只有尝试过后才能理解比如徐飞提到的各种权衡,也只有尝试过后才能知道哪个能真正提升自己的开发效率。
今天看了几篇关于这三个主流框架的PK,如标题:react.js,angular.js,vue.js学习哪个好?相信每个人都有这种问题。
现在的前端框架层出不穷,作为前端开发者何去何从?fackbook的react.js盛世火热,react nati... 摘要:保证上线后的版本不会因浏览器缓存而产生影响。前端部分之后会有多人合作,为了提高效率决定采用组件化开发。对之后的维护工作造成了一点困扰。之后的日子里做到一周更新两篇博文,主要是实际项目中遇到的具体问题来加以总结和分析,未完待续。
原文链接: http://xdlrt.github.io/2016/1...距离上次更博已经过去两个月了,终于也有时间能静下心来想一些事情,也对这几个月的生活做... 阅读 1400·2021-09-22 16:04 阅读 2777·2019-08-30 15:44 阅读 860·2019-08-30 15:43 阅读 753·2019-08-29 15:24 阅读 1801·2019-08-29 14:07 阅读 1118·2019-08-29 12:30 阅读 1711·2019-08-29 11:15 阅读 2729·2019-08-28 18:08,
,
, 限制了能被它包裹的元素,而一些像 这样的元素只能出现在某些其它元素内部。
比如,子组件需要某个数据,就在内部定义一个prop属性,然后父组件就像给html元素指定特性值一样,把自己的data属性传递给子组件的这个属性。
而当子组件内部发生了什么事情的时候,就通过自定义事件来把这个事情涉及到的数据暴露出来,供父组件处理。Vue.component("mycomponent",{
template: "
比如:
注意,根据父组件传递给子组件的属性类型的不同,当在子组件中更改这个属性时,会有以下两种情况:
methods: {
changeArray () {
this.counter++
this.$emit("update:childArray", this.counter)
}
}
子组件希望对传入的prop进行操作
props: ["initialCounter"],
data: function () {
return { counter: this.initialCounter }
}
Prop验证
Vue.component("example", {
props: {
// 基础类型检测 (`null` 意思是任何类型都可以)
propA: Number,
// 多种类型
propB: [String, Number],
// 必传且是字符串
propC: {
type: String,
required: true
},
// 数字,有默认值
propD: {
type: Number,
default: 100
},
// 数组/对象的默认值应当由一个工厂函数返回
propE: {
type: Object,
default: function () {
return { message: "hello" }
}
},
// 自定义验证函数
propF: {
validator: function (value) {
return value > 10
}
}
}
})
// 自定义Person构造器
function Person(name, age) {
this.name = name
this.age = age
}
Vue.component("my-component", {
template: `
非Prop类型的属性
注意:前面已经提到过,覆盖原则对于class和style不适用,而是采用了合并(merge)的原则。 this.$emit("myclick", "这是我暴露出去的数据", "这是我暴露出去的数据2")
探究v-model
来实现一个简单的只能输入hello的表单输入组件。
定制组件的v-model
Vue.component("my-checkbox", {
model: {
prop: "checked", // 将输入的特性改为checked
event: "change" // 触发的自定义事件类型为change
},
props: {
checked: Boolean,
// this allows using the `value` prop for a different purpose
value: String
}
})
Vue.component("my-component3", {
template: ``,
props: ["checked"], // 属性名改变
model: {
prop: "checked",
event: "change"
},
methods: {
checkInput (value) {
var hello = "hello"
if (!hello.includes(value)) {
this.$emit("change", hello) // 事件类型改变
this.$refs.input.value = hello
} else {
this.$emit("change", value) // 事件类型改变
}
}
}
})
动态组件
var Home = {
template: `
保留切换出去的组件,避免重新渲染
相关文章
Vue.js学习系列二 —— vuex学习实践笔记(附DEMO)
【Vue原理】VModel - 白话版
react.js,angular.js,vue.js学习哪个好?
反思总结然后整装待发
发表评论
0条评论
mdluo
男|高级讲师
TA的文章
阅读更多
虚拟主机月流量是什么意思-虚拟主机月流量是指什么?
前端20个真正灵魂拷问,吃透这些你就是中级前端工程师 【上篇】
行业log | 小程序搭载智慧零售,实现五位一体数字化营销
网络篇—浏览器缓存(一)
关于 jqeury easyui
css字体相关样式的处理
使用 @font-face
flexbox:更加优雅的Web布局