vue完整项目开发流程

news/2024/7/10 0:36:19 标签: vue

vue完整项目开发流程

  • 1.创建项目,初始化项目
  • 2.配置多环境变量
  • 3.配置全局sass
  • 4.封装axios
  • 5.封装vuex
  • 6.按需引入我们需要的框架,(移动端:vant-ui)(后台管理:element-ui)
  • 7.路由封装
  • 8.封装组件
  • 9.代码优化:节流防抖,函数防抖,图片懒加载,keep-alive缓存不活动的组件
  • 10.打包上线

前言:

项目优化后最核心的是:之前是10mb,压缩好以后缩小到几百kb

1.创建项目,初始化项目

  • 首先:开发这个项目我用的是vue脚手架3.0
  • 项目搭建好以后,我们需要初始化项目,安装需要的插件
  • 我们常用的有:axios(请求)、框架(后台管理系统安装element-ui,移动端安装vant),vuex-persistedstate(数据持久化插件),前期我们先安装这几个,后面根据项目的需要,在安装需要的插件

2.配置多环境变量

1.首先我们需要在根目录下创建三个.env的文件,根据环境的不同,配置不同的VUE_APP_ENV

  • .env.development.js文件:开发环境
NODE_ENV='development'
# must start with VUE_APP_ 
VUE_APP_ENV = 'development'
  • .env.staging文件:测试环境
NODE_ENV='staging'
# must start with VUE_APP_
VUE_APP_ENV = 'staging'
  • .env.production.js:文件:生产环境
NODE_ENV='production'
# must start with VUE_APP_
VUE_APP_ENV = 'production'

2.在src根目录下面,创建一个config的文件,里面创建四个文件:
env.development.js(定义开发环境)、env.production.js(定义生产环境)、env.staging.js(定义测试环境),index.js(根据环境的不同,引入不同配置,process.env.VUE_APP_ENV),config这个文件夹下面创建的env的文件,必须要跟上面三个.env的文件名一致

  • env.development.js文件:定义开发环境的公共路径(baseURL)、不同环境的(cdn加速)、不同环境图片的前缀路径
// 本地环境配置
module.exports = {
  title: 'backstage',
  baseUrl: 'http://120.53.31.103:84/api', // 项目地址
  baseApi: 'https://test.xxx.com/api', // 本地api请求地址,注意:如果你使用了代理,请设置成'/'
  APPID: 'xxx',
  APPSECRET: 'xxx',
  $cdn: 'https://gimg2.baidu.com'
}
  • env.staging.js文件:定义测试环境的公共路径(baseURL)、不同环境的(cdn加速)、不同环境图片的前缀路径
// 测试环境
module.exports = {
  title: 'backstage',
  baseUrl: 'https://www.xxx.com/', // 正式项目地址
  baseApi: 'https://www.xxx.com/api', // 正式api请求地址
  APPID: 'xxx',
  APPSECRET: 'xxx',
  $cdn: 'https://www.sunniejs.cn/static'
}
  • env.production.js文件:定义开发环境的公共路径(baseURL)、不同环境的(cdn加速)、不同环境图片的前缀路径
// 生产环境
module.exports = {
  title: 'backstage',
  baseUrl: 'https://www.xxx.com/', // 正式项目地址
  baseApi: 'https://www.xxx.com/api', // 正式api请求地址
  APPID: 'xxx',
  APPSECRET: 'xxx',
  $cdn: 'https://www.sunniejs.cn/static'
}

3.配置全局sass

  • 首先需要安装两个插件
npm install --save-dev sass-loader
npm install --save-dev node-sass

2.在assets这个文件夹下面创建一个css文件,在里面创建三个文件,index.scss文件,默认样式,清楚元素初始的样式,mixin.js文件:里面定义一些公用的代码块,variables.scss文件:里面定义全局样式变量,最后要把后面这两个文件引入到index.js这个文件里面

  • index.scss:定义默认样式,清楚元素初始的样式
@import './variables.scss';
@import './mixin.scss';
body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,blockquote,th,td{margin:0;padding:0}html,body,#app{width:100vw;height:100vh}ul,ol{list-style:none}a{text-decoration:none;color:#333333}a,span{vertical-align:top}img{border:0;vertical-align:middle}input,button,text{vertical-align:top;outline:none;border:none}button{padding:0;background:none;cursor:pointer}button::-moz-focus-inner{padding:0}textarea{outline:none;border:none;resize:none}input,textarea{box-sizing:content-box;outline:none;background:0 0;font-family:"Microsoft YaHei"}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#acacac}input:-moz-placeholder,textarea:-moz-placeholder{color:#acacac}input::-moz-placeholder,textarea::-moz-placeholder{color:#acacac}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#acacac}table tr td,table{border-collapse:collapse}body{font-size:16px;color:#000;font-family:"Microsoft YaHei"}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:"";line-height:0}.clearfix:after{clear:both}.lf{float:left}.rt{float:right}.db{display:inline-block}.mt10{margin-top:10px}.mt15{margin-top:15px}.mt20{margin-top:20px}.mr5{margin-right:5px}.mr10{margin-right:10px}.mr15{margin-right:15px}.mr20{margin-right:20px}.centerWidth{max-width:7.5rem;margin:0 auto}
  • mixin.scss:定义公共样式
// mixin
// 清除浮动
@mixin clearfix {
  &:after {
    content: "";
    display: table;
    clear: both;
  }
}
 
// 多行隐藏
@mixin textoverflow($clamp:1) {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  -o-text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: $clamp;
  /*! autoprefixer: ignore next */
  -webkit-box-orient: vertical;
}

//flex box
@mixin flexbox($jc:space-between, $ai:center, $fd:row, $fw:nowrap) {
  display: flex;
  display: -webkit-flex;
  flex: 1;
  justify-content: $jc;
  -webkit-justify-content: $jc;
  align-items: $ai;
  -webkit-align-items: $ai;
  flex-direction: $fd;
  -webkit-flex-direction: $fd;
  flex-wrap: $fw;
  -webkit-flex-wrap: $fw;
}
  • variables.scss:定义全局样式变量
// variables
$background-color: #f8f8f8;
  1. 在根目录下创建一个vue.config.js文件,在抛出的对象里面写入以下代码
css: {
    extract: IS_PROD, // 是否将组件中的 CSS 提取至一个独立的 CSS 文件中 (而不是动态注入到 JavaScript 中的 inline 代码)。
    sourceMap: false,
    loaderOptions: {
      scss: {
        // 向全局sass样式传入共享的全局变量, $src可以配置图片cdn前缀
        // 详情: https://cli.vuejs.org/guide/css.html#passing-options-to-pre-processor-loaders
        prependData: `
          @import "assets/css/mixin.scss";
          @import "assets/css/variables.scss";
          $cdn: "${defaultSettings.$cdn}";
         `
      }
    }
  },

4.最后把index.scss这个文件引入到main,js全局文件里面引入,然后就可以用啦

// 引入全局样式
import '@/assets/css/index.scss'

4.封装axios

  • 好处:axios的封装和api接口的统一管理,其实主要目的就是在帮助我们简化代码和利于后期的更新维护。

  • 第一步:首先在src创建一个api的文件夹,然后创建三个js文件,
    在这里插入图片描述

  • api.js:里面主要统一管理接口

export default {
  // 头部
  HEADER: "/menu/info",
  //登陆
  LOGIN:"/adminUser/login",
  }
  • http.js:里面主要封装的是核心文件,用params封装request,设置请求拦截和响应拦截,在请求拦截里面我们可以设置请求头,设置loading动画,在响应拦截里面我们可以根据后台返回的状态码,对不同的状态码做一些操作,最后设置不同的请求方式,我一般设置的请求方式有get、post、put,等需要其它的时候,在封装也可以
import axios from 'axios';
import { Message, Loading } from 'element-ui';
import _ from 'lodash';
import { baseUrl } from '@/config';
import store from '@/store'
import QS from 'qs'

console.log(baseUrl)

const request = axios.create({
  baseURL: baseUrl, //设置请求的base url
  timeout: 40000 //超时时长
});

//loading对象
let loading;

//当前正在请求的数量
let needLoadingRequestCount = 0;

//显示loading
function showLoading(target) {
  // 后面这个判断很重要,因为关闭时加了抖动,此时loading对象可能还存在,
  // 但needLoadingRequestCount已经变成0.避免这种情况下会重新创建个loading
  if (needLoadingRequestCount === 0 && !loading) {
    loading = Loading.service({
      lock: true,
      text: 'Loading',
      spinner: 'el-icon-loading',
      background: 'rgba(0, 0, 0, 0.7)',
      target: target || "body"
    });
  }
  needLoadingRequestCount++;
}

//隐藏loading
function hideLoading() {
  needLoadingRequestCount--;
  needLoadingRequestCount = Math.max(needLoadingRequestCount, 0); //做个保护
  if (needLoadingRequestCount === 0) {
    //关闭loading
    toHideLoading();
  }
}

//防抖:将 300ms 间隔内的关闭 loading 便合并为一次。防止连续请求时, loading闪烁的问题。
let toHideLoading = _.debounce(() => {
  loading.close();
}, 300);
//添加请求拦截器
request.interceptors.request.use(config => {
  //判断当前请求是否设置了不显示Loading
  if (config.headers.showLoading !== false) {
    showLoading(config.headers.loadingTarget);
  }
  if (store.state.token || localStorage.getItem('token')) {
    const token = store.state.token || localStorage.getItem('token');
    token && (config.headers.authorization = 'Bearer '+token);
  }
  return config;
}, err => {
  //判断当前请求是否设置了不显示Loading
  if (config.headers.showLoading !== false) {
    hideLoading();
  }
  Message.error('请求超时!');
  return Promise.resolve(err);
});


//响应拦截器
request.interceptors.response.use(
  response => {
    //判断当前请求是否设置了不显示Loading(不显示自然无需隐藏)
    if (response.config.headers.showLoading !== false) {
      hideLoading();
    }
    if (response.status == 200) {
      return Promise.resolve(response);
    } else {
      Message.error(response.message);
      return Promise.reject(response);
    }
  },
  error => {
    //判断当前请求是否设置了不显示Loading(不显示自然无需隐藏)
    if (error.config.headers.showLoading !== false) {
      hideLoading();
    }
    if (error.response && error.response.data && error.response.data.message) {
      var jsonObj = JSON.parse(error.response.data.message);
      Message.error(jsonObj.message);
    } else {
      Message.error(error.message);
    }
    return Promise.reject(error);
  }
);


export default {
  /**
 * get方法,对应get请求
 * @param {String} url [请求的url地址]
 * @param {Object} params [请求时携带的参数]
   */
  get(url, data) {
    let params = data || ''
    return new Promise((resolve, reject) => {
      request
        .get(url, params)
        .then(res => {
          resolve(res.data)
        })
        .catch(err => {
          reject(err.data)
        })
    })
  },

  /**
 * post方法,对应post请求
 * @param {String} url [请求的url地址]
 * @param {Object} params [请求时携带的参数]
   */
  post(url, data) {
    let params = data || ''
    return new Promise((resolve, reject) => {
      request
        .post(url, QS.stringify(params))
        .then(res => {
          resolve(res.data)
        })
        .catch(err => {
          reject(err.data)
        })
    })
  },
  /**
 * upload方法,对应upload请求
 * @param {String} url [请求的url地址]
 * @param {Object} params [请求时携带的参数]
   */
  upload(url, data) {
    let params = data || ''
    return new Promise((resolve, reject) => {
      request
        .upload(url, QS.stringify(params))
        .then(res => {
          resolve(res.data)
        })
        .catch(err => {
          reject(err.data)
        })
    })
  },

  /**
 * download方法,对应download请求
 * @param {String} url [请求的url地址]
 * @param {Object} params [请求时携带的参数]
   */
  download(url, data) {
    let params = data || ''
    return new Promise((resolve, reject) => {
      request
        .download(url, QS.stringify(params))
        .then(res => {
          resolve(res.data)
        })
        .catch(err => {
          reject(err.data)
        })
    })
  },
  /**
 * put方法,对应put请求
 * @param {String} url [请求的url地址]
 * @param {Object} params [请求时携带的参数]
   */
  put(url, data) {
    let params = data || ''
    return new Promise((resolve, reject) => {
      request
        .put(url, QS.stringify(params))
        .then(res => {
          resolve(res.data)
        })
        .catch(err => {
          reject(err.data)
        })
    })
  },
  /**
 * delete方法,对应delete请求
 * @param {String} url [请求的url地址]
 * @param {Object} params [请求时携带的参数]
   */
  delete(url, data) {
    let params = data || ''
    return new Promise((resolve, reject) => {
      request
        .delete(url, QS.stringify(params))
        .then(res => {
          resolve(res.data)
        })
        .catch(err => {
          reject(err.data)
        })
    })
  }
}
  • index.js:主要定义方法,一个接口对应一个方法,要把前面封装号的两个文件引入到这个文件里面,然后引入到main.js全局文件里面,注册全局
import api from "./api"; // 导入接口域名列表
import http from "./http"; // 导入http中创建的axios实例

export default {
  install(Vue) {
    Vue.prototype.$http = this;
  },
  //头部接口
  HEADER(params = "") {
    return http.post(api.HEADER, params);
  },
  //登陆接口
  LOGIN(params) {
    return http.post(api.LOGIN, params);
  },
  STUDENT(params) {
    return http.get(
      api.STUDENT +
        `?page=${params.page_num}&limit=${params.page_size}&status=${params.status}&nickname=${params.nickname}&mobile=${params.mobile}&`
    );
  },
  //详情接口
  DETAIL(params) {
    return http.get(api.DETAIL + `/${params}?`);
  },
  //禁用接口
  FORBIDDEN(params) {
    return http.put(api.FORBIDDEN + `/${params}`);
  },
  DELETE(params) {
    return http.delete(api.DELETE + `/${params}`);
  },
  //省市区接口
  PROVINCE(id) {
    return http.get(api.PROVINCE + `/${id}`);
  },
  //上传头像接口
  IMG(file) {
    return http.post(api.IMG ,file);
  },
};

vuex_445">5.封装vuex

前言:什么是vuex

  • Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式,相当于是一个仓库,存放公共数据的,任何组件都可以使用存放在仓库里面的数据

1.vuex由五大部分组成

  • state:定义数据,使用方法是通过:this.$store.state.xxx(方法名)
  • actions:可以包含异步操作,使用方法是通过:
    this.$store.dispatch.xxx(方法名)
  • mutations:唯一可以修改state数据的场所,使用方法是通过:this.$store.commit.xxx(方法名)
  • getters:类似于vue组件中的计算属性,对state数据进行计算(会被缓存),使用方法是:this.$store.getters.xxx(方法名)
  • modules:模块化管理store(仓库),每个模块拥有自己的 state、mutation、action、getter

2.下面说下封装vuex的核心

  • 第一步:在src文件夹下面创建store的文件夹,然后在这个文件夹下面创建四个js文件
  • state:定义公共数据
  • actions:操作异步的数据
  • mutations:操作同步的数据,也是唯一一个可以直接改变state里面定义的数据
  • getters:类似于vue组件中的计算属性,对state数据进行计算(会被缓存)
  • index:把前面封装好的文件都引入到这个文件里面,然后抛出
import Vue from 'vue'
import Vuex from 'vuex'
import state from './state';
import mutations from './mutations';
import actions from './actions';
import vuexPersist from "vuex-persist";

Vue.use(Vuex)

export default new Vuex.Store({
  state,
  mutations,
  actions,
  plugins: [
    new vuexPersist({
      storage: window.localStorage,
    }).plugin,
  ],
})

下面说下封装vuex的好处和具体的思路

我们在用vue脚手架3.0创建项目的时候,他会自动帮我们在src这个文件夹下面生成一个store文件夹,下面有一个index.js这个文件,index.js这个文件里面有5个属性,就是我们用vuex的时候,所用到的5个属性,把这5个属性放在同一个文件里面,适合开发中小型项目的时候使用,因为需要公用的数据不多,写在一个文件里面就可以,但是开发一个中大型项目的话,我们需要在vuex里面定义的数据比较多,所以我们就把需要的5个属性拆分出来,拆分成单独的文件,这样能在以后项目的维护,或者修改的时候比较方便,每个文件定义不同的数据,下面我们来分析一下

在这里插入图片描述

  • state:可以把项目中需要定义在state里面的数据,都定义在这个文件里面
  • action:他是一个异步的操作,把项目中异步的请求全部放在这个文件里面,如果要修改state里面定义的数据,必须要通过commit来调用mutations里面的方法,才能修改state里面的数据,不能直接修改,在组件里面需要action里面的数据,可以通过tthis.$store.dispatch+需要调用的方法名来获取
  • mutations:他是一个同步的操作,也是唯一一个可以直接修改state里面定义的数据,可以把项目中同步的数据放在这个文件里面,在组件中需要通过this.$store.commit+需要调用的方法名来获取
  • getters:计算属性,可以把项目中需要计算的数据放在这个文件里面,统一管理,在组建中通过this.$store.getters+调用的方法名可以获取到数据

6.按需引入我们需要的框架,(移动端:vant-ui)(后台管理:element-ui)

-vant-ui:移动端

安装指令

npm i babel-plugin-import -D

  • 在babel.config.js 设置
// 对于使用 babel7 的用户,可以在 babel.config.js 中配置
const plugins = [
  [
    'import',
    {
      libraryName: 'vant',
      libraryDirectory: 'es',
      style: true
    },
    'vant'
  ]
]
module.exports = {
  presets: [['@vue/cli-plugin-babel/preset', { useBuiltIns: 'usage', corejs: 3 }]],
  plugins
}
  • 在src文件夹下面创建一个plugins文件夹,然后下面创建一个index.js文件,里面统一管理我们需要用的组件
// 按需全局引入 vant组件
import Vue from 'vue'
import { Button, List, Cell, Tabbar, TabbarItem } from 'vant'
Vue.use(Button)
Vue.use(Cell)
Vue.use(List)
Vue.use(Tabbar).use(TabbarItem)
  • 然后在main.js全局文件里面引入,抛出,在全局就可以用啦
import './plugins/vant.js'

后台管理系统

注意:必须要在搭建项目以后,别的什么都不操作,都还没有操作的情况下,才能使用,否则安装完别的依赖,在安装下面这个指令的话,就用不了

vue add element

  • 在src文件夹下面创建一个plugins文件夹,然后下面创建一个index.js文件,里面统一管理我们需要用的组件
import Vue from 'vue'
import {
  Pagination,
  Dialog,
  Autocomplete,
  Dropdown,
  DropdownMenu,
  DropdownItem,
  Menu,
  Submenu,
  MenuItem,
  MenuItemGroup,
  Input,
  InputNumber,
  Radio,
  RadioGroup,
  RadioButton,
  Checkbox,
  CheckboxButton,
  CheckboxGroup,
  Switch,
  Select,
  Option,
  OptionGroup,
  Button,
  ButtonGroup,
  Table,
  TableColumn,
  DatePicker,
  TimeSelect,
  TimePicker,
  Popover,
  Tooltip,
  Breadcrumb,
  BreadcrumbItem,
  Form,
  FormItem,
  Tabs,
  TabPane,
  Tag,
  Tree,
  Alert,
  Slider,
  Icon,
  Row,
  Col,
  Upload,
  Progress,
  Badge,
  Card,
  Rate,
  Steps,
  Step,
  Carousel,
  CarouselItem,
  Collapse,
  CollapseItem,
  Cascader,
  ColorPicker,
  Transfer,
  Container,
  Header,
  Aside,
  Main,
  Footer,
  Loading,
  MessageBox,
  Message,
  Notification
} from 'element-ui'

Vue.use(Pagination)
Vue.use(Dialog)
Vue.use(Autocomplete)
Vue.use(Dropdown)
Vue.use(DropdownMenu)
Vue.use(DropdownItem)
Vue.use(Menu)
Vue.use(Submenu)
Vue.use(MenuItem)
Vue.use(MenuItemGroup)
Vue.use(Input)
Vue.use(InputNumber)
Vue.use(Radio)
Vue.use(RadioGroup)
Vue.use(RadioButton)
Vue.use(Checkbox)
Vue.use(CheckboxButton)
Vue.use(CheckboxGroup)
Vue.use(Switch)
Vue.use(Select)
Vue.use(Option)
Vue.use(OptionGroup)
Vue.use(Button)
Vue.use(ButtonGroup)
Vue.use(Table)
Vue.use(TableColumn)
Vue.use(DatePicker)
Vue.use(TimeSelect)
Vue.use(TimePicker)
Vue.use(Popover)
Vue.use(Tooltip)
Vue.use(Breadcrumb)
Vue.use(BreadcrumbItem)
Vue.use(Form)
Vue.use(FormItem)
Vue.use(Tabs)
Vue.use(TabPane)
Vue.use(Tag)
Vue.use(Tree)
Vue.use(Alert)
Vue.use(Slider)
Vue.use(Icon)
Vue.use(Row)
Vue.use(Col)
Vue.use(Upload)
Vue.use(Progress)
Vue.use(Badge)
Vue.use(Card)
Vue.use(Rate)
Vue.use(Steps)
Vue.use(Step)
Vue.use(Carousel)
Vue.use(CarouselItem)
Vue.use(Collapse)
Vue.use(CollapseItem)
Vue.use(Cascader)
Vue.use(ColorPicker)
Vue.use(Container)
Vue.use(Header)
Vue.use(Aside)
Vue.use(Main)
Vue.use(Footer)

Vue.use(Loading.directive)

Vue.prototype.$loading = Loading.service
Vue.prototype.$msgbox = MessageBox
Vue.prototype.$alert = MessageBox.alert
Vue.prototype.$confirm = MessageBox.confirm
Vue.prototype.$prompt = MessageBox.prompt
Vue.prototype.$notify = Notification
Vue.prototype.$message = Message

  • 最后也是在main.js全局文件里面引入,然后抛出就可以啦
import './plugins/element.js'

7.路由封装

前言:大家都知道,我们在搭建好项目以后,src文件夹下面会生成一个router这个文件夹,然后下面有一个index.js这个文件,这个里面就是我们做项目需要放路由的地方,如果我们的项目比较大,跳转的页面比较多的话,把全部的路由都放在这一个文件里面,后期优化不好优化,在做项目的时候需要找路由的时候也不好找,或者说在后期我们需要改路由的时候也不好改,所以我们就选择路由封装是最好不过的啦。。。注意:如果项目比较小,跳转的页面不是很多的情况下,就没必要封装路由

下面说下路由封装的思路,这个很简单,大家一看就会

  • 我一般在做项目时候,遇到跳转页面多的时候呢,我会把路由分成几个文件来封装,比如现在我做的这个后台管理系统,有10个页面,每个页面里面肯定有很多需要跳转的页面,这时候我会在router这个文件夹下面创建10个文件,然后每个文件对应一个页面,比如现在首页的这个页面,就在router这个文件夹下面创建一个home.js文件,然后把首页需要跳转的的路由全部写在这个文件里面,然后把他引入到index.js这个文件里面就可以啦,这样呢,在做项目,或者以后优化的时候就比较好找,如果以后我们要优化项目,需要优化首页的时候,在我们需要优化首页这个页面路由的时候,我们就可以去home.js这个文件里面去找就可以啦

8.封装组件

前言:大家都知道,vue项目都是单页面,都是组件拼接起来的,如果说我们在做中大型项目的时候,页面比较多,如果我们把这些页面都写在一个文件里面,就比较麻烦,修改的时候、找的时候、或者在优化项目的时候找起来比较麻烦,所以我们就把页面分成一个一个的组件,封装起来,然后引入到渲染的页面,这样的话,在我们写项目、修改。以后优化项目的时候,就比较方便

封装组件的话分为两种

  • 一个是页面组件的封装
  • 一个是公共组件的封装

9.代码优化:节流防抖,函数防抖,图片懒加载,keep-alive缓存不活动的组件

10.打包上线


http://www.niftyadmin.cn/n/1836058.html

相关文章

lnmp1.5一键安装包 访问thinkphp项目public目录下的index.php 提示500服务器错误问题

php版本是 7.1.18 mysql是5.5.60 swoole是4.0.0 redis是4.0版本 phpmyadmin 是4.4.15.6 tp5.1.16 运行正常 目前在centos 7.3的虚拟机上成功安装了以上软件。 但是其中遇到了一大波坑,大部分都是由于lnmp1.5里面的nginx配置文件引起的问题。 导致了,…

gridview 点击 行页面跳转

前台代码&#xff1a; <asp:GridView ID"GridView1" runat"server" AutoGenerateColumns"False" Width"100%" EmptyDataText" 无" BackColor"White" BorderColor"#CC9966" BorderStyle"None&qu…

【前端框架之Bootstrap01】我们一起来看看这个家伙是什么

前言 我感觉自己的眼界没有打开&#xff0c;关注的东西前前后后都是那么几样&#xff0c;诚然不精一门何以精前端&#xff0c;但是对前端新技术的关注还是需要的&#xff0c;就拿我们今天要说到的。 bootstrap&#xff0c;说实话&#xff0c;知道的或者说用过的人肯定不多&…

安装lnmp1.5到最后出现Error: MySQL install failed的解决方法

mv /usr/bin/cmake /usr/bin/cmake.backup wget http://www.cmake.org/files/v3.0/cmake-3.0.2.tar.gz tar zxf cmake-3.0.2.tar.gz cd cmake-3.0.2 ./configure gmake make && make install ln -sf /usr/local/bin/cmake /usr/bin/cmake

如何对给定序列进行趋势预测

1. 趋势预测的定义 趋势预测法又称趋势分析法。是指自变量为时间&#xff0c;因变量为时间的函数的模式。 趋势预测法的主要优点是考虑时间序列发展趋势&#xff0c;使预测结果能更好地符合实际。 2. 如何对给定序列计算趋势 序号 值 1 562 2 345 3 567 4 652 5 249已知以上序列…

关于前端的复制功能

我的标题看起来很大&#xff0c;但我却是纯粹的标题党&#xff0c;所以不要对接下来的内容抱有太大希望&#xff0c;这里只是我的个人笔记本而已&#xff0c;但却总好像是写给别人看的一样&#xff0c;可能写完还会发发微博&#xff0c;但却有忽悠嫌疑。好了&#xff0c;说了这…

ThinkPHP5远程代码执行高危漏洞(附:升级修复解决方法)

漏洞描述 由于ThinkPHP5框架对控制器名没有进行足够的安全检测&#xff0c;导致在没有开启强制路由的情况下&#xff0c;黑客构造特定的请求&#xff0c;可直接GetWebShell。 漏洞评级 严重 影响版本 ThinkPHP 5.0系列 < 5.0.23 ThinkPHP 5.1系列 < 5.1.31 安全版本…

js数据类型、栈堆存储、多数据类型计算

js数据类型、栈堆存储、多数据类型计算 js数据类型有哪些 基本数据类型&#xff08;值类型&#xff09;&#xff1a; Number、String、Boolean、Undefined、Null、Symbol&#xff08;es6新增独一无二的值&#xff09; 和 BigInt&#xff08;es10新增&#xff09;&#xff1b; …