目录
props
属性,父组件向子组件传递数据props
属性- const cpn = {
- template: "#cpn",
- props: {
- cmessage: {
- type: String,
- default: 'zzzzz',
- required: true //在使用组件必传值
- }
- }
- }
- "app">
- <cpn :cMessage="message">cpn>
- <script>
- const app = new Vue({
- el: "#app",
- data: {
- message: "你好",
- movies: ["复仇者联盟", "钢铁侠", "星际穿越", "哪吒传奇"]
- },
- components: {
- cpn
- }
- })
- script>
props: ['cmovies', 'cmessage']
- props: {
- cmessage: {
- type: String,
- default: 'zzzzz',
- required: true //在使用组件必传值
- }
- }
- //1.类型限制(多个类使用数组)
- cmovies:Array,//限制为数组类型
- cmessage:String,//限制为Strin类型
- cmessage:['String','Number']//限制为String或Number类型
- // 2.提供一些默认值,以及必传值
- cmessage: {
- type: String,
- default: 'zzzzz',//默认值
- }
- cmessage: {
- type: String,
- default: 'zzzzz',
- required: true //在使用组件必传值
- }
- //类型是Object/Array,默认值必须是一个函数
- cmovies: {
- type: Array,
- default () {
- return [1, 2, 3, 4]
- }
- },
- vaildator: function (value) {
- //这个传递的值必须匹配下列字符串中的一个
- return ['zzzzz', 'ttttt', 'yyy'].indexOf(value) !== -1
- }
- function Person(firstName,lastName) {
- this.firstName = firstName
- this.lastName = lastName
- }
- cmessage:Person//限定了cmeessage必须是Person类型
- DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8">
- <title>title>
-
- head>
- <body>
- <div id="app">
-
-
- <cpn1 :msgab="add">cpn1>
- <h2>{{count}}h2>
- div>
- <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js">script>
- <script>
- const app = new Vue({
- el: "#app",
- data: {
- /* message: ['蔡英文', '吴钊燮'] */
- /* message2:{
- name:'蔡英文',
- age:56,
- sex:'女'
- } */
- count:0
- },
- methods: {
- add:function(){
- return this.count++
- }
- },
- computed: {
-
- },
- components: {
- cpn1: {
- /* template: `
- 我是中国人{{msg.name}}{{msg.sex}}
- `, */
- template: `
-
- +
-
-
- `,
- props: {
- /* msg:{
- type: Array
- } */
- /* msg:{
- type: Object
- } */
- msgab:{
- type:Function
- },
-
- },
- methods:{
- sum(){
- this.msgab()
- }
- }
-
-
- }
- }
- })
- script>
- body>
- html>
子组件向父组件传值,使用自定义事件$emit
。
-
- <div id="app">
-
- <cpn @itemclick="cpnClcik">cpn>
-
- div>
-
-
- <template id="cpn">
-
- <div>
- <button v-for="(item, index) in categoties" :key="index" @click="btnClick(item)">{{item.name}}button>
- div>
- template>
-
- <script src="../js/vue.js">script>
-
- <script>
- const cpn = {
- template: "#cpn",
- data() {
- return {
- categoties: [{
- id: 'aaa',
- name: '热门推荐'
- },
- {
- id: 'bbb',
- name: '手机数码'
- },
- {
- id: 'ccc',
- name: '家用家电'
- },
- {
- id: 'ddd',
- name: '电脑办公'
- },
- ]
- }
- },
- methods: {
- btnClick(item) {
- this.$emit('itemclick', item)
- }
- },
- };
- const app = new Vue({
- el: "#app",
- data() {
- return {
-
- }
- },
- methods: {
- cpnClcik(item) {
- console.log('cpnClick'+item.name);
- }
- },
- components: {
- cpn
- },
- })
- script>
1.在子组件中定义一个方法btnClick(item)
,使用$emit
,'itemclick'是事件名,item
是传过去的值。
- methods: {
- btnClick(item) {
- this.$emit('itemclick', item)
- }
- },
2.在子组件中监听点击事件并回调此方法
- <button v-for="(item, index) in categoties" :key="index" @click="btnClick(item)">{{item.name}}button>
3.在父组件中定义一个方法cpnClcik(item)
- methods: {
- cpnClcik(item) {
- console.log('cpnClick'+item.name);
- }
- },
4.并在父组件(vue实例)中调用
(不写参数默认传递btnClick的item ),父组件监听事件名为itemclick
的子组件传过来的事件。
"cpnClcik">
父组件访问子组件,有时候需要直接操作子组件的方法,或是属性,此时需要用到$children
和$ref
。
使用this.$children
直接获取**当前实例的直接子组件,需要注意 $children
并不保证顺序,也不是响应式的。**如果你发现自己正在尝试使用 $children
来进行数据绑定,考虑使用一个数组配合 v-for
来生成子组件,并且使用 Array 作为真正的来源。
-
- <div id="app">
- <cpn>cpn>
- <cpn>cpn>
- <cpn ref="aaa">cpn>
- <button @click="btnClick" >按钮button>
- div>
-
- <template id="cpn">
- <div>
- 我是子组件
- div>
- template>
- <script src="../js/vue.js">script>
- <script>
- // 父传子:props
- const cpn = {
- template: "#cpn",
- data() {
- return {
- name:"我是子组件的name"
- }
- },
- methods: {
- showMessage(){
- console.log("showMessage");
- }
- },
- };
- const app = new Vue({
- el: "#app",
- data() {
- return {
- message:"hello"
- }
- },
- methods: {
- btnClick(){
- // 1.children
- // console.log(this.$children[0].showMessage)
- // for (let cpn of this.$children) {
- // console.log(cpn.showMessage)
- // }
- // 2.$ref
- console.log(this.$refs.aaa.name)
- }
- },
- components: {
- cpn
- },
- })
- script>
$children
方式
- // 1.children
- console.log(this.$children[0].showMessage)
- for (let cpn of this.$children) {
- console.log(cpn.showMessage)
- }
$refs方式:ref 被用来给元素或子组件注册引用信息。引用信息将会注册在父组件的 $refs 对象上。如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例
- ref的基本使用 用在元素上
- DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8">
- <title>title>
-
- head>
- <body>
- <div id="app">
- <p ref="p" @click="handelClick" id="ppp">hellop>
- div>
- <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js">script>
- <script>
- const app = new Vue({
- el: "#app",
- data: {
-
- },
- methods: {
- handelClick(){
- console.log(this.$refs.p);
- const ppp = document.querySelector('#ppp')
- console.log(ppp);
- }
- },
- computed:{
-
- }
- })
- script>
- body>
- html>
- DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8">
- <title>title>
-
- head>
- <body>
- <div id="app">
- <counter ref="one" @change="handelChange">counter>
- <counter ref="two" @change="handelChange">counter>
- <div>total:{{total}}div>
- div>
- <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js">script>
- <script>
- Vue.component('counter',{
- template:'{{number}}',
- data(){
- return {
- number:0
- }
- },
- methods:{
- handelclick(){
- this.number++;
- this.$emit('change');
- }
- }
- })
- const app = new Vue({
- el: "#app",
- data: {
- total:0
- },
- methods: {
- handelChange(){
- this.total = this.$refs.one.number + this.$refs.two.number
- }
- },
- computed:{
-
- }
- })
- script>
- body>
- html>
- DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8">
- <title>title>
-
- head>
- <body>
- <div id="app">
- <helloworld ref="hello">helloworld>
- <button @click="getHello">获取helloworld组件中的值button>
- div>
- <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js">script>
- <script>
- Vue.component('helloworld',{
- template:'',
- data(){
- return {
- number:0
- }
- },
- methods:{
- handelclick(){
- console.log('被调用了');
- }
- }
- })
- const app = new Vue({
- el: "#app",
- data: {
-
- },
- methods: {
- getHello(){
- this.$refs.hello.handelclick();
- console.log(this.$refs.hello.number);
- console.log(this.$refs.hello.$el.innerHTML);
- }
- },
- computed:{
-
- }
- })
- script>
- body>
- html>
- 基于 DOM 内模板的限制来工作
- DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8">
- <title>title>
-
- head>
- <body>
- <div id="app">
- <table>
- <tr is="row">
- tr>
- table>
- div>
- <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js">script>
- <script>
- Vue.component('row',{
- template:'
111 ' - })
- const app = new Vue({
- el: "#app",
- data() {
- return {}
- },
- methods: {
-
- },
- computed:{
-
- }
- })
- script>
- body>
- html>
- DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8">
- <title>title>
- head>
- <body>
- <div id="app">
-
- <component :is="type">component>
- <button @click="handerClick">点击button>
- div>
- <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
- <script>
- Vue.component('child-one',{
- template:'child-one'
- })
- Vue.component('child-two',{
- template:'child-two'
- })
- const app = new Vue({
- el:'#app',
- data(){
- return {
- type:'child-one'
- }
- },
- methods:{
- handerClick(){
- console.log('111');
- this.type=this.type==='child-one'?'child-two':'child-one';
- }
-
- }
- })
-
- script>
- body>
- html>
- 这是动态组件官网案例
- DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8">
- <title>title>
- <style>
- .tab-button {
- padding: 6px 10px;
- border-top-left-radius: 3px;
- border-top-right-radius: 3px;
- border: 1px solid #ccc;
- cursor: pointer;
- background: #f0f0f0;
- margin-bottom: -1px;
- margin-right: -1px;
- }
- .tab-button:hover {
- background: #e0e0e0;
- }
- .tab-button.active {
- background: #e0e0e0;
- }
- .tab {
- border: 1px solid #ccc;
- padding: 10px;
- }
- style>
- head>
- <body>
- <div id="app">
- <button v-for="(tab,index) in tabs":key="index" @click="handelclick(tab)" :class="getStyle(tab)">{{tab}}button>
- <component :is="currentTabComponent">component>
- div>
- <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
- <script>
- Vue.component('tab-home',{
- template:'child-one'
- })
- Vue.component('tab-posts',{
- template:'child-two'
- })
- Vue.component('tab-archive',{
- template:'child-three'
- })
- const app = new Vue({
- el:'#app',
- data(){
- return {
- currentTab: "Home",
- tabs: ["Home", "Posts", "Archive"]
- }
- },
- methods:{
- handelclick(tab){
- this.currentTab = tab
- },
- getStyle(tab){
- return ['tab-button',{active:this.currentTab===tab}]
- }
- },
- computed:{
- currentTabComponent(){
- /* return `tab-${this.currentTab}`.toLowerCase() */
- return "tab-"+this.currentTab.toLowerCase()
- },
-
- }
- })
-
- script>
- body>
- html>