even

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

1、vue的函数式组件编程以及jsx语法

为写项目的过程中,如果遇到比较动态的template的时候,可以使用函数式组件,具体如下

新建jsx文件

export default {
  name: 'homeTest',
  functional: true, //是否开启函数式编程,开启后不能定义data, methods, computed, watch等对象
  props: { // 可以对传入的属性进行选择接收与不接收,如果不接收,那么在render里面就无法使用,如果不定义的情况下,那么所有传入的属性都可以使用
    title: String,
    isShow: Boolean
  },
  render (h, context) { //第一个参数必需传h,第二个参数表示调用组件里的上下文
    return <div class='container'>
      {context.props.title} <!--在进行变量使用的时候需要用{}进行修饰-->
      {context.props.isShow //使用三元运算符进行判断是否渲染,如果多条件的情况,可以在jsx的文件里定义函数进行处理
        ? context.props.title //在使用事件的时候,如果 on-click这个是固定格式,里面需要用{}进行修饰,注意下面定法
        : <el-button type='primary' on-click={() => context.listeners.change()}>按钮</el-button>}
      <div>{context.slots().default}</div> <!--使用插槽的时候,调用方法-->
    </div>
  }
}

注意:以上方式进行编码的时候,引入样式文件很容易影响到全局,那么可以使用另外一种方式,并且以上的方法需要在父组件中定义,调用时用context.listeners进行调用

 新建test.vue内容如下,但是在render里面用的时jsx的语法

<script>
export default {
  name: 'homeTest',
  functional: true,
  props: {
    title: String,
    isShow: Boolean
  },
  render (h, context) {
    return <div class='container'>
      {context.props.title}
      {context.props.isShow
        ? context.props.title
        : <el-button type='primary' on-click={() => context.listeners.change()}>按钮</el-button>}
      <div>{context.slots().default}</div>
    </div>
  }
}
</script>
<style lang="less" scoped>
.container{
  color: blue
}
</style>

 注意:一旦声明了functional为true的时候就无状态、无实例、没有this上下文、无生命周期

 在jsx中实现列表循环渲染

export default {
  name: 'homeTest',
  functional: true,
  props: {
    title: String,
    isShow: Boolean
  },
  render (h, context) {
    const list = ['aaa', 'bbb', 'ccc']
    const arr = []
    list.forEach(val => arr.push(<div>{val}</div>))
    return <div class='container'>
      {arr}
    </div>
  }
}

注意: style={{width:'233px', marginRight:'10px'}}样式的写法要用双花括号,里面可以使用变量 

使用template的方式进行函数式组件的定义

主组件

<template>
  <div>
    <h3>this is home</h3>
    <itemWrap :title="title" @clickEvent="clickEvent"><div>haha</div></itemWrap> <!--函数式组件的调用-->
  </div>
</template>
<script>
import itemWrap from './itemWrap'
export default {
  name: 'Home',
  components: {
    itemWrap
  },
  data () {
    return {
      title: '这个是传值的title'
    }
  },
  methods: {
    clickEvent () {
      console.log('ok')
    }
  }
}
</script>
<style lang="less" scoped></style>

 函数式组件

<template functional>
  <div>
    <h1>{{props.title}}</h1> <!--属性的调用-->
    <slot></slot> <!--插槽的调用-->
    <button @click="listeners.clickEvent">点击</button> <!--方法的调用-->
  </div>
</template>
<script>
export default {
  name: 'Item'
}
</script>
<style lang="less" scoped></style>

 2、组件的拆分规则

在使用vue组件进行拆分功能的时候,如果有遇到需要渲染的数据比较深层的时候避免一个组件完成,尽量使用插槽来完成例如:

在调用界面

  <itemWrap>
    <item v-for="(val, ind) of list" :key="ind" :content="val"></item>
  </itemWrap>

itemWrap组件

<div class="itemWrap">
  <slot></slot>
</div>

item组件

<template>
    <div>{{content}}</div>
</template>
<script>
export default {
  name: 'item',
  props: {
    content: {
      type: String,
      required: true
    }
  }
}
</script>

这种格式的好处在于,如果遇到数据多层级的时候,而致使中层传数据的麻烦,可以在调用层进行数据配置

 3、vue路由传参params与query的区别

vue通过路由传参的方式有两种,params与query,两者的区别在于,params是实现编程式导航跳转,而query是实现路径拼接跳转

1、在路由配置的时候,params的配置需要配置成 /路径/:id 的形式,id表示会在params中进行定义,而query无需这样配置

params路由的配置如下

{
  path: '/test/:id',
  name: 'test',
  component: () => import('@/views/test/first'),
  meta: { title: 'test' }
}

注意:如果是可选参数,那么可以书写成该样式 :id?

query路由的配置按正常配置

2、在进行路由跳转的时候,params需要用路由中定义的name进行跳转,不能用path进行跳转否则会失败

params路由跳转

this.$router.push({ name: 'test', params: { id: { name: 'aaa', age: '12', sex: 'unknow' } } })
<router-link :to="{ name:'router1',params: { id: status ,id2: status3},query: { queryId:  status2 }}" >

query路由跳转按正常跳转

4、vue中动态参数,以及动态事件的写法

let app = Vue.createApp({
    template: '<div @[event]="test" :[name]="content">{{content}}</div>',
    data() {
        return {
            content: 'abc',
            event: 'mouseover', //这里的mouseover相当于一个动态事件
            name: 'message'  //这里的name相当于一个动态参数
        }
    },
    setup(proxy) {
        const test = () => {
            console.log(app, vm)
        }

        return {
            test
        }
    }
})
let vm = app.mount('#root')

5、vue中样式的模块化写法

<template>
<div :class="[$style.container]">
  <h2 :class="[$style.container__p]">this is home111</h2>
  <el-button type="primary" @click="changeEvent(0)">item组件</el-button>
  <el-button type="primary" @click="changeEvent(1)">itemWrap组件</el-button>
  <component :is='getType(currentIndex)' ref="abc"></component>
  <el-button @click="getComp">获取</el-button>
</div>
</template>
<script>
import Item from './item'
import ItemWrap from './itemWrap'
export default {
  name: 'Home',
  components: {
    Item, ItemWrap
  },
  data () {
    return {
      currentIndex: 0
    }
  },
  methods: {
    getType (id) {
      return id === 0 ? 'Item' : 'ItemWrap'
    },
    changeEvent (id) {
      this.currentIndex = id
    },
    getComp () {
      console.log(this.$refs.abc)
      this.$refs.abc.check && this.$refs.abc.check()
    }
  }
}
</script>
<style lang="less" module>
  .container{
    color: red;
    &__p{
      color: blue;
    }
  }
</style>

相当react里的css in js的写法

 

posted on 2021-02-20 00:41  even_blogs  阅读(198)  评论(0编辑  收藏  举报