组件通过props属性传值

组件之间的传值

组件是一个单独功能模块的封装,有属于自己的data和methods,一个组件的 data 选项必须是一个函数
为什么必须是函数:因为只有当data是函数时,不同实例调用同一个组件时才会开辟新空间,互不干扰

data() {
  return {
    count: 0
  }
}

父子组件区分

    <div id="app">
            <cpn> </cpn>
            <cpn1></cpn1>
    </div>
<script>
    //子组件
    const childCpn = Vue.extend({
        template: `
            <div>
                <h3>我是局部组件,也是子组件</h3>
            </div>
     			` })
    // 父组件
    const parentCpn = Vue.extend({
        template: `
            <div>
                <h2>我是局部组件,也是父组件</h2>
                <!-- 使用子组件 -->
                <cpn1></cpn1>
            </div>
        `,
        components:{
            cpn1: childCpn  //在父组件中注册子组件
        }
    })
    let app = new Vue({
        el:"#app",
        data:{ },
        components:{
            cpn : parentCpn,
            cpn1 : childCpn   //若想在实例中使用子组件也需要在实例中注册
        },
    })
</script>

父传子

Prop 是可以在组件上注册的一些自定义属性,prop值可以是属性也可以是方法,最终都会出现在子组件的实例上供子组件直接调用

一个组件默认可以拥有任意数量的 prop,任何值都可以传递给任何 prop ,在组件实例中可以直接访问这个值,就像访问 data 中的值一样

<body>
    <!--vue实例需要一个根组件div-->
    <div id="app">
        <ul>
        	<!--使用组件-->
            <tokyo v-for="item in names " :first-name="item"></tokyo>
        </ul>
    </div>

<script type="text/javascript">
        //注册组件
    Vue.component('tokyo',{
        props:['firstName'], //属性
        template:'<li>名字:<h3>{{firstName}}</h3></li>' //模板
    })
    //vue实例
    const app = new Vue({
        el:'#app',
        data:{
            names:['lixiang','wanzi'],  
        }
    })
</script>
</body>

命名方式:

组件名:组件名如果是多个单词时,首字母大写或者加横线都可以。MyComponentName 或my-component-name
若使用首字母大写的方式注册,使用时两种方式都可

prop参数:camelCase (驼峰命名法) 的 prop 名需要使用其等价的 kebab-case (短横线分隔命名) 命名,在子组件内部命名方式不变,绑定父组件属性时要改驼峰命名
为短横线连接

语法

父传子分离写法

 <!--父组件模板-->
    <div id="app">
        <!--使用子组件,v-bind绑定父组件属性给子组件props属性-->
        <cpn v-bind:ctitle="title"  :cname="names" ></cpn>
    </div>
    <!--子组件模板-->
    <template id="cpnTemplate">
    <div>
        <h3>{{ctitle}}</h3>
        <ul>
            <li v-for="item in cname"> <p>{{item}}</p> </li>
        </ul>
    </div>
    </template>
<script>

    //注册子组件
    const cpn ={
        template:"#cpnTemplate",
        props:['cname','ctitle'],
        data(){
            return{}
        },
        methods:{
        }
    }
    //注册父组件
    let app = new Vue({
        el:"#app",
        data:{
            names:['丸子','莉香','三上'],
            title:'hello'
        },
        components:{
            // cpn:cpn
            cpn   //标签名和组件名相同时可简写为cpn
        }
    })
</script>

vue-cli项目组件写法

1、定义组件

<template>
   <div>
        <h3>{{ctitle}}</h3>
        <ul>
            <li v-for="item in cname"> <p>{{item}}</p> </li>
        </ul>
   </div> 
</template>
<script>
export default {
     name: "tokyoLoveStory",
     components: {},
     mixins: [],
     props:['cname','ctitle'],
     data(){
        return{}
     },
     methods:{
     }
};
</script>

2、使用组件

<template>
    <!--使用组件时,需变驼峰为短横线-->
    <tokyo-love-story v-bind:ctitle="title"  :cname="names"></tokyo-love-story>
</template>

<script>
    import tokyoLoveStory from 'xxx/tokyoLoveStory'
    export default{
       

        data(){
             names:['丸子','莉香','三上'],
             title:'hello'
        } ,
        components:{
            tokyoLoveStory
        },
        methods:{
            ...
        },
            ...
        }
</script>

props另一种书写形式:

 props:{
            cname:'',
            ctitle:'',
            //基础类型
            propA:Number,
            //多个可能的类型
            propB:[String,Number],
            //必填的字符串
            propC:{
                type:Number,
                required:true
            },
            //带有默认值的字符串
            propD:{
                type:Number,
                default:100
            },
            //对象或数组默认值必须是一个函数,返回值是[]或{}
            propE:{
                type:Object,
                default: function () {
                    return [];
                }
            }

子组件向父元素传值

想要子组件的数据传递给父元素,需要自定义触发事件,实现数据的传值。

子组件可以通过调用内建的 $emit 方法并传入事件名称来触发一个事件

<body>
    <!--vue实例需要一个根组件div-->
    <div id="app">
        <ul>
        <!--使用组件,绑定props属性,子组件的触发事件调用父元素方法达到传递参数的目的-->
            <tokyo v-for="item in names " 
            	:first-name="item" 
				:parentMethod="parentMethod"
				@emitevent="emitName">
            </tokyo>
        </ul>
        <h3>选中的姓名是:{{chooseName}}</h3>
    </div>

<script type="text/javascript">
        <!--注册组件-->
    Vue.component('tokyo',{
        props:['firstName'],
        template:'<li>名字:<h3>{{firstName}}</h3> ' +
            ' <button @click="chooseEvent(firstName)">点击传递姓名</button></li>', 
        methods:{
            chooseEvent(firstName){
                console.log(firstName);
                //触发父元素中emitevent事件,并传递firstName参数给该事件
                this.$emit('emitevent',firstName);  
            }
            parent(){
    			this.parentMethod()	//parentMethod()在子组件实例中,可直接调用
			}
        }

    })
    const app = new Vue({
        el:'#app',
        data:{
            names:['莉香','丸子','三上','里美'],
            chooseName:''
        },
        methods:{
            //父元素被触发的事件,name为子组件传递过来的参数,赋给父元素的data:{}中的属性
            emitName(name){
                console.log("被触发事件");
                this.chooseName = name;
            },
            parentMethod(){
                console.log("parentMethod")
            }
        }
    })
</script>
</body>
posted @ 2020-11-16 00:16  至安  阅读(1181)  评论(0编辑  收藏  举报