小白水平 可能會包含一些錯誤 或者還沒寫完... 或者非最佳實踐 僅供參考
這個vue的官方api會有介紹javascript
model: { prop: 'checked', event: 'change' }
v-on:change="$emit('change', $event.target.checked)"
子代操做方法二:css
props:{ value:[String,Number], }
handleInput(event) { const value = event.target.value; // 經過這個實現v-model的set this.$emit('input', value); },
<input :value="something" @input="something=$event.target.value" /> <!-- 組件上的簡化 --> <custom-input :value="something" @input="something=$event" > </custom-input> <!-- 子組件 --> <input type="text" :value="currentValue" @input="handleInput"> <!-- 1.子組件設置props的value --> props:['value'],//接受父組件傳遞過來的value值 <!-- 2.向父組件傳遞改變的值 --> methods:{ handleInput(event){ let value =event.target.value; this.$emit('input',value);//觸發input事件,並傳入新的值 }, setCurrentValue(value) { this.currentValue = value; }, } <!-- 3.重要:經過watch父組件的value改變纔會更新子組件 這裏以前就會出現父級value改變 子代不改變的bug--> watch: { value(val, oldValue) { this.setCurrentValue(val); } },
// 例子 <input type="checkbox" ref='switch' @click="handleClick"/> handleClick(evt) { this.$emit('click', evt); } // 例子 <input type="checkbox" ref='switch' @focus="handleFocus"/> handleFocus(event) { this.focused = true; this.$emit('focus', event); },
/* 父組件 */ <Example :width=40></Example> /* 子組件 */ <span class="el-switch__core" ref="core" :style="{ 'width': width + 'px' }">
// 第一步,註冊組件 import Switch from './src/component'; Switch.install = function(Vue) { // name="TuiSwitch" Vue.component(Switch.name, Switch); }; export default Switch; // 第二步,安裝組件(main.js) import Switch from 'install文件'; Vue.use(Switch); // 第三步,在組件中直接使用便可 <tui-switch></tui-switch>
axios.defaults.timeout = 30000; // 開發時只關心接口名稱便可 axios.defaults.baseURL = "http://10.0.1.1:8080"; // 配置axios的攔截器,能夠用來配置token axios.interceptors.request.use( config => { if (localStorage.getItem("token")) { config.headers.Authorization = localStorage.getItem("token"); } return config }, error => { return Promise.reject(error) } );
axios.post(url, params, { headers: { "Content-Type": "application/json;charset=UTF-8" } }).then(res=>{})
JSON.stringify({sdkParams: JSON.stringify(this.params)}); <!-- 這樣子後面的字符串中的引號就會有轉義字符 -->
git remote -v
顯示origin表明的遠程地址Node將在node_modules中搜索element-ui目錄,Node會假設element-ui爲一個包並試圖找到包定義文件package.json。若是element-ui目錄裏沒有包含package.json文件,Node會假設默認主文件爲index.js,即會加載index.js。若是index.js也不存在,那麼加載將失敗。 package.json: { "license": "MIT", "main": "lib/element-ui.common.js", "name": "element-ui", } node將會返回element-ui.common.js模塊
websocket(prodId) { this.ws = new WebSocket('ws://..........'); this.ws.onopen = function () { console.log("ws connected!"); }; this.ws.onmessage = e => { }; this.ws.onclose = function () { // 關閉 websocket後的回調函數 console.log("ws closed"); }; // 組件銷燬時調用,主動關閉websocket鏈接 this.over = () => { ws.close(); }; }, beforeDestroy() { if (this.over) { this.over(); } send(msg){ if(this.ws){ this.ws.send(msg) } }
<!-- 這是文件擴展名爲 .vue 的 single-file components(單文件組件) 相比傳統new Vue({ el: '#container '})要好不少 --> <template> <div>This will be pre-compiled</div> </template> <script src="./my-component.js"></script> <style src="./my-component.css"></style> <!-- 開發時也會常用這種的格式 -->
flex是flex-grow flex-shrink flex-basis的縮寫html
在有固定高的容器中實現標題在上面,內容在剩餘高度居中:前端
display: flex; flex-direction: row; flex-wrap: wrap;
flex:1
來實現佔滿一行align-self: flex-start||baseline;
均可以實現,(測試元素是一個img)var EventUtil={ /*檢測綁定事件*/ addHandler:function(element,type,handler){ if(element.addEventListener){ element.addEventListener(type,handler,false); } else if(element.attachEvent){ element.attachEvent('on'+type,handler); } else{ element["on"+type]=handler /*直接賦給事件*/ } }, /*經過removeHandler*/ removeHandler:function(element,type,handler) { /*Chrome*/ if (element.removeEventListener) element.removeEventListener(type, handler, false); else if (element.deattachEvent) { /*IE*/ element.deattachEvent('on' + type, handler); } else { element["on" + type] = null; /*直接賦給事件*/ } } };
### 18.多層組件的封裝vue
18-9-13 當時的觀點有點弱智啊,這個這個直接改變了子組件中的值啊,多是由於對象深度緣由沒有報錯?java
<!-- 數據單向綁定,不須要使用watch從父組件更新值到子組件,這句話很矛盾啊 --> <template> <div> <div class="product_info_row" v-for='(arr,index) in value' :key="index"> <div class="tag_input"> <lubun-input :cancleable='true' v-for='(v,i) in arr.tags' :key="i" type="text" v-model="v.value" :width=width :tagrow='index' :tagid='v.id' @click='removeTag' /> <!-- 失去焦點也須要保存 --> <lubun-input autofocus v-if='arr.show' type="text" v-model="arr.value" :width=80 @enter='buildTag(arr)' @blur='buildTag(arr)' /> <lubun-button v-else text="+" @click="addTag(arr)" :width=30 /> </div> </div> </div> </template> <script> export default { name: "LubunTaginput", componentName: "LubunTaginput", props: { width: { type: [String, Number], default: 150 }, value: { type: Array, default: function () { return [ { id: 0, show: false, value: "", tags: [] } ] } } }, methods: { addTag(rows) { rows.show = true; rows.value = ""; }, removeTag(obj) { // console.log("傳入的rows:",obj); var tags = this.value[obj.tagRow].tags; // console.log("rows中的tags",tags); for (let i = 0; i < tags.length; i++) { // console.log("循環tags:", tags[i]); if (tags[i].id === obj.tagId) { // console.log('find'); tags.splice(i, 1); return; } } }, buildTag(rows) { rows.show = false; // 內容爲空不會生成tag if (rows.value !== "") { rows.tags.push({ id: rows.id++, value: rows.value }); rows.value = ""; } } }, }; </script>
white-space:nowrap
這樣就能夠撐開兩個div了beforeDestroy() { //組件銷燬前須要解綁事件。不然會出現重複觸發事件的問題 bus.$off("Event Name"); },
father{ display: flex; width: 100%; height: 100%; overflow: auto; } child-left{ position: relative; min-width: 800px; height: 100%; flex: 1; } child-right{ position: relative; min-width: 420px; height: 100%; }
<label style="width:80%" class='btn' for="uploadPic">上傳文件</label> <input id="uploadPic" type="file" @change='uploadPic' style="display:none">
<span class="button" onclick="sel_local_images()" id="add_img" title="Add new file from local disk">加載圖片</span> <input type="file" id="invisible_file_input" name="files[]" style="display:none"> //js中再給input加change事件便可 //這個也能夠在vue中使用,給input加@change,而後手動觸發這個input 的click()就能夠彈出上傳文件的界面了
var invisible_file_input = document.getElementById("invisible_file_input"); function sel_local_images() { if (invisible_file_input) { invisible_file_input.setAttribute('multiple', 'multiple'); invisible_file_input.accept = '.jpg,.jpeg,.png,.bmp'; invisible_file_input.onchange = (e)=>{ // 得到第一張圖片 var img = e.target.files[0]; }; invisible_file_input.click(); } }
//reader有幾個讀取文件的方法用於讀取成不一樣格式,還有幾個鉤子函數用於不一樣階段執行一些功能 // var img =xxxxxxxxxxxx // 將圖片的base64格式顯示在頁面上,圖片可使用input上傳 let reader = new FileReader(); reader.onload = (theFile)=>{ that.imgLoaded = e.target.result; // 2018-10-24 圖片尚未加載完成,不是DOM的問題,使用onload才能正確得到原始寬高 var i = new Image(); i.src = e.target.result; i.onload = () => { img_loaded_width = i.width; img_loaded_height = i.height; }} // 這個貌似會執行上面的onload reader.readAsDataURL(img);
var blob = new Blob([JSON.stringify(data, null, 2)],{type : 'application/json'}); var aTag = document.getElementById('download_img'); aTag.setAttribute('href', URL.createObjectURL(blob)); aTag.setAttribute('download', that.imgLoadedName.split('.')[0]+'.json'); aTag.click();
第一種能夠實現對拍照界面的重寫,IPhone環境11開始兼容; 第二種方式其實是調用input[type='file'],會彈出一個選擇框讓用戶選擇是調用相機仍是調用相冊, 第二種兼容優於第一種,很差的地方就是這種方法沒法控制拍照,想要在移動端實現只能拍照不能選擇照片或者在拍照界面添加引導遮罩層的方法是行不通了。
<video width="640" height="480" id="myVideo"></video> <canvas width="640" height="480" id="myCanvas"></canvas> <button id="myButton">截圖</button> <button id="myButton2">預覽</button> <button id="myButton3"> <a download="video.png">另存爲</a> </button>
var cobj = document.getElementById('myCanvas').getContext('2d'); var vobj = document.getElementById('myVideo'); getUserMedia({video: true}, function (stream) { vobj.src = stream; vobj.play(); }, function () { }); document.getElementById('myButton').addEventListener('click', function () { cobj.drawImage(vobj, 0, 0, 640, 480); document.getElementById('myButton3').children[0].href = cobj.canvas.toDataURL("image/png"); }, false); document.getElementById('myButton2').addEventListener('click', function () { window.open(cobj.canvas.toDataURL("image/png"), '_blank'); }, false); function getUserMedia(obj, success, error) { if (navigator.getUserMedia) { getUserMedia = function (obj, success, error) { navigator.getUserMedia(obj, function (stream) { success(stream); }, error); } } else if (navigator.webkitGetUserMedia) { getUserMedia = function (obj, success, error) { navigator.webkitGetUserMedia(obj, function (stream) { var _URL = window.URL || window.webkitURL; success(_URL.createObjectURL(stream)); }, error); } } else if (navigator.mozGetUserMedia) { getUserMedia = function (obj, success, error) { navigator.mozGetUserMedia(obj, function (stream) { success(window.URL.createObjectURL(stream)); }, error); } } else { return false; } return getUserMedia(obj, success, error); }
有時候後端傳過來的字符串中\\n轉成字符對象時會成爲\n可是在vue中渲染到頁面中不會出現換行,而是顯示爲\n (compose.environment[key]).replace(/\\n/g,'\n') 而後就能夠實現前端換行了 很奇怪 不知道爲何
//{men:{name:'Kik',age:11},place:['A','B','C']} ArrayList<String> place = (ArrayList<String>) jsonObject.getObject("place", List.class);
String algorithmList = "["a","b","c"]" List<String> apacMainIdList = JSONObject.parseObject(algorithmList, List.class);
<!--使用absolute和top,left,right,bottom來完成div填充剩餘部分--> <div style="position:absolute;background:#ccc;top:0;left:0;right:0;bottom:0;overflow:hidden"> <div style="position:absolute;width:140px;background:#C00;top:0;left:0;bottom:0"> </div> <div style="position:absolute;left:140px;background:#0C0;top:0;right:0;bottom:0;"> </div> </div>
// 讀取爲二進制 function createXHR(){ return window.XMLHttpRequest? new XMLHttpRequest(): new ActiveXObject("Microsoft.XMLHTTP"); } function getData(url){ let request = createXHR(); request.open("GET",url,false); request.responseType = 'blob'; request.onload = function () { var reader = new FileReader(); reader.readAsArrayBuffer(request.response); reader.onload = function (e) { var DAT_data = e.target.result; console.log("DAT_data:" + DAT_data); }; }; request.send(); }