zoukankan      html  css  js  c++  java
  • 项目踩坑

    一、vue

    1、v-model实现数据的双向绑定,需要在data中声明初始值,因为v-model 会忽略所有表单元素的 value、 checked、selected attribute 的初始值,将 Vue 实例的数据作为数据来源。可用提供一个值为空的禁用 选项用于解决ios用户无法选择第一个选项的问题。<option disabled value="">请选择</option>

    2、:disabled=Boolean实现禁用。<option value="" disabled>请选择</option>

    3、一个Option就是一个下拉选项,可通过v-for循环定义好的数组、对象或整数实现列表渲染,需要通过:value接收Option选中的值

    <Select class="area" v-model="tstadium.area">
        <Option v-for="item in stateList" :value="item.value" :key="item.value" name="area">
                {{item.label }}
         </Option>
    </Select>
    

    4、v-for="item in items" 分别代表数组元素迭代的别名和源数组;其中in可用of代替。
    v-for="(item,index) in items" index为数组索引。
    当v-for循环的是一个对象时,可表示为 v-for="(value,key) in object 表示对象的键和值。
    使用v-for时尽量加上:key,这是为vue循环出来的每一项都提供唯一的标识;v-bind:key="item.id"这种 表示形式。

    5、当v-for和v-if处于同一节点时,v-for 的优先级比 v-if 更高。如果是想有条件的跳过循环执行,可将for包 在if里面。

    6、条件渲染:v-if v-else-if v-else搭配,其中v-else需要紧跟在v-if或v-else-if后面才能够被识别。
    如果在v-if指令后面添加了key,条件切换时页面都将会重新被渲染,否则共用。

    7、v-show可实现的功能和v-if相同,只是v-show是切换css的display属性,而v-if需要重新渲染dom,
    所以如果需要频繁切换最好使用v-show以减少开销,否则使用v-if为好。

    8、class的绑定:

    <div class="static" v-bind:class="{ active: isActive, 'text-danger': hasError }"></div>
       
    data: {
     isActive: true,
     hasError: false
    }
    
    最终结果为:<div class="static active"></div>
    可以使用三元运算符动态改变class如:
    	<div :class="isActive ? activeClass : ''"></div>
    如果条件为true时才会加载类。
    

    9、style的绑定:

    <div v-bind:style="styleObject"></div>
       
    data: {
     styleObject: {
         color: 'red',
         fontSize: '13px'
     }
    }
    

    ​ 表示将对象中的属性与值赋值给style,看似是css,其实是js对象,需要使用驼峰命名或短横线分隔 (用引号括起来) 来命名

    10、数据与方法:
    使用 Object.freeze(obj),会阻止修改现有的 property,因此页面不会进行渲染更新。
    vue实例属性和方法前面如果有$表示为vue自带的property 与方法,与用户自定义的区别。

    11、实例创建之后,可以通过 vm.$data 访问原始数据对象。
    Vue 实例也代理了 data 对象上所有的 property,因此访问 vm.a 等价于访问 vm.$data.a。

    12、使用v-once,执行一次性插值,当数据改变时,插值处的内容不会更新,但会影响到该节点上的其它数 据绑定。

    13、使用v-html,输出真正的 HTML,不可以在大括号中直接放入绑定的数据(HTML代码)。


    14、vue的生命周期:

    vue的生命周期

    <script>
     var vm = new Vue({
         el: "#app",
         data: {
             msg: "ok"
         },
         methods: {
             show() {
                 console.log("执行了show方法")
             }
         },
         /**
    			 * 实例创建期间的四个函数
    			 */
            // data和methods中的数据还没有被初始化
                beforeCreate() { //这是第一个生命周期函数,表示实例完全被创建之前会执行它
                // console.log(this.msg)			//提示未定义
                // 注意:在beforeCreate生命周期函数执行的时候,data和methods中的数据都还没有被初始化
            },
            // data和methods中的数据被初始化
            created() { // 这是遇到的第二个生命周期函数
                // console.log(this.msg);		//可以被调用
                // this.show();
                // 在created中,data和methods中的数据都已经被初始化;如果要调用methods中的方法或者data中的数据,最早要在created中调用
            },
            // 判断是否设置了el挂载点;vue开始编译模板,在内存中生成最终的模板字符串,然后将他渲染为内存中的DOM,还没有将此模板渲染到真正的页面中去
            beforeMount() { //第三个生命周期函数,表示模板已经在内存中编译完成,还没渲染到页面中
                // console.log(document.getElementById("h3").innerText);		//输出模板字符串
                //在此周期执行时,页面中的元素还没有真正替换,还只是之前写的模板字符串
            },
            // 将内存中编译好的模板替换到页面中去
            mounted() { //表示内存中的模板已经渲染到页面中, 用户可以看到页面;整个实例已经初始化完成,进入运行阶段
                // console.log(document.getElementById("h3").innerText);			//输出页面上真实的数据
                // 此时可以获取到页面中的值,这是实例创建期间的最后一个钩子函数,此时如果没有其他操作的话,它将在内存中一动不动
                // 如果需要操作DOM中的节点,最早需要在此周期中操作
            },
            /**
    			 * 组件运行阶段的生命周期函数,只有data中的数据发生改变时才会进入环节,最少执行0次
    			 */
            // 当执行此函数时,页面上的数据时旧的,但是data中的数据是最新的,页面尚未和最新的数据保持同步
            beforeUpdate() { //界面还没有被更新,但是数据被更新了
                // console.log('页面上的数据:' + document.getElementById("h3").innerText)
                // console.log('data中的数据:' + this.msg)
                // 当data中的数据发生改变时才会触发此函数
            },
            // 先根据内存中最新的数据重新渲染出一份最新的dom树,当内存中最新的DOM树被更新完成之后,就会重新渲染到页面中去,从而完成model到view的更新
            updated() {
                // 此函数中的数据和页面上内容都是最新的
            },
            /**
    			 * 组件销毁时执行的生命周期函数
    			 */
            beforeDestroy() {
                // 当执行此函数时实例就已经从运行阶段进入到了销毁阶段,实例身上所有的data methods 过滤器及指令等都还处于可用状态,还没有真正执行销毁的过程
            },
            destroyed() {
                // 当执行到此函数时,组件已经被完全销毁,里面所有的东西都不可用
            }
        });
    </script>
    

    (一)、beforeCreate
    第一个生命周期函数,表示实例完全被创建出来(vue初始化)之前,会执行它
    注意: 在 beforeCreate 生命周期函数执行的时候,data 和 methods 中的 属性与方法定义都还没有没初 始化,所以无法获取到data中的数据和方法

    (二)、created
    在 created 中,data 和 methods 都已经被初始化好了!
    如果要调用 methods 中的方法,或者操作 data 中的数据,最早(最好),在 created 中操作

    (三)、beforeMount
    第三个生命周期函数,表示 模板已经在内存中编辑完成了,但是尚未把 模板渲染到 页面中。
    在 beforeMount 执行的时候,页面中的元素,还没有被真正替换过来,只是之前写的一些模板字符串

    (四)、mounted---------推荐在此生命周期中获取数据:Ajax、axios(需要ES6支持)
    第四个生命周期函数,表示,内存中的模板,已经真实的挂载到了页面中,用户已经可以看到渲染好的页面了
    注意: mounted 是 实例创建期间的最后一个生命周期函数,当执行完 mounted 就表示,实例已经被完全创建好了,
    此时,如果没有其它操作的话,这个实例,就静静的 躺在我们的内存中,一动不动,表示vue实例已经初始化完毕了,组建已脱离创建阶段,进入运行阶段了。

    (五)、beforeUpdate()
    这时候,表示 我们的界面还没有被更新,但是vue中的数据已经更新了

    (六)、updated
    updated 事件执行的时候,页面和 data 数据已经保持同步了,都是最新的

    (七)、beforeDestroy
    毁之前执行,当beforeDestroy函数执行时,表示vue实例已从运行阶段进入销毁阶段,
    vue实例身上所有的方法与数据都处于可用状态

    (八)、destroyed
    当destroy函数执行时,组件中所有的方法与数据已经被完全销毁,不可用

    (九)、activated
    页面出现的时候执行 activated生命周期函数,跟 监听 watch 有类似的作用。
    activated生命周期函数,是配合 keep-alive 进行使用。进入页面时,mounted 与 activated 生命周期函数都会执行,
    当前 keep-alive 时,进行了缓存,这时返回上一页 ,mounted生命周期函数不会执行,而 activated 会执行。
    注意:新增

    (十)、deactivated
    页面消失的时候执行,deactivated生命周期函数。是配合 keep-alive 进行使用
    注意:新增


    15、在vue中实现对页面dom的操作: vm.$nextTick(function () {在此操作dom});

    16、页面渲染之前会闪烁一下的问题:在挂在的标签内写个属性:v-clock,再在style中使用属性选择器设为

    [v-clock]{
     display:none;
    }
    

    17、计算属性:内存中运行,可以理解为缓存,将不经常变化的结果在内存中缓存以节约浏览器的开销。

    ​ html中调用vue中methods的方法需要加上括号,computed中的方法不需要加括号(因为是个属性);methods和computed中的方法尽量不重名,重名后methods中的优先级高。

    18、watch:用于动态监听input中的值:可在此实现实时搜索功能

    watch: {
     //动态监听输入框中的值
     'name': {		//name为data中定义的变量
         handler: function (newValue, oldValue) {
             //newValue为新输入的值,oldValue为之前的值
             if (newValue == "" || newValue == null) {
                 //实现逻辑
             }else{
                 //实现逻辑
             }
         },
             // 深度监听 监听对象,数组的变化
             deep: true
     }
    }
    

    19、Vue.config.keyCodes.f2 = 113;自定义键盘事件,将f2指定为113键盘码,在页面直接使用(keyup.f2)

    20、使用Vue.directive('focus',{函数}),定义全局指令(不加s),参数1为指令的名称,定义时不用加v-,在调用时需要加上;参数2为一个对象,对象上有一些指令相关的函数,在相关阶段执行相关的操作。

    自定义指令


    自定义私有指令:

    自定义私有指令

    21、在axios请求数据时,get请求方式使用params传参数;post请求方式使用data传递参数。

    22、axios传json到后台:

    // 在axios中加入下面代码
    data: JSON.stringify(vm.studentInfo),
    headers:{
    "Content-Type": "application/json; charset=UTF-8"
    }
    
    // 后台接口使用String接收并转为Java对象
    public R register(@RequestBody String registerObj){
    JSONObject jsonObject = JSONObject.fromObject(registerObj);
      //将json字符串转Java对象
      RegisterForm form = (RegisterForm) JSONObject.toBean(jsonObject,RegisterForm.class);
      System.out.println("java对象:" + form);
    }
    

    二、JavaScript

    1、jQuery为页面中的标签添加属性:$(选择器).attr("属性名", "属性值");

    2、split();分割数组。push();追加到数组最后并返回一个新的数组。math.abs();返回一个数的绝对值。

    4、获取指定日期前后的天数:需要通过毫秒计算

    /**
     * 获取当前指定前后天数对应的年月日
     * @param AddDayCount    指定日期前后的天数
     * @returns {string}    202004420
     * @constructor
     */
    function GetSagginDateStr(AddDayCount) {
            var nDate = new Date().getTime();   //获取当前时间的毫秒值
            var millSeconds = Math.abs(nDate) + (AddDayCount * 24 * 60 * 60 * 1000); //将两个毫秒值相加
            var rDate = new Date(millSeconds);      //将毫秒值转为一个标准时间
            var year = rDate.getFullYear();
            var month = rDate.getMonth() + 1;
            if (month < 10) {
                month = "0" + month;
            }
            var date = rDate.getDate();
            if (date < 10) {
                date = "0" + date;
            }
            return year + "" + month + "" + date;
    }
    

    5、获取时间的毫秒值:new Date().getTime();

    6、获取时间戳:Date.now();

    7、Es6相关语法:

    const用于声明一个只读 常量,且必须在声明常量时就需要对其进行赋值,一旦声明就不可再改变(内存地址不变);
    let用于声明一个变量,与var类似,但是只在它声明的代码块内有效。
    二者都需要先声明再使用。
    
    在ES5中,变量声明只有 var 和function两种方法,
    在ES6中,添加了 let 和 const,还有 class 和 import 两种命令
    

    8、数组的解构和赋值:通过匹配位置赋值

    let [a,b,c] = [1,2,3];		//分别打印abc,会分别得到123
    //如果左右的值匹配不成功就会返回undefined
    //右边的值需要是能够遍历的解构或者数组,否则会报错
    

    解构

    9、对象的解构和赋值:通过对象属性名进行赋值

    let {name,age} = {name:'张三',age:18}		//如果名字匹配不上就将报undefined
    
    let {log} = console;		//可以将对象中的方法赋值给某个变量
    	log("hello world");		//将会输出“hello world”
    /**
    *对象结构赋值的内部机制,即先找到同名的属性,再将属性复制给同名的变量,真正被赋值的后者,而不是前者
    *如下代码中,foo只是匹配模式,name才是真正的变量
    */
    let {foo:name} = {foo:'hello'};
    	console.log(name);
    
    let {name,age=18} = {name:'张三',age:undefined}		//如果值为undefined时,会执行默认值
    
    

    10、字符串的解构:

    let [a,b,c,d,e] = "hello";		//会将字符串拆分为单个字母
    
    let {length:len} = "hello";		//返回字符串的长度	
    
    

    ​ 用途:

    /**
    001、交换变量的值
    */
    let x = 10;
    let y = 20;
    [x,y] = [y,x];
    
    /**
    002、获取函数的多个返回值
    */
    //获取返回数组的多个值
    function example(){
     return [1,2,3]
    }
    let [a,b,c] = example();
    
    //获取返回对象的多个值
    function example2(){
     return{
         name:'hello',
         slogan:'world'
     }
    }
    let {name,slogan} = example2();
    
    /**
    003、提取json数据
    */
    let jsonData = {
     name:'test',
     age:18,
     like:'frisbee'
    };
    let [name,age,like] = jsonData;
    
    /**
    004、设置函数参数的默认值
    */
    function sendMsg(url,{
         async=true,
         beforeSend = function(){},
         global=true
    	} = {}){
     //..函数处理逻辑
    }
    
    /**
    005、输入模块的指定方法
    */
    const {sourceMapConsumer,SourceNode} = require("source-map")
    
    /**
    06、遍历Map
    */
    const map = new Map();
    map.set('first','hello');
    map.set('second','world');
    
    for(let [key,value] of map){
     console.log(key + ":" + value);
    }
    

    11、str.padStart(maxLength,'String'),当字符串的位数不足指定的maxLength时就在开始填充指定的string;同时还有padEnd方法在尾部填充。

    12、focus()方法可以获取到焦点

    13、去掉字符串前面的0: console.log(s.replace(/(0+)/gi,""));

    14、ECharts配置:

    echats

    15、立即执行函数:

    (function(){
    	// js代码,里面定义的都是局部的,从而避免命名污染
    })();
    
    (function(j){		// j为内部调用
    	// js代码
    }(i));  			// i为外部参数传递的入口
    
    !function(){
     
    }();
    
    void function(){
     
    }();
    

    16、cookies、sessionStorage、localStorage的区别:

    cookie数据始终在同源的http请求中携带(即使不需要),记会在浏览器和服务器间来回传递,大小不可超过4k。
    sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存,可达5M或更大。
    
    localStorage只有手动才能删除,除非一直生效。
    sessionStorage当前浏览器关闭后自动删除。
    cookie在过期时间内有效,即使页面或浏览器关闭。
    

    17、当前标签打开新页面:

    window.location.href = "../html/login.html";
    

    18、iframe标签子页面操作父页面:

    $(window.parent.document).find('footer').css("display", "none");
    

    三、html

    1、使背景不能左右滑动:

    body{
     overflow-x: hidden;
    }
    

    2、微信使用input-file出现没有应用可执行此操作:是因为 input-file添加了accept属性 ,删除并在js判断格式

    <input type="file" @change="getFile">
    getFile(){
     let previewImgs = e.target.files[0]
     if (!new RegExp("(jpg|jpeg|gif|png)+","gi").test(previewImgs.type)) {
       Toast('您上传的图片格式有误,请重新上传~')
       return
     }
    }
    
    

    3、使整个网页变灰:来源

    html {
     filter: progid:DXImageTransform.Microsoft.BasicImage(grayscale=1);
     -webkit-filter: grayscale(100%);
    }
    

    4、网页无法选择:来源

    /*在HTML的body标签中加入相关代码*/
    οnpaste="return false" /*不准粘贴*/
    οncοpy="return false;" /*不准复制*/
    oncut="return false;" /*防止剪切*/
    onselectstart = "return false" /*不准选择*/
    

    5、在图片上点击查看大图(将图片从新页面打开):

    <img title='点击查看大图' onclick='window.open("src")' src=src width=100% height=100%>
    

    四、Linux

    1、jar文件在后台不间断运行:

    nohup java -jar xxx.jar >temp.txt &
    nohup 意思是不挂断运行命令,当账户退出或终端关闭时,程序仍然运行
    & 代表在后台运行
    >temp.txt 表示将运行日志保存到temp文件中
    

    五、Java

    1、spring boot获取yml中的配置信息:在配置文件中编写数据、导入依赖、创建实体类、使用

    # 配置信息
    we-chat-info:
       token: badmin
       appid: wx73deaf87124512b7e
       secret: 87fe6292ca050b1ca541b148e2512345
    
    <!--导入配置文件处理器,获取application.yml中的数据,第二个测试可不需要-->
    <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-configuration-processor</artifactId>
         <optional>true</optional>
    </dependency>
    
    <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-test</artifactId>
         <scope>test</scope>
    </dependency>
    
    /**
    * 创建实体类
    */
    @Data
    @Configuration
    @ConfigurationProperties(prefix = "we-chat-info")		//yml中的根节点名
    public class SysWeChat implements Serializable {
     private static final long serialVersionUID = 1L;
    
     /**
      *节点中对应的各个属性名
      */
     private String token;
    
     private String appid;
    
     private String secret;
    
    }
    
    /**
     * 调用
     */
    @Autowired
    private static SysWeChat sysWeChat;
    
    private static final String TOKEN = sysWeChat.getToken();
    private static final String APPID = sysWeChat.getAppid();
    private static final String SECRET = sysWeChat.getSecret();
    
    /**
     * 测试
     */
    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class WeChatTest {
    
        @Autowired
        private WeChatConfig weChatConfig;
    
        @Value("${we-chat-info.token}")
        private String token;
    
    
        @Test
        public void testInfo() {
            System.out.println(weChatConfig.getAppid());
            System.out.println(token);
        }
    }
    
    

    2、Java对象转json字符串:

    //1、使用JSONObject
    JSONObject json = JSONObject.fromObject(stu).toString();
    //2、使用JSONArray
    JSONArray array=JSONArray.fromObject(stu).toString();
    

    3、json字符串转java对象:

    //1、使用JSONObject
    JSONObject jsonObject=JSONObject.fromObject(objectStr);
    Student stu=(Student)JSONObject.toBean(jsonObject, Student.class);
    
    //2、使用JSONArray
    JSONArray jsonArray=JSONArray.fromObject(arrayStr);
    //获得jsonArray的第一个元素
    Object o=jsonArray.get(0);
    JSONObject jsonObject2=JSONObject.fromObject(o);
    Student stu2=(Student)JSONObject.toBean(jsonObject2, Student.class);
    

    4、list转json字符串:

    List<Student> lists=new ArrayList<Student>();
    lists.add(stu);
    //1、使用JSONObject
    //JSONObject listObject=JSONObject.fromObject(lists);
    //2、使用JSONArray
    JSONArray listArray=JSONArray.fromObject(lists);
    

    5、json字符串转list:

    List<Student> list2=(List<Student>)JSONArray.toList(JSONArray.fromObject(arrayStr), Student.class);
    
    for (Student stu : list2) {
     System.out.println(stu);
    }
    //转化为数组
    Student[] ss =(Student[])JSONArray.toArray(JSONArray.fromObject(arrayStr),Student.class);
    for (Student student : ss) {
     System.out.println(student);
    }
    

    6、map转json字符串:

    Map<String,Student> map=new HashMap<String,Student>();
    map.put("first", stu);
    
    //1、JSONObject
    JSONObject mapObject=JSONObject.fromObject(map);
    System.out.println("mapObject"+mapObject.toString());
    
    //2、JSONArray
    JSONArray mapArray=JSONArray.fromObject(map);
    System.out.println("mapArray:"+mapArray.toString());
    

    7、json字符串转map:

    //JSONObject
    JSONObject jsonObject=JSONObject.fromObject(strObject);
    Map map=new HashMap();
    map.put("first", Student.class);
    
    //使用了toBean方法,需要三个参数 
    MyBean my=(MyBean)JSONObject.toBean(jsonObject, MyBean.class, map);
    System.out.println(my.getFirst());
    /**
    * 使用toBean()方法是传入了三个参数,第一个是JSONObject对象,第二个是MyBean.class,第三个是一个Map对象。
    * 通过MyBean可以知道此类中要有一个first的属性,且其类型为Student,要和map中的键和值类型对应,即,first对应键 first类型对应值的类型。
    */
    

    8、上传文件:使用post方式提交

    @RequestMapping("/file")
    public String file(@RequestParam("file") MultipartFile file, String creditCode) {
     if (file.isEmpty()) {
         return "请选择文件";
     }
     Long date = System.currentTimeMillis();
     String fileRealName = file.getOriginalFilename();       // 获取文件原始名称
     String extension = getExtension(fileRealName);          // 获取文件扩展名
     String fileName = date + "." + extension;              // 拼接文件名
     // 路径如:D:internshipimageafterInternship
     String filePath = fileUtil.getRootPath("image" + File.separator + "afterInternship");
     // 如果不存在文件夹就创建一个
     if (!new File(filePath).isDirectory()) {
         new File(filePath).mkdir();
     }
     File dest = new File(filePath + fileName);
     try {
         file.transferTo(dest);
         return fileName;
     } catch (IOException e) {
    
     }
     return "上传失败!";
    }
    

    9、对象转map

    Map<String, Object> tempMap = new HashMap<>();
    // 将对象转为map
    BeanInfo beanInfo = Introspector.getBeanInfo(对象.getClass());
    PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
    for (PropertyDescriptor property : propertyDescriptors) {
     String key = property.getName();
     if (key.compareToIgnoreCase("class") == 0) {
         continue;
     }
     Method getter = property.getReadMethod();
     Object value = getter != null ? getter.invoke(对象) : null;
     tempMap.put(key, value);
    }
    

    10、controller注解:

    public R xxx(@RequestBody Object object)  //用于接收前端post请求发送的data数据,后端使用对象接收。
     
    public R xxx(@RequestParam Map<String, Object> params)  //用于接收前端get方式发送的params数据;params.get("userId").toString();
    
    public R xxx(@RequestBody String objData)  //用于接收前端post发送的json字符串,后端使用JSONObject.fromObject(objData)将其转为json对象;如果对象中有多余的值,可通过json对象的remove方法将其删除;再通过JSONObject.toBean(jsonObject,Object.class)将其转为指定对象。
     
    @PostMapping("login/{userId}")  //前端在发送请求时直接将参数拼接在url后面,使用斜杠隔开;后端在方法上使用@PathVariable("userId") String uId接收。
     
    @RequestMapping(value = "/wx", method = {RequestMethod.GET, RequestMethod.POST})  //可同时接收post和get方式的请求。
    
  • 相关阅读:
    了解一些分词工具
    Maven 依赖的作用域
    aop 的一些表达式
    Mybatis 高级查询的小整理
    namespace" 或The content of element type "mapper" must match "EMPTY"
    Spring事务管理
    Java异常详解
    初识事务
    数据库共享锁与排它锁
    StringUtils.isEmpty和StringUtils.isBlank的区别
  • 原文地址:https://www.cnblogs.com/zhangzimuzjq/p/13568902.html
Copyright © 2011-2022 走看看