首页 > 技术文章 > npm 和 yarn 区别

shiyi2009 2020-12-21 08:38 原文

npm 

1 1. 不用单独安装,node装好了npm就自动装好了
2 2. npm是一个包,这个包可以管理(下载、更新、删除)别的包
3 3. npm在下载包的时候有一个缓存的过程,我们一般不会使用npm默认下载缓存目录,而会自定义指定npm下载缓存目录
4 执行 npm config set cache "C:\Program Files\nodejs\npm_cache"
5 4. npm下载包分为本地下载和全局下载,本地下载会下载到指定的文件夹,而全局下载会下载到默认的全局包保存路径,我们一般不会使用npm默认的全局包下载保存路径,而会自定义指定npm全局包下载路径。
6 执行 npm config set prefix "C:\Program Files\nodejs\npm_global"
7 
8 注意:npm自定义修改了全局包存放路径,还需要去设置环境变量,将自定义全局包路径加到环境变量中,否则全局装的包没法在命令行窗口中正常使用

yarn

 1 1. 这个包默认没有,需要使用npm来进行安装
  执行命令:
npm install -g yarn
 2 2. yarn是一个包,这个包可以管理(下载、更新、删除)别的包  
3
3. yarn在下载包的时候有一个缓存的过程,我们一般不会使用yarn默认下载缓存目录,而会自定义指定yarn下载缓存目录
4
5 执行 yarn config set cache-folder "C:\Program Files\nodejs\yarn_cache"
6
7 4. yarn下载包分为本地下载和全局下载,本地下载会下载到指定的文件夹,而全局下载会下载到默认的全局包保存路径,我们一般不会使用yarn默认的全局包下载保存路径,而会自定义指定yarn全局包下载路径。
8 9 执行 yarn config set global-folder "C:\Program Files\nodejs\yarn_global"
10 11 注意:yarn自定义修改了全局包存放路径,还需要去设置环境变量,将自定义全局包路径加到环境变量中,否则全局装的包没法在命令行窗口中正常使用
12 为什么要用yarn?
13 在企业中开发yarn用得更多!!npm能做的事情它都可以做!而且做得更好

14
15 要求大家要记两套命令

vue 中的 element-ui框架  yarn和npm 都可以进行运行

    (1). 环境配置: 

        1.使用 vue init webpack 项目名创建一个新项目,步骤跟之前一样,自动生成目录

         2.无论是使用 yarn 还是 npm 最初使用的时候都需要进行 创建一下路径, 如果创建完之后下一次使用

        就不需要进行使用了。

        3.第三步就是  当我们拿一个项目之后我们要做的就是要检查一下  node-modules这个文件夹

        一般情况下都不会有这个东西

        node-modules 是 package.json 所依赖的所有第三方包

        如果没有这个包存在 就要在控制台里面 执行 yarn  install 就会 根据 package.json里面的数据

        进行下载。

        4.一般创建项目之后 package.json 中默认:start: npm run dev 所以要把它修改  为  yarn run dev

        其他的没涉及到yarn就不需要进行修改。

        5.下载 element-ui 框架的包,开发用的包使用 yarn add element-ui 下载

        6.下载完之后需要在main.js进行配置 一下(因为这个框架是全局使用,所以需要进行配置一下)

         所下载的 element。 

 1 import Vue from "vue";
 2  import app from "./App.vue" // 1、导入根组件
 3  // element-ui 需要引入的东西
 4  import ElementUI from 'element-ui';
 5  import 'element-ui/lib/theme-chalk/index.css';
 6  import router from "./router";
 7  import "./assets/css/reset.css";
 8  Vue.use(ElementUI); // 全局使用vue-router插件,只需要导入一次就行    全局导入的最好方法。
 9  // new Vue创建根实例,并渲染根组件
10  // 根实例渲染根组件,根组件使用router-view
11  new Vue({
12  el: "#app", // 根实例
13  components: { app }, // 2、注册根组件
14  template: "<app></app>", // 3、使用根组件 可以只写单标记<app/>
15  router
16  });

    7.创建router 文件夹,配置路由index.js文件

 1 import Vue from "vue";
 2  import VueRouter from "vue-router";
 3  // 只有 login 和 home 页需要进行路由跳转
 4  import Home from "../pages/Home";
 5  import Login from "../pages/Login"
 6  Vue.use(VueRouter); // 全局使用vue-router插件,只需要导入一次就行
 7  let router = new VueRouter({
 8  routes: [
 9  { path: '/',redirect: '/login' },
10  { path: '/home', component: Home },
11  { path: '/login', component: Login }
12  ]
13  });
14  export default router; //

   9.最后配置一下 App.vue文件,这个文件 是由 router 和 main两个的一些文件共同控制的。

    从而进行实现页面渲染

   10. element -ui 创建首页框架步骤(官网都有配置要求,css也可使用更加高级的写法)

      1.同样分为三大部分

        template  script  style 

      2.确定管理系统首页结构,上中分  中间分为 左右,  左边是菜单,右边分上下,上是内容区域,下面是页脚(结构能使用的标签官网有规定)

      <el-container>:外部容器。当子元素中包含<el-header> 或 <el-footer>时,

      全部子元素会垂直上下排列,否则会水平左右排列

      <el-header>:顶栏容器。

        <el-aside>:侧边栏容器。
        <el-main>:主要区域容器。
         <el-footer>:底栏容器。
注意: 以上组件采用了flex 布局  使用前请确定目标浏览器是否兼容。此外<el-container>的子元素只能是最后四者,后四者的父元素
    也只能是 <el-container>  所以一定要注意写法。
    
    导入element-ui 之后可以使用这些标签,el-container 可以无限嵌套自己
  
 1 <template>
 2    <el-container class="page-container">
 3      <el-header height="60px"> <!-- 最好是在行内写这 种,header footer 默认高度就是60px -->
 4        <h1>这是标题</h1>
 5      </el-header>
 6      <el-container>
 7          <el-aside>这是菜单栏</el-aside>
 8        <el-container>
 9          <el-main>这是内容区</el-main>
10          <el-footer>这是页脚</el-footer>
11        </el-container>
12      </el-container>
13    </el-container>
14  </template>

    3.css的高级写法---stylus

  

 1 <style  lang="stylus" type="text/stylus" scoped>
2 /* sass less stylus 三个高级语法 */ 3 /* stylus 需要安装两个包支持,stylus-loader stylus */ 4 /* stylus语法规定:不能多缩进,也不能少缩进,空格只能在冒号后边加 */ 5 /* 安装stylus的包的时候注意版本,要选择支持当前webpack版本的包,不要随便 动webpack的版本,动webpack所有都要重新配置 */ 6 /* 直接使用.el-container会误伤其他两个,所以起个类名区分 */ 7   .page-container 8     height: 100% 9     .el-header 10       background-color: cadetblue 11       display: flex 12       align-items: center 13       color: #fff 14     .el-aside 15       background-color: cornsilk 16     .el-footer 17       background-color: cadetblue 18       color: #fff 19 </style>

    (3.) element-ui 创建首页菜单步骤(官网有配置要求、css更改专用样式属性)

    1.菜单栏使用的固定标签(静态书写)

    <el-menu>:菜单栏的根节点

    <el-menu-item>:叶子节点,该菜单下没有 二级菜单
    <el-submenu>:非叶子节点,该菜单下还有二级菜单
 
  注意: el-menu 自带 1px 的有边框,记得去掉 .el-menu border-right:none
  两种不同节点<el-menu-item>和<el-submenu> 的规定标题格式 
<el-menu>
   <el-submenu>
     <template slot="title">     //这个是二级菜单的头部   一定要加 slot这个属性
       <i class="el-icon-setting"></i>
       <span>系统管理</span>
     </template>
     <el-menu-item>   // 这个是标题下面的子菜单
       <i class="el-icon-menu"></i>
       <span>子菜单</span>
     </el-menu-item>
     <el-menu-item>
       <i class="el-icon-menu"></i>
       <span>子菜单</span>
     </el-menu-item>
   </el-submenu>
   <el-submenu>.......</el-submenu>// 使用方法和第一个一样
   <el-submenu>.......</el-submenu>
===========================================================================   <el-menu-item> //这个是叶子节点 没有子菜单了     <i class="el-icon-menu"></i>     <span slot="title">密码修改</span> //就不需要进行嵌套一些东西了。同样有一个插槽,显示标题   </el-menu-item> </el-menu>

    2.动态创建菜单栏(实际数据应该是从服务器请求回来的数据)

   服务器请求回来的数据是线性结构,要先将线性结构转换成树状结构,便于使用 v-for 遍历数据,使用计算属性动态计算

 

 js 中的计算属性

  computed: {

     menuData() {
               // 接收返回的树状结构的数据,给每个一级动态创建children属性,包            
               //含其自 己的子集
      let result = [];
                // 将menu数组中fid为0 筛选出来,遍历并深复制,以免改变原数组中的值
               // (以免把动态开辟的children添加到原数组中)
              //为什么要深复制就是为了不改变后台 传过来的 数组(数据)
   this.menu.filter(item => item.func_fid === 0).forEach(item => {    let node = Object.assign({},item); // 深复制             // 筛选出menu数组中为父子关系的   let children = this.menu.filter(item2 => item2.func_fid === item.func_id);             // 如果该元素有children,把children遍历并深复制后push到   node.children  if(children.length > 0){     node.children = [];     children.forEach(item2 => node.children.push(Object.assign({},item2)));   } // 最后 result.push(node); }); return result; } }
<!-- default-active 不支持sync修改值,只能通过监听事件修改 -->
 <!-- @select菜单激活回调,自带两个回调参数 -->
 <el-menu background-color="cornsilk" active-text-color="" :default￾active="activeFuncKey" @select="menuSelectHandler">
 <!-- template不会被保留,可以用于不太好循环的地方,但template不可以加key-->
 <!-- key要加在template的根节点上,有两个则两个都加 -->
 <template v-for="item in menuData" >
                                            <!-- 使用key值判断是否是叶子或非叶子节点,空为非叶子,非空为叶子 -->
                                            <!-- element-ui 规定菜单栏 的子节点必须要有 唯一的index值 -->
                                             <!-- 默认el-menu-item的 index 使用func_key,这个很重要 -->
                                            <!-- 默认el-submenu的 index 使用func_id,因为要求string型,所以
                                                 toString,这个保证index是唯一的就行 -->
     <el-menu-item v-if="item.func_key" :index="item.func_key" :key="item.func_key" >
         <i class="el-icon-menu"></i>
         <span v-text="item.func_name" slot="title" ></span> <!-- 不要 漏掉slot -->
     </el-menu-item>
     <el-submenu v-else :index="item.func_id.toString()" :key="item.func_id" >
       <template slot="title">
         <i class="el-icon-setting"></i>
         <span v-text="item.func_name"></span>
       </template>
           <!-- 套一层template用于判断是否有子集 -->
       <template v-if="item.children">
           <!-- 这里是确定只有两级,确定使用该标签才直接用该标签v-for --
       >
         <el-menu-item v-for="item2 in item.children" :index="item2.func_key" :key="item2.func_id" >
             <i class="el-icon-menu"></i>
             <span v-text="item2.func_name" slot="title" ></span>
          </el-menu-item>
       </template>
     </el-submenu>
 </template>
 </el-menu>
 activeFuncKey: "", // 记录菜单当前被激活的index
 methods: {
   menuSelectHandler(index,indexPath) {
   this.activeFuncKey = index; // 赋值     
 // index 返回的是当前被激活菜单的index值
 // indexPath返回的是当前被激活菜单的index值,以及其父级的index值组成 的对象
 }
 }

二、实现选项卡内容: element-ui  

   1.首先要 v-show/value 两种情况实现 同步渲染和异步渲染

   选项卡静态代码书写

 1  1 @vue/cli
 2  2 1.作用:是一个搭建vue的开发环境的脚手架工具包(脚手架工具包一般全局安装   就相当于准备工作)
 3  3 2.安装:npm install -g @vue/cli或者yarn global add @vue/cli
 4  4 3.验证是否安装成功: vue -V输出@vue/cli版本号标识成功;
 5  5 4.使用@vue/cli提供的全局命令vue快速搭建vue开发环境
 6  6 5.vue create项目名称
 7  7 注意事项:项目名字不能包含中文和大写字母,能包含数字,小写字母,中杠,下杠,数字不能打头;这个命令一定要注意当前执行的上下文路径、
 8  8 yarn config set registry https://registry.npm.taobao.org -g设置镜像地址,保证下载速度    //这句话是为了更好的下载第三方文件。
 9  9 Webstore:自动生成项目目录介绍
10 10 Src:是我们程序员写代码得地方 是核心
11 11 Src文件夹下的 -main.js文件: 整个项目应用程序的的入口文件
12 12 5.进入项目目录执行yarn serve启动项目,开发调试;
13 13 6.修改src中的代码无需反复在cmd窗口中执行yarn serve,如果修改了src以外的文件,要注意一定要停止当前正在运行得yarn serve,然后再去执行
14 14 7.在根组件导出时候要用export default {
15 15 用到的数据
16 16 }

 ajax 发送 的情况简写

 1 this.$http(配置)
 2     .then(function(promise携带的数据){
 3           做想做任何事情    
 4 })
 5 
 6 //es6  
 7 generate function*(){
 8       let data = yeild this.$http(配置);
 9       //想做的事情  用data 进行直接赋值
10 }    

async/await 的本质是es6中generate * 的简写,是一种 “语法糖”

  await 一定出现在 async修饰的函数中  async中一定有 await吗? 不一定。

es7
async function(){ let data = await this.$http(配置); //直接data 进行赋值 不需要写then了 }
举例说明:
 1   login(model){
 2                                this.$refs[model].validate(async (valid) => {
 3                                        if (valid) {
 4                                                let token = await this.$http({
 5                                                        url:"/user/login",
 6                                                        method:'post',
 7                                                        data:this.model
 8                                                });
 9                                                sessionStorage.setItem("token",token);
10                                                sessionStorage.setItem('user_name', this.model.user_name);
11                                                this.$router.replace('/home');
12                                        } else {
13                                                console.log('error submit!!');
14                                                return false;
15                                        }
16                                });
17 
18                         }

 

horizontal  :水平      

vertical: 垂直

 

推荐阅读