zoukankan      html  css  js  c++  java
  • VUE起步

    image

    1、环境准备

    # 1. 官网下载node.js
        http://nodejs.cn/download/
    # 2. 配置node.js环境变量
        windows系统:环境变量添加以下配置
        	NODE_HOME = nodejs安装目录
        	PATH = %NODE_HOME%/bin
    # 3. 验证nodejs是否安装成功
        node -v
    # 4. npm简单介绍
        node package manager nodejs包管理工具
        maven 	管理java后端依赖 远程仓库(中心仓库) 阿里云镜像
    	npm		管理前端系统依赖远程仓库(中心仓库)   配置淘宝镜像
    # 5.配置淘宝镜像
    	配置淘宝镜像
    	npm config set registry https://registry.npm.taobao.org
    	验证是否设置成功
    	npm config get registry
    # 6.配置全局修改npm下载依赖配置
    	npm config set cache "D:java
    odeJS
    ode_modules
    pm-repo
    pm-cache"
    	npm config set prefix "D:java
    odeJS
    ode_modules
    pm-repo
    pm_global"
    	修改完成之后,再次npm config ls 就会看到变化。而且.npmrd文件也会有变化,这个文件在C盘的用户目录下,比如C:UsersAdministrator。
    	
    # 7.检测node.js环境配置
    	查看npm当前配置 npm config ls -l
    

    2、安装nodejs脚手架

    # 0、卸载@vue/cli脚手架命令
    	npm uninstall -g @vue/cli
    # 1、vue cli 官网
    	https://cn.vuejs.org/
    # 2、安装 vue-cli  版本2
    	npm install -g vue-cli	
    # 3、安装 @vue/cli 版本3
    	npm install -g  @vue/cli
    

    3、创建第一个vue脚手架项目

    初始化

    # 1、创建第一个脚手架项目
    	vue init webpack 项目名
    # 2、理解开发方式,一切皆组件
    	js、css、html
    	开发一个一个xxx.vue(组件),将多个组件组合成前端框架系统
    

    D:java odeJS ode_modules pm-repo pm_globalvue.cmd

    在intellij中开发vue

    • intellij插件商店下载Vue.js插件
    • 配置node服务器启动命令

    vue项目初始结构目录及作用

    4、如何开发vue脚手架

    vue-cli项目中一切皆组件

    • 组件中的MVVM

    main.js主入口

    • 一个常规组件
    <template>
      <div>
        <h1>用户模块</h1>
        <h1>内容</h1>
        <table border="1">
          <tr>
            <td>id</td>
            <td>name</td>
            <td>age</td>
            <td>操作</td>
            <td></td>
          </tr>
          <!--循环-->
          <tr v-for="user in users">
            <!--第一种方式取值-->
            <td v-text="user.id"></td>
            <!--第二种方式取值-->
            <td>{{user.name}}</td>
            <td>{{user.age}}</td>
            <td><a href="">删除</a>&nbsp;&nbsp;<a href="">修改</a></td>
          </tr>
        </table>
        <!--使用导入的组件-->
        <Footer></Footer>
      </div>
    </template>
    <script>
        import Footer from "./Footer";  // 导入Footer公共页脚组件
        export default {  // 导出默认组件
            name: "User",  // 组件名称
            data() { // 当前组件拥有数据
                return {
                    users: [
                        {id: 1, name: '李小龙', age: 18},  // 伪造的数据
                        {id: 2, name: '卡特玲娜', age: 0}  // 伪造的数据
                    ]
                }
            },
            methods: {}, // 当前组件拥有的方法
            components: {  // 在当前组件中祖册其它组件
                Footer
            },
            created() { // created生命周期,通过执行axios的API与后端springboot接口通信获得数据到data上
            }
        }
    </script>
    <style scoped>
    /*scoped:表示样式只在当前组件中起作用*/
    </style>
    
    • 路由文件:router/index.js
    import Vue from 'vue'
    import Router from 'vue-router'
    import Home from "../components/Home";
    import User from "../components/User";
    import Student from "../components/Student";
    Vue.use(Router)  // 全局Vue实例注册Router路由
    
    export default new Router({
      mode:'history',  //  去掉路径前的#
      routes: [// 为组件配置路由映射路径
        {path: '/',redirect:"/home"}, // 重定向
        {path: '/home', name: 'Home', component: Home},
        {path: '/user', name: 'User', component: User},
        {path: '/student', name: 'Student', component: Student}
    
      ]
    })
    
    • 在脚手架中使用axios异步通信库
    # 1.安装axios
    	npm install axios --save -dev
    # 2.配置main.js,引入axios
    	import axios from "axios";
    	Vue.prototype.$http=axios; // 修改vue内部的$http(异步)为axios(异步)
    # 3.使用axios
    	在需要发送异步请求的位置使用:
    	this.$http.get("url").then((res)=>{}),
    	this.$http.post("url").then((res)=>{})发送异步请求
    # 4.接口模拟平台
    	提供自定义访问接口,返回预期数据
    	http://rap2.taobao.org/account/login
    
    • VUE-CLI 脚手架项目打包和部署
    # 1.在package.json的同级目录下,执行
    	npm run build
    	vue脚手架打包的项目必须在服务器上运行,不能双击运行
    # 2.打包之后项目中的变化
    	dist目录就是vue脚手架的生产目录,将其复制到服务器直接部署
    # 3.注意
    	如果vue前端系统路径采用的是model:history模式,不带#的路径模式,可能出现找不到路径的情况
    

    Vue项目build后,图片加载不出来解决方案

    vue项目,build之后会对图片进行处理,具体处理的方式是在文件webpack.base.conf.js中,有如下代码:

    module: {
        rules: [
         {
            test: /.(png|jpe?g|gif|svg)(?.*)?$/,
            loader: 'url-loader',
            options: {
              limit: 10000, // 1k-----限制文件的大小
              name: utils.assetsPath('img/[name].[hash:7].[ext]')
            }
         }
        ]
    }
    

    以上代码中,使用url-loader对图片的大小进行限制,在limit之内,webpack会将图片转化为base64,超出limit限制,交给file-loader处理。如果在limit范围之内,不会出现图片加载不出来的情况;
    超出limit,webpack会将处理后的图片放在dist/static/img/中,此时加载图片将会显示不出来。

    具体做法如下:
    1、在config/index.js文件内,修改代码: (列出index.js的部分代码)

    assetsPublicPath字段值由之前的'/'改为'./';

    build: {
        // Template for index.html
        index: path.resolve(__dirname, '../dist/index.html'),
        // Paths
        assetsRoot: path.resolve(__dirname, '../dist'),
        assetsSubDirectory: 'static',
        assetsPublicPath: './', 
    }
    

    2、在webpack.prod.conf.js文件内,output字段,添加代码(publicPath: './'):

    output: {
        publicPath: './', // 添加的代码
        path: config.build.assetsRoot,
        filename: utils.assetsPath('js/[name].[chunkhash].js'),
        chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
      },
    

    3、在utils.js文件里添加 publicPath:'../../',代码如下:

    // (which is the case during production build)
    if (options.extract) {
      return ExtractTextPlugin.extract({
        use: loaders,
        fallback: 'vue-style-loader',
        publicPath: '../../'  // 添加的代码
      })
    } else {
      return ['vue-style-loader'].concat(loaders)
    }
    

    以上步骤操作完后,执行命令:npm run build
    在build后,dist中的index.html页面的link、script标签的引入路径变为相对路径;同时,相关的图片路径,也变变为相对路径,此时部署项目,不再出现图片路径404。

    Element UI 起步

    • 掌握vue,vue脚手架的基本知识

    • 初始化一个前端vue脚手架项目

    • 项目安装Element UI

    # 1、下载element-UI依赖到当前项目中
    	npm i element-ui -S
    # 2、指定当前项目使用element-ui依赖
    	main.js配置导入。
    	import ElementUI from 'element-ui';
    	import 'element-ui/lib/theme-chalk/index.css';
    	
    	
    	// 声明(注册)在当前vue脚手架项目使用element-ui
    	Vue.use(ElementUI)
    

    src源码

    • main.js
    import Vue from 'vue'  // 导入vue
    import App from './App'  // 导入根组件
    import router from './router'  // 导入路由
    import ElementUI from 'element-ui'; // 导入elementUI
    import 'element-ui/lib/theme-chalk/index.css'; // 导入样式
    import axios from "axios"; // 导入axios通信模块
    
    Vue.prototype.$http = axios; // 修改vue内部的$http(异步)为axios(异步)通信机制
    
    
    Vue.config.productionTip = false // 浏览器console控制台提示
    
    Vue.use(ElementUI) // 注册elementUI
    
    new Vue({
      el: '#app',  // vue接管根挂载点
      router,   // 路由组件
      components: {App},
      template: '<App/>'
    })
    
    • index.js
    import Vue from 'vue'  // 导入全局vue
    import Router from 'vue-router'
    import Index from "../components/Index"; // 导入首页
    import List from "../components/user/List"; // 导入用户列表页
    
    
    // 注册路由
    Vue.use(Router)
    
    export default new Router({
      routes: [ // 路由规则列表
        {path: "/", redirect: "/index"},
        {path: "/index", name: "Index", component: Index},
        {path: "/users", name: "users", component: List},
      ]
    })
    
    
    • App.vue
    <template>
      <div id="app"><!--根挂载点-->
        <el-container><!--el容器-->
          <el-header><!--容器头部-->
            <!--导航栏菜单-->
            <el-menu :default-active="activeIndex" class="el-menu-demo" mode="horizontal" @select="handleSelect">
              <el-menu-item index="/index">主页</el-menu-item>
              <el-menu-item index="/users">用户管理</el-menu-item>
              <el-menu-item index="/msgs">消息中心</el-menu-item>
              <el-menu-item index="/orders">订单管理</el-menu-item>
            </el-menu>
          </el-header>
          <el-main><!--容器主体部分-->
            <router-view/><!--路由控制视图变化的区域-->
          </el-main>
        </el-container>
      </div>
    </template>
    
    <script>
    export default {  // 配置导出
      name: 'App',   // 组件命名
      data() { // 数据
        return {
          activeIndex: this.$route.path,  // 激活连接下划蓝线标识
        };
      },
      methods: {  // 方法
        handleSelect(key, keyPath) {  // 绑定事件:点击菜单
          console.log(key, keyPath);
          this.$router.push(key) // 跳转视图
        }
      }
    }
    </script>
    <style>
    </style>
    
    • Index.vue
    <template>
      <el-carousel indicator-position="outside"><!--跑马灯-->
        <el-carousel-item v-for="item in imgs" :key="item"><!--遍历图片-->
          <el-image :src="item" style="height: 100%;  100%" fit="fill"><!--设置样式-->
          </el-image>
        </el-carousel-item>
      </el-carousel>
    </template>
    
    <script>
    // 导入组件
    import homeImg1 from '../assets/indeximages/1.jpg';
    import homeImg2 from '../assets/indeximages/2.jpg';
    import homeImg3 from '../assets/indeximages/3.jpg';
    import homeImg4 from '../assets/indeximages/4.jpg';
    import homeImg5 from '../assets/indeximages/5.jpg';
    import homeImg6 from '../assets/indeximages/6.jpg';
    import homeImg7 from '../assets/indeximages/7.jpg';
    import homeImg8 from '../assets/indeximages/8.jpg';
    import homeImg9 from '../assets/indeximages/9.jpg';
    
    export default {
      name: "Index",
      data() {
        return {imgs: [homeImg1,homeImg2,homeImg3,homeImg4,homeImg5,homeImg6,homeImg7,homeImg8,homeImg9,]}
      }
    }
    </script>
    <style scoped>
    </style>
    
    • /user/List.vue
    <template>
      <div>
        <!--遍历展示数据-->
        <el-table
          :data="tableData.filter(data => !search || data.name.toLowerCase().includes(search.toLowerCase()))"
          style=" 100%">
          <!--编号列-->
          <el-table-column
            label="编号"
            width="180">
            <template slot-scope="scope">
              <p>{{ scope.row.id }}</p>
            </template>
          </el-table-column>
          <!--姓名列-->
          <el-table-column
            label="姓名"
            width="180">
            <template slot-scope="scope">
              <el-tag size="medium">{{ scope.row.name }}</el-tag>
            </template>
          </el-table-column>
          <!--生日-->
          <el-table-column
            label="生日"
            width="180">
            <template slot-scope="scope">
              <i class="el-icon-potato-strips"></i>
              <span style="margin-left: 10px">{{ scope.row.bir }}</span>
            </template>
          </el-table-column>
          <!--性别-->
          <el-table-column
            label="性别"
            width="180">
            <template slot-scope="scope">
              <p>{{ scope.row.sex }}</p>
            </template>
          </el-table-column>
          <!--搜索查找-->
          <el-table-column
            align="right">
            <template slot="header" slot-scope="scope">
              <el-input
                v-model="search"
                size="mini"
                placeholder="输入姓名关键字搜索"/>
            </template>
          </el-table-column>
          <!--修改、删除操作-->
          <el-table-column>
            <template slot-scope="scope">
              <el-button
                size="mini"
                @click="handleEdit(scope.$index, scope.row)">编辑
              </el-button>
              <el-button
                size="mini"
                type="danger"
                @click="handleDelete(scope.$index, scope.row)">删除
              </el-button>
            </template>
          </el-table-column>
        </el-table>
    
        <!--分页条-->
        <div class="block" style="text-align: center">
          <el-pagination
            layout="prev, pager, next,jumper,total,sizes"
            :total="total"
            :page-sizes="[1,2, 4, 6, 8]"
            :page-size="2"
            prev-text="上一页"
            next-text="下一页"
            background
            @size-change="changeSize"
            @current-change="changePage"
            @prev-click="preClick"
            @next-click="nextClick"
          >
          </el-pagination>
        </div>
    
        <!--添加按钮-->
        <el-button type="success" size="mini" style="margin-top: 20px" @click="add">添加</el-button>
    
        <!--添加保存用户表单-->
        <transition name="el-zoom-in-center">
          <div v-show="show" class="transition-box">
    
            <el-form required :rules="rules" ref="userForm" :model="form" label-suffix=":" label-width="80px">
              <!--表单id项-->
              <el-form-item hidden>
                <el-input v-model="form.id" class="inputSize"></el-input>
              </el-form-item>
              <!--表单name项-->
              <el-form-item label="用户姓名" prop="name" label-width="100px">
                <el-input v-model="form.name" class="inputSize"></el-input>
              </el-form-item>
              <!--表单bir项-->
              <el-form-item label="生日" label-width="100px" prop="bir">
                <el-date-picker type="date" placeholder="选择日期" v-model="form.bir" class="inputSize">
                </el-date-picker>
              </el-form-item>
              <!--表单sex项-->
              <el-form-item label="性别" label-width="100px" prop="sex">
                <el-radio-group v-model="form.sex">
                  <el-radio label="男"></el-radio>
                  <el-radio label="女"></el-radio>
                </el-radio-group>
              </el-form-item>
              <!--表单address项-->
              <el-form-item label="用户地址" label-width="100px" prop="address">
                <el-input v-model="form.address" class="inputSize"></el-input>
              </el-form-item>
              <!--表单操作项-->
              <el-form-item label-width="350px">
                <el-button type="primary" @click="onSubmit('userForm')">保存用户信息</el-button>
                <el-button @click="resetForm('userForm')">重置</el-button>
              </el-form-item>
            </el-form>
          </div>
        </transition>
      </div>
    </template>
    
    <script>
    export default {
      name: "List",
      data() {
        return {
          tableData: [], //展示用户信息数据表
          search: '', // 搜索
          total: 0,
          pageNow: 1,
          pageSize: 2,
          show: false, // 控制添加,修改表单标志位
          form: {  // 添加、修改绑定数据
            id: '',
            name: '',
            bir: '',
            sex: '男',
            address: ''
          },
          rules: {  // 表单验证规则
            name: [
              {required: true, message: '请输入用户名称', trigger: 'blur'}, // 没输入数据时失去焦点提示信息
              {min: 2, max: 10, message: '长度在 2 到 10 个字符', trigger: "blur"}],
            bir: [{required: true, message: '请输入用户生日', trigger: 'blur'}],
            sex: [{required: true, message: '请输入用户性别', trigger: 'blur'}],
            address: [{required: true, message: '请输入用户地址', trigger: 'blur'}]
          }
        }
      },
      methods: {
        handleEdit(index, row) {
          console.log(index, row);
          this.show = true
          this.form = row;
    
          this.$http.post("http://localhost:8989/user/del", row).then((resp => {
            if (resp.data == "success") {
              this.$message({message: "修改成功", type: "success"});
              this.findAll();
            } else {
              this.$message.error('修改失败');
            }
          }))
        },
        handleDelete(index, row) {
          console.log(index, row);
          console.log(row.id)
          this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
          }).then(() => {
            this.$http.post("http://localhost:8989/user/del", new String(row.id)).then((res) => {
              if (res.data == "success") {
                this.$message({message: "删除成功", type: "success"});
                this.findAll();
              } else {
                this.$message.error('删除失败');
              }
            });
          })
        },
        changePage(page) {
          this.pageNow = page
          this.findAll()
          console.log(page)
        },
        changeSize(pageSize) {
          this.pageSize = pageSize
          this.findAll()
          console.log(pageSize)
        },
        preClick(pageChange) {
          this.pageNow = pageChange
          this.findAll()
          console.log(pageChange)
        },
        nextClick(pageChange) {
          this.pageNow = pageChange
          this.findAll()
          console.log(pageChange)
        },
        resetForm(userForm) {
          this.$refs[userForm].resetFields();
          this.show = true
          this.form = {sex: '男'};
        },
        add() {
          this.show = !this.show
          this.form = {sex: '男'};
        },
        onSubmit(userForm) {
          this.$refs[userForm].validate((valid) => {
            if (valid) {
              if (this.form.id) {
                this.$confirm('是否确认要更新该用户信息', '提示', {
                  cancelButtonText: '取消',
                  confirmButtonText: '确定',
                  type: 'warning'
                }).then(() => {
                  this.$http.post("http://localhost:8989/user/update", this.form).then((response) => {
                    console.log(response.data);
                    if (response.data == "success") {
                      this.$message({
                        message: '更新成功',
                        type: 'success'
                      });
                      //  清除表单信息
                      this.show = false;
                      this.findAll();
                    } else {
                      this.$message.error('更新失败');
                    }
                  });
                })
              } else {
                this.$http.post("http://localhost:8989/user/save", this.form).then((response) => {
                  console.log(response.data);
                  if (response.data == "success") {
                    this.$message({
                      message: '添加成功',
                      type: 'success'
                    });
                    //  清除表单信息
                    this.form = {sex: '男'};
                    this.show = false;
                    this.findAll();
                  } else {
                    this.$message.error('添加失败');
                  }
                });
              }
            } else {
              this.$message.error('输入的表单信息不合法');
              return false;
            }
          });
        },
        findAll() {
          var url = "http://localhost:8989/user/findByPage"
          if (this.pageNow && this.pageSize) {
            url = url + "?pageNow=" + this.pageNow + "&pageSize=" + this.pageSize;
          } else if (this.pageNow) {
            url = url + "?pageNow=" + this.pageNow
          } else if (this.pageSize) {
            url = url + "?pageSize=" + this.pageSize
          }
          this.$http.get(url).then((response) => {
            this.tableData = response.data.users
            this.total = response.data.countUsers
          });
        }
      },
      created() {
        this.findAll()
      },
    };
    
    </script>
    
    <style scoped>
    /*添加、修改用户表单样式*/
    .transition-box {
      margin-bottom: 10px;
       100%;
      height: 300px;
      border-radius: 4px;
      padding: 40px 20px;
      box-sizing: border-box;
      margin-right: 20px;
    }
    
    /*表单输入框大小,还可以用栅格处理*/
    .inputSize {
       100%;
    }
    </style>
    
    

    效果展示

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利
  • 相关阅读:
    贝尔级数
    NOIP2018 退役记
    Codeforces1106F 【BSGS】【矩阵快速幂】【exgcd】
    codeforces1111 简单题【DE】简要题解
    BZOJ4836: [Lydsy1704月赛]二元运算【分治FFT】【卡常(没卡过)】
    BZOJ3771: Triple【生成函数】
    Codeforces 1096G. Lucky Tickets【生成函数】
    Codeforces1099F. Cookies【DP】【线段树】【贪心】【博弈】【沙比提(这是啥算法)】
    Codeforces gym101955 A【树形dp】
    BZOJ3551: [ONTAK2010]Peaks加强版【Kruskal重构树】【主席树】
  • 原文地址:https://www.cnblogs.com/hhddd-1024/p/14364321.html
Copyright © 2011-2022 走看看