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

  • 相关阅读:
    “约瑟夫问题”实现代码
    “百钱买百鸡”问题
    链栈的表示与实现
    个人作品Demo3PLY文件的读取
    系统程序员成长计划容器与算法(一)(下)
    循环单链表的建立
    链式队列元素删除实现
    使用链栈实现数制的转换
    系统程序员成长计划容器与算法(二)(上)
    个人作品Demo4STL文件读取
  • 原文地址:https://www.cnblogs.com/wenpeng/p/12284150.html
Copyright © 2011-2022 走看看