最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • Vue2基础-组件

    正文概述 掘金(西湖区小阿宋)   2020-11-29   472

    组件

    真实的业务场景中,我们的网页是被分成很多个模块的,比如导航栏,内容区,状态栏等等,同时我们开发的逻辑也是模块化组件化去耦合,因此我们需要以一种嵌套的组件树的形式来组织我们的视图和代码:

    Vue2基础-组件

    组件注册

    我们可以先看一个例子,观察一下什么是组件注册。

    const Foo = {
        template:`
        <div>this is component-Foo</div>
        `
    }
    
    Vue.component("Bar",{
        components:{
            Foo,
        },
        data(){
            return{
                msg: "this is component-Bar"
            }
        },
        template:`
        <div>{{msg}}
            <Foo></Foo>
        </div>
        `
    });
    
    const app = new Vue({
        el:"#app",
        data(){
            return{
                count : 100
            }
        },
        template:`
            <div>
                {{count}}<br>
                <Bar></Bar>
            </div>
        `,
    })
    

    通过上述例子,我们可以看到:

    • 通过vue.component的方式注册的组件被称为全局组件,这一类之组件只要组成后,可以在任何位置使用。声明语法为:

      vue.component('component-name',{
      	//options API
      })
      
    • 通过创建函数对象,并在其他组件內通过components:{component-a,component-b,component-c}的方式注册的,被称为局部注册,仅在该声明的组件內生效。声明语法为:

      const Foo = {
        //options API...
      };
        
      vue.component('Bar',{
      	components:{ Foo },
        // other options API...
      })
      

    通过props传参

    如果我们想要在调用一个组件的时候,通过传入某些参数来控制组件內渲染的视图时,我们可以在注册声明组件的时候,声明一个props参数来实现这个需求:

    Vue.component("Foo",{
      props:['msg','count'],
      template:`
    		<div>
    			{{msg}},{{count}}
    		</div>
    	`
    })
    

    然后在组件外部调用该组件的时候,可以通过上述制定一个attribute来传递进去:

    <Foo msg="msg1" count="one"></Foo>
    <Foo msg="msg2" count="two"></Foo>
    <Foo msg="msg3" count="three"></Foo>
    

    通过emit和v-on监听子组件事件

    如果我们想要通过监听子组件的事件来更改父组件视图的话,比如:当点击子组件的button按钮的时候,父组件上显示的数字翻倍。这时就可以用到emit和v-on了。

    其中emit是子组件用来向父组件传递事件的。

    Vue.component('Foo',{
      data(){
        return{}
      },
      methods:{
        handleClick(){
          this.$emit('double',2);
          this.$emit('treble',3);
        }
      }
      template:`
    		<div><button v-on:click="handleClick">send msg to fatherComponent</button></div>
    	`
    })
    

    这样当点击子组件的按钮的时候,就会触发handleClicck的方法,然后在该方法內通过$emit发送了两个自定义事件和参数。父组件通过V-on监听对应事件,当该事件触发时执行对应的业务逻辑。

          const app = new Vue({
            methods: {
              handleDouble(value) {
                console.log("翻倍了:" , this.count * value);
              },
              handleTreble(value) {
                console.log("三倍:", this.count * value);
              },
            },
            template: `
                <div>
                    <Foo @double="handleDouble" @treble="handleTreblee"></Foo>
                </div>
            `,
            data() {
              return { count:1 };
            },
          });
    

    v-model语法糖实现自定义事件侦听

    当我们在进行父级和子级通信的时候,是需要一方抛出一个自定义事件,然后另一方需要先接受到对应的事件,然后在进行处理逻辑,这样是比较麻烦的。因此v-model语法糖可以给我提供一种方式,不需要再抛出事件/监听事件。

    首先,在需要发送消息的一方,需要定义model:

    Vue.component('Sender',{
      props:['visible'],
      data(){return{}},
      model:{
        event:"close",
        prop:"visible"
      },
      methods:{
        handleClose(){
          this.$emit("close", false)
        }
      },
      template: `
    		<div v-if="visible">
          this is sender, and its state is {{visible}}
          <button @click="handleClose">close</button>
        </div>
    		`,
    })
    

    当子组件点击close按钮的时候,回调用handleClose()方法,这时会向父组件发送一个("close", false),这两个值代表什么东西,等我们看完父组件的代码之后再说:

    const app = new Vue({
      template:`
    		<div>
        	this is receiver,this button can show Sender-component:
          <button @click="handleShowSender">show</button>
          <Sender v-model="showSender" ></Sender>
        </div>
    	`,
      data(){
        return{
          showSender:false
        }
      },
      methods:{
        handleShowSender(){
          this.showSender = true
        }
      }
    })
    

    上述代码v-model="controlSenderr"中的controlSender对应的值对应着子组件定义的model.prop:"visible"参数,当触发handleShowSender函数时,会将showSender的值修改为true,对应的会传递给子组件的visible使之变成true

    刚才留着没有解释的子组件发来的("close", false)这个close其实就是model.event定义的这个事件,与之对应的就是父组件的v-modle:"showSender"这个事件,false就是传过来的value值,赋值给showSender

    这样就实现了不用抛出事件,监听事件,再处理逻辑这样一套繁琐的操作。

    sync实现自定义事件侦听

    Vue还给我们提供了一种类似v-model的方法,也就是.sync修饰符,用法类似,但是我个人更倾向于使用这种方式,因为起名字这个问题永远困扰着程序员,而.sync这种方式个人认为表意更加清晰明确。

    以下是.sync修饰符的使用方式,我们还是先看子组件:

    Vue.component("Sender", {
      components: {},
      props: ["visible"],
      data() {
      	return {};
      	},
    	methods: {
    		handleClose() {
    			this.$emit("update:visible", false);
    			},
    		},
    	template: `
    		<div v-if="visible"> 
    			state of Sender is {{visible}}
    			<button @click="handleClose">close</button>
    		</div>
              `,
    

    可以看到,我们同样是需要定义一个props:'visible'这样才可以控制子组件模块的显示和隐藏;同样的,我们也是在组件内添加了一个close按钮,当点击按钮的时候会触发handleClose的函数方法;不同的是,该方法$emit发送的却改变了,由之前的"close"改成了"update:visible",前面的update:是这种方式的固定语法,后面跟着的就是需要修改的对应props,这样就表意十分明确,一眼可以认出来。

    对应的,父组件需要进行如下操作:

    const app = new Vue({
        el: "#app",
        template: `
            <div>
                <button @click="handleShowSender">showSender</button>
                <Foo :visible.sync="isVisible" ></Foo>
            </div>
        `,
        data() {
          return {
            isVisible: false,
          };
        },
        methods: {
            handleShowSender() {
            this.isVisible = true;
          },
        },
      });
    

    父组件通过:visible:sync监听来自自组件的自定义事件,当接收到自定义事件之后,会讲传过来的第二个参数赋值给后面的isVisible响应式数据。

    slot插槽实现组件自定义模版与替换

    我们可以在子组件里面使用slot插槽,来预设一些模版内容;父组件可以按需加在,如果父组件想要更改模版内容,可以执行在template标签內加上加上自己需要的内容。否则就会渲染出来预设的内容。

    Vue.component("Foo", {
        components: {},
        data() {
          return {};
        },
    
        template: `
            <div> 
              <slot name="header" test1="123" test2="234">header in slot</slot>
              <slot name="main">main in slot</slot>
              <slot name="footer">footer in slot</slot>
            </div>
          `,
    

    在子组件预设slot插件的时候,可以通过name字段区分各个slot,并且也可以预设一些参数,父组件可以直接调用:

    const app = new Vue({
        el: "#app",
        template: `
            <div>
                <Foo>
                  <template #header="{test1}">
                    {{test1}}
                  </template>
    
                  <template #main>
                    main in template
                  </template>
    
                  <template #footer>
                  </template>
                </Foo>
            </div>
        `,
        data() {
          return {};
        },
      });
    

    父组件通过#slotName="{propName}"的方式读取对应名称的slot插槽并使用预设的参数。


    起源地下载网 » Vue2基础-组件

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元