zoukankan      html  css  js  c++  java
  • Vue3(二)工程化开发方式做项目

    工程化的开发方式

    这是开发中、大型项目的必备技能,网上资料也很多,这里只是一个简单的综合性的介绍。包括vue的全家桶、建立项目的几种方式、UI库的简单使用等。
    可以和上一篇的cnd方式做项目做一下对比。

    node.js,npm、cnpm、yarn

    node.js

    执行 npm run serve ,然后就可以在浏览器里面访问了,那么这是怎么做到的呢?
    这个就要归功于node了。建立项目的时候,会自动创建一个node的服务,这样我们就可以边写代码,边看运行效果了。
    所以工程化开发,首先要安装一个node。安装方法网上已经有很多了,这里就不搬运了。
    大家也不用担心,不会用node怎么办。这个是自动化的,记住几个命令就行。

    然后要掌握一个安装包的技能,npm、cnpm、yarn都是包管理的工具。

    npm

    因为需要从国外服务器下载需要的文件,所以安装包的速度会很慢。如果不发布自己的包的话,那么就没有必要用这个了。
    安装node后,一般会自动安装npm。

    cnpm

    是淘宝团队做的一个国内镜像,cnpm会从国内服务器下载需要的文件,所以速度就非常快了,除了不能发布包之外,其他功能和npm是一样的。

    • 安装方式:
    npm install -g cnpm --registry=https://registry.npm.taobao.org
    

    yarn

    Yarn是facebook发布的一款取代npm的包管理工具。
    yarn会缓存下载的文件,虽然第一次会有点慢,但是以后就会非常快了,而且还可以并行下载。所以推荐使用 yarn 做资源包的管理工具。

    • 安装方式:
    npm install -g yarn
    
    • 使用方式
    yarn --version   // 查看版本
    yarn init // 同npm init,执行输入信息后,会生成package.json文件
    yarn add [package] // 在当前的项目中添加一个依赖包,会自动更新到package.json和yarn.lock文件中
    yarn upgrade  // 用于更新包到基于规范范围的最新版本
    yarn install //安装package.json里所有包,并将包及它的所有依赖项保存进yarn.lock
    yarn serve // 开发环境下运行vue3的项目
    yarn publish   // 发布包
    yarn remove [package] // 移除依赖包
    
    

    也可以到官网下载安装:https://yarn.bootcss.com/docs/install/#windows-stable

    安装Vue

    # 最新稳定版
    yarn add vue@next
    # OR
    cnpm install vue@next
    

    安装脚手架

    yarn global add @vue/cli@next
    # OR
    npm install -g @vue/cli@next
    

    建立项目

    目前有两种方式创建Vue3的项目:

    • 传统的脚手架(cli)的方式,完善、全面、稳定、成熟。
    • 新的vite的方式,似乎还在完善中,可以尝尝鲜。

    cli 脚手架的方式建立项目

    官网:https://cli.vuejs.org/zh/guide/
    其优点就是可以自动创建项目目录结构和需要的各种文件,免去新手自己安装各种包的麻烦。
    vue全家桶、Babel/TypeScript 转译、ESLint 集成、单元测试和 end-to-end 测试等。
    网上资料比较多,我就不搬运了。

    vue create my-project // 命令行的方式创建项目,按照提示一步一步选择,最后创建项目。
    # OR
    vue ui // 可以在浏览器里面可视化的方式创建项目,而且是中文版,适合新手使用。
    

    vite 的方式建立项目

    官网: https://vue3js.cn/docs/zh/guide/installation.html#命令行工具-cli

    vite 是一个 web 开发构建工具,由于其原生 ES 模块导入方法,它允许快速提供代码。通过在终端中运行以下命令,可以使用 Vite 快速构建 Vue 项目。
    这是尤雨溪大大做的一个新的方式,想法非常新颖,可以多关注和尝试。

    $ npm init vite-app <project-name>
    $ cd <project-name>
    $ npm install
    $ npm run dev
    

    或者

    $ yarn create vite-app <project-name>
    $ cd <project-name>
    $ yarn
    $ yarn dev
    

    一个有趣的现象,在vue的官网上面,vite建立项目的方法,直接介绍了,但是cli建立项目的方法却没有直接介绍,而是加了一个不太明显的连接,害得我都没看到。
    记得以前是在官网里直接介绍cli的创建项目的方式的。
    那么是不是意味着vue打算主推vite呢?

    vue全家桶的手动安装方式

    • Router
    npm install vue-router
    # or
    yarn add vue-router
    
    • Vuex
    npm install vuex --save
    # or
    yarn add vuex
    

    安装第三方UI库

    • element Plus
    npm install element-plus --save
    
    • Ant Design Vue
    npm install ant-design-vue --save
    yarn add ant-design-vue
    
    • Vant
    npm i vant@next -S
    

    其他略...

    项目结构

    好了,各种折腾,终于把项目搭建起来了,我们来看看是什么样子
    目录结构.png

    是不是很简单清晰。

    代码入口 main.js

    import { createApp } from 'vue' // 引入 createApp 函数
    import Antd from 'ant-design-vue' // 引入UI库
    import 'ant-design-vue/dist/antd.css' // 引入css
    import App from './App.vue' // 引入我们写的代码
    import router from './router' // 引入路由的实例
    import store from './store' // 引入状态管理的实例
    
    createApp(App)
        .use(store) // 状态管理
        .use(router) // 路由
        .use(Antd) // UI 库
        .mount('#app') // 挂载
    
    • import
      es6的一种加载方式,from 后面只能写常量,不能写变量,也不支持字符串的运算。

    还是感觉cdn的方式更容易看清楚内部原理。

    页面入口 App.vue

    在vue里面都是组件(.vue),只是我们从业务逻辑的角度来说,可以分为页面和组件两种,当然并不是严格的区分。

    App.vue 可以视为页面的入口

    <template>
      <div id="nav">
        <router-link to="/">Home</router-link> |
        <router-link to="/about">About</router-link>
      </div>
      <router-view/>
    </template>
    
    <script>
    export default {
      name: 'App', 
      setup() {
        console.log('你好,世界!')
      }
    }
    </script>
    
    <style lang="scss">
    #app {
      font-family: Avenir, Helvetica, Arial, sans-serif;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      text-align: center;
      color: #2c3e50;
    }
    
    #nav {
      padding: 30px;
      a {
        font-weight: bold;
        color: #2c3e50;
        &.router-link-exact-active {
          color: #42b983;
        }
      }
    }
    </style>
    

    脚手架默认为我们做了一个简单的路由,设置了模板、代码、css的结构。

    • template
      模板部分。可以写html和vue的方式。

    • script
      js脚本部分,可以没有。支持js语法,写vue需要的各种代码。

    • style
      css部分,也可以没有。

    页面 About.vue

    在这里实现一下上一篇里的功能。

    • 模板部分
    <template>
      <div class="about">
        <h1>这是一个测试页面</h1>
        {{value}}<br>
        <input type="button" value="测试" @click="click"/>
    
        <hr>
        vuex状态演示<br>
        $store - count:{{$store.state.count}}<br>
        $store - myObject:{{$store.state.myObject}}<br>
        $store - myObject.time:{{$store.state.myObject.time}}<br>
        setup - count:{{count}}<br>
        setup - obj :{{obj}}<br>
        setup - objTime :{{objTime}}<br>
        <input type="button" @click="setCount" value="vuex的 计数"/><br>
        <input type="button" @click="setTime" value="vuex的 设置属性"/><br>
        <hr>
    
        路由的演示<br>
        <div>
          <p>
            路由的简单演示,其实CND方式不太适合用路由,因为组件写起来比较麻烦。<br>
            <!-- 使用 router-link 组件来导航. -->
            <!-- 通过传入 `to` 属性指定链接. -->
            <!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
            <router-link to="/about/home">首页</router-link>&nbsp;&nbsp;&nbsp;
            <router-link to="/about/product">产品</router-link>
          </p>
          <!-- 路由出口 -->
          <!-- 路由匹配到的组件将渲染在这里 -->
          路由入口<br>
          <router-view></router-view>
        </div>
      </div>
    </template>
    

    按照前一篇的例子,实现相同的功能,做一下对比,可以发现基本没有啥区别。

    • js代码部分
    <script>
    import { ref } from 'vue'
    import { useStore } from 'vuex'
    
    // vue3的 Composition API 的含义
    const testManage = () => {
      const value = ref  ('你好,世界')
      const click = () => {
        value.value = '好的,收到' + new Date().valueOf()
      }
      
      return {
        value,
        click
      }
    }
    
    export default {
      name: 'Home',
      setup() {
        // 使用外面的定义,分解setup内部的代码
        const { value, click } = testManage()
        
        const store = useStore()
        console.log('store', store)
        console.log('store.state', store.state)
    
        const setCount = () =>{
          store.commit('setCount')
        }
    
        const setTime = () =>{
          store.commit('setTime')
          // 测试直接修改
          // 加上 readonly 就不可修改了,
          // 但是代码并不会报错
          setTimeout(() => {
            obj.time = '222'
            console.log('setTimeout-obj',obj)
          },500)
        }
    
        // 获取state
        // const count1 = store.state.count 强烈建议不要直接访问
        const count = store.getters.getCount
        const obj = store.getters.getMyObject
        const objTime = store.getters.getTime
        console.log('obj', obj)
        console.log('objTime', objTime)
        
        return {  // 返回给模板,否则模板访问不到。
          value,
          click,
          setCount,
          setTime,
          count,
          obj,
          objTime
        }
      }
    }
    

    基本上也没啥大区别。不重复介绍了。

    组件

    • home.vue
    <template>
      <div class="hello">
        <h1>{{ msg }}</h1>
        home <br>
        $store - count:{{$store.state.count}}<br>
        $store - myObject:{{$store.state.myObject}}<br>
      </div>
    </template>
    
    <script>
    export default {
      name: 'com-home',
      props: {
        msg: String
      }
    }
    </script>
    

    基本上是一个空的组件,没啥实际内容,只是显示一下状态管理里的state的数据。只是一个简单的演示。
    另一个组件也是类似,就不贴代码了。

    状态管理

    import { readonly } from 'vue'
    import { createStore } from 'vuex'
    
    export default createStore({
      state: {
        count: 0,
        myObject: {
          time: '现在的时间'
        }
      },
      getters: {
        getCount: (state) => {
          return state.count
        },
        getMyObject: (state) => {
          return readonly(state.myObject)
        },
        getTime: (state) => {
          return state.myObject.time
        }
      },
      mutations: {
        setCount(state) {
          state.count++
        },
        setTime(state) {
          state.myObject.time = '现在时间:' + new Date()
        }
      },
      actions: {
      },
      modules: {
      }
    })
    
    

    对比一下cnd的方式,除了引用的部分之外,其他的也是基本一致。不再次介绍了。

    路由设置

    import { createRouter, createWebHistory } from 'vue-router'
    import Home from '../views/Home.vue'
    
    const routes = [
      {
        path: '/',
        name: 'Home',
        component: Home
      },
      {
        path: '/about',
        name: 'About',
        // route level code-splitting
        // this generates a separate chunk (about.[hash].js) for this route
        // which is lazy-loaded when the route is visited.
        component: () => import('../views/About.vue'),
        children: [
          {
            path: 'home',
            name: 'About-home',
            component: () => import('../components/home.vue')
          },
          {
            path: 'product',
            name: 'About-product',
            component: () => import('../components/product.vue')
          }
        ]
      },
    ]
    
    const router = createRouter({
      history: createWebHistory(process.env.BASE_URL),
      routes
    })
    
    export default router // 返回实例
    

    脚手架默认设置了一个简单路由,这个就不改了,只是在about里面加一个子路由,实现一个简单的嵌套路由。

    主要部分都介绍完毕。

    小结

    工程化开发的好处有很多,比如可以就帮我们划分好目录结构,文件位置,这样大家都按照这个规则来开发,那么看别人的项目的时候就不用费劲想别人会用什么开发方式了。

    这只是做开发的第一步,后面还有很多很多很多。。。

  • 相关阅读:
    UWP 应用获取各类系统、用户信息 (1)
    Windows Composition API 指南
    详解 UWP (通用 Windows 平台) 中的两种 HttpClient API
    Win2D 官方文章系列翻译
    Spring的IOC容器, AOP切面及启动流程简述
    maven和gradle的全局阿里云镜像代理
    SpringBoot项目中@Async方法没有执行的问题分析
    Oracle向MySQL迁移的注意点整理
    SpringBoot项目替换内部的依赖jar包
    MySQL的主从复制
  • 原文地址:https://www.cnblogs.com/jyk/p/14357601.html
Copyright © 2011-2022 走看看