zoukankan      html  css  js  c++  java
  • Vue单文件组件的开发以及CLI脚手架的使用

    Vue.component全局注册组件的方式的缺点

    Vue.component方式 定义的全局组件很方便,但是它有几个天生的缺陷,导致它只能用在很小的项目中,无法发挥Vue框架的全部实力。

    • 它是全局自定义的,要求组件的名称全局唯一,组件数量一旦较多就很难管理。
    • 它没有办法被编辑器的语法高亮支持,编写复杂的template时比较麻烦。
    • 它不支持CSS,需要在外部定义组件的样式,影响组件的使用效率。
    • 它不支持动态构建,无法使用预处理和热加载。
    Vue的单文件组件解决方案及其环境安装和配置

    Vue框架给出的解决方案时.vue后缀的单文件组件。
    那么如何使用.vue为后缀的单文件组件来享受Vue提供给我们的这些便利呢?

    1. 首先,需要安装node.js框架,通过安装这个框架,我们可以获得一系列自动化的工具如npm,当然也可以自行安装yarn来作为npm的替代。但是node.js是一定要安装的。
    2. 安装完毕node.js之后,我们通过npm命令安装vue脚手架.-g是指将vue脚手架安装到全局用户。
    npm install -g @vue/cli
    
    1. 安装完成之后,可以通过vue命令查看安装是否成功以及安装的vue版本
    vue --version
    

    如图

    image
    4. 接下来,我们就可以通过vue的create指令创建新的前端vue工程。并选择default模式。然后脚手架会自动安装工程需要的全部依赖

    vue create vue-demo
    
    1. 创建完成后的vue-demo工程会存在于用户文件夹下的当前用户下。可以看到脚手架帮助我们创建了很多基础文件,甚至为我们创建了本地git。
      如图:
      image

    2. 在控制台中通过cd进入这个目录文件夹,然后通过npm或yarn命令启动项目。推荐使用yarn方式。

    npm run serve
    

    image
    或者

    yarn serve
    

    image

    7.此时已经可以访问创建的vue-demo了
    image

    现有组件的单文件化改造

    为了进一步深入学习,接下来,我们要把前面一直在优化的todo-list和todo-item组件改造成Vue单文件组件,并使用前端框架的形式访问。

    1. 打开vue-demo前端项目的入口文件main.js,这个文件中定义了vue的根节点名称。
    new Vue({
      render: h => h(App),
    }).$mount('#app')
    

    起到的作用类似于

    var vm = new Vue({
            el: "#app",
            /.../
            })
    
    1. render:h=>h(App)代表入口组件是App.vue,我们需要在App.vue引入并注册todo-list和todo-item组件。
    2. App.vue默认引用并注册了一个叫HelloWorld的组件。从这个示例证明,要想在App.vue中引入我们自己的组件,我们先要为这两个组件创建自己的单文件.vue文件。
      image
    3. 按照约定,我们在components文件夹在创建两个vue后缀文件。
    4. 首先是todo-item.vue。通过观察helloWorld.vue,我们可以发现,一个vue文件是由三大块组成的。
    • template用来放置模板,相当于现有组件中的template标签。
    • script用来放置组件的数据(data),方法(methods),属性(props)
    • style是原有组件中不予支持的样式表
    <template>
        
    </template>
    <script>
    export default {
        
    }
    </script>
    <style scoped>
    
    </style>
    
    1. 按照这个结构,我们需要将原有todo-item组件下的template部分,放置到template标签中
    template: `
                  <li>
                      <slot name="pretext" :val="vrandom"></slot>
                      <span v-if="!del">{{title}}</span>
                      <span v-else style="text-decoration:line-through">{{title}}</span>
                      <button v-show="!del" @click="handleClick">删除</button>
                      <slot name="suftext">默认尾部</slot>
                  </li>`,
    

    变为

    <template>
        <li>
            <slot name="pretext" :val="vrandom"></slot>
            <span v-if="!del">{{title}}</span>
            <span v-else style="text-decoration:line-through">{{title}}</span>
            <button v-show="!del" @click="handleClick">删除</button>
            <slot name="suftext">默认尾部</slot>
        </li>
    </template>
    
    1. 将原组件中的props,data,methods放置到script标签中。
    <script>
    export default {
        props: {
              title: String,
              del: {
                type: Boolean,
                default: false
              }
            },
        data: function() {
              return {
                  vrandom:Math.random()
              };
            },
        methods: {
                handleClick(){
                    console.log("点击删除按钮!");
                    this.$emit('delete',this.title);
                }
            }
    }
    </script>
    
    1. 同理,我们创建todo-list.vue
    <template>
        <ul>
            <slot></slot>
        </ul>
    </template>
    <script>
    export default {
        data: function() {
              return {
                
              };
            },
        methods:{
                
        }
    }
    </script>
    <style scoped>
    
    </style>
    

    9.在App.vue将todo-item.vue和todo-list.vue引入并注册.

    <script>
    import todolist from './components/todo-list.vue'
    import todoitem from './components/todo-item.vue'
    
    export default {
      name: 'App',
      components: {
        todolist,
        todoitem
      }
    }
    </script>
    
    1. 我们注册了todolist和todoitem,我们需要在App.vue中使用它。要使用这两个组件,我们需要准备相应的数据。将原new Vue中的data数据和methods方法移到App.vue中。
      App.vue的完整script如下
    <script>
    import todolist from './components/todo-list.vue'
    import todoitem from './components/todo-item.vue'
    
    export default {
      name: 'App',
      components: {
        todolist,
        todoitem
      },
      data(){
        return{
          list: [
                  {
                    title: "新课程1",
                    del: false
                  },
                  {
                    title: "新课程2",
                    del: true
                  },
                  {
                    title: "新课程3",
                    del: false
                  }
                ]
        };
      },
      methods: {
        handleDelete(vtitle){
          console.log("删除工程!",vtitle)
        }
      }
    }
    </script>
    
    1. 最后将原页面中html代码,即使用todo-list和todo-item组件的html移至App.vue中。
    <template>
      <div id="app">
        <todolist>
          <todoitem v-on:delete="handleDelete" v-for="item in list" data-wen="wen" :title="item.title" :del="item.del">
            <template v-slot:pretext="{val}">
              <label>前置文字{{val}}</label>
            </template>
          </todoitem>
        </todolist>
      </div>
    </template>
    

    此时有两个细节需要处理:

    • v-for 后面需要动态绑定Key关键字。
    • 使用的组件名要与注册的组件名一致。前期我们的组件一直叫todo-item,但是我们在本次注册时将组件注册为了todoitem,那么同理我们需要在使用时将名称对应起来。否则会报如下错误。
      image
    1. 全部完成后,效果如图
      image

    至此,我们就完成了两个组件的单文件话改造。现在注册到App.vue的组件todolist和todoitem都是局部作用域,不会污染和与其他组件冲突。

    那么,假如我们希望将todolist在全局注册怎么做能?
    我们只需要在main.js中引入todolist并通过Vue.component注册即可。

    import todolist from './components/todolist.vue'
    
    Vue.component("todolist", todolist);
    

    import Vue from 'vue'
    import App from './App.vue'
    import todolist from './components/todolist.vue'
    
    Vue.component("todolist", todolist);
    
    Vue.config.productionTip = false
    
    new Vue({
      render: h => h(App),
    }).$mount('#app')
    

    但是一般建议少注册全局组件。

    单文件组件中的样式的使用

    单文件组件中我们还有一个内容一直没有使用:style,我们可以通过style定义自己组件的样式,并且保证这个样式只会对自己起作用而不污染其他组件。
    写法如下:

    <style scoped>
        .redsapn{color: red}
    </style>
    

    通过写在scoped标签,Vue框架会对我们的样式生成一个唯一哈希值,保证样式的唯一。
    譬如,我们为todoitem组件增加上述样式,并在组件的template中使用:

    <template>
        <li>
            <slot name="pretext" :val="vrandom"></slot>
            <span class="redsapn" v-if="!del">{{title}}</span>
            <span v-else style="text-decoration:line-through">{{title}}</span>
            <button v-show="!del" @click="handleClick">删除</button>
            <slot name="suftext">默认尾部</slot>
        </li>
    </template>
    

    执行效果如下:
    image

  • 相关阅读:
    JS BOM对象 History对象 Location对象
    JS 字符串对象 数组对象 函数对象 函数作用域
    JS 引入方式 基本数据类型 运算符 控制语句 循环 异常
    Pycharm Html CSS JS 快捷方式创建元素
    CSS 内外边距 float positio属性
    CSS 颜色 字体 背景 文本 边框 列表 display属性
    【Android】RxJava的使用(三)转换——map、flatMap
    【Android】RxJava的使用(二)Action
    【Android】RxJava的使用(一)基本用法
    【Android】Retrofit 2.0 的使用
  • 原文地址:https://www.cnblogs.com/wenpeng/p/12284150.html
Copyright © 2011-2022 走看看