<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.min.css" />
<script src="//polyfill.io/v3/polyfill.min.js?features=es2015%2CIntersectionObserver" crossorigin="anonymous"></script>
<script src="//unpkg.com/vue@latest/dist/vue.min.js"></script> @*目前版本是2.x*@
<script src="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.min.js"></script>
<script src="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue-icons.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script> @*http 請求*@
<script src="~/Scripts/moment-with-locales.min.js"></script> @*date 格式化*@
html
定義app範圍
<div id="app">
...
</div>
顯示data
{{plaintext}}
顯示html文字
<span v-html="htmltext"></span>
input綁定屬性值,.number 表示限制只能輸入數字
<input v-model.number="unitprice" type="number" />
.trim 表示自動刪除前後空白字元
<input type="text" v-model.trim="trimMsg" />
可綁定陣列屬性
<label><input type="checkbox" value="Jack" v-model="checkedNames">Jack</label>
<label><input type="checkbox" value="John" v-model="checkedNames">John</label>
href 替換變數bbb
<a v-bind:href='`...?a=${bbb}`' target="_blank">{{ccc}}</a>
select 綁定用法,v-bind:value="option" 透過 v-bind: 讓屬性 綁定變數
<select v-model="selected">
<option disabled value="">请选择</option>
<option v-for="option in options" v-bind:value="option.value" v-bind:key="option.value"> @*v-bind:key 指定識別物件的屬性*@
{{ option.text }}
</option>
</select>
select 複選綁定用法,搭配ctrl or shift 選擇多筆
<select multiple v-model="multiselected">
<option disabled value="">请选择</option>
<option v-for="option in options" v-bind:value="option.value">
{{ option.text }}
</option>
</select>
v-bind:xxx 對應 attribute:xxx 綁定屬性值,v-on:xxx 對應事件,.stop 表示事件觸發不往上層拋,.prevent 表示不觸發預設行為
<button v-bind:disabled="loading" v-bind:class="{ 'error': 按鈕禁用 }" v-bind:style="按鈕樣式" v-on:click.stop.prevent="下單($event)">下單</button>
v-on:keyup.enter 表示按enter 後執行
<input type="text" placeholder="輸入任意文字後按下 enter 鍵" v-model.trim="trimMsg"
v-on:keyup.enter="下單()">
v-on:keyup.enter.exact 表示若有搭配其他按鍵則不要觸發 (例如 shift+enter)
依據條件控制是否顯示
<span v-show="按鈕禁用">按鈕禁用</span>
※若搭配 class:d-flex 會造成 v-show 無法正確隱藏,必須改用 v-if
強制更新頁面區塊,每當componentKey 更新時就會更新此div (重新判斷v-show)
<div v-show="new Date()>=時間 && !已預約" v-bind:key="componentKey">很抱歉,活動已開始,無法預約囉</span>
依據屬性值控制顯示忙碌中圖案,例如呼叫後端尚未完成時,內部元素會暫時無法互動,預設位置是外部容器的正中間
<b-overlay :show="loading" opacity="0.8" variant="light" spinner-variant="primary">
...
</b-overlay>
若要保持捲動瀏覽器視窗時位置不會跑掉,外面必須再包一層div
<div style="position: fixed; top: 2em; width: 100%; z-index: 10;"><b-overlay :show="loading" opacity="0.8" variant="light" spinner-variant="primary"></b-overlay></div>
或單獨使用 b-spinner 顯示忙碌中圖案,各按鈕單獨控制是否暫時disable
<div style="position: fixed;top:1em; left: 50%; transform: translateX(-50%)" v-show="loading"><b-spinner label="Loading..." variant="primary"></b-spinner></div>
使用 Bootstrap Icon
<b-icon-[Bootstrap Icon name]></b-icon-[Bootstrap Icon name]>
<b-icon-clipboard></b-icon-clipboard>
針對 arrow-90deg-left 順時針旋轉90度
<b-icon-arrow-90deg-left style="transform: rotate(90deg)"></b-icon-arrow-90deg-left>
格式化輸出
{{ xxx | dateFormat('HH:mm')}}
{{ xxx | numberFormat(0,false) }}
javascript (放在 </html> 後面才能正確載入)
====
設定 moment 為繁體中文
moment.locale('zh-tw');
加入filter
// 數值格式化
Vue.filter('numberFormat', function (value, 最大小數位, 千分位符號) {// 小數位、千分位符號
return Intl.NumberFormat('en-US', { maximumFractionDigits: 最大小數位, useGrouping: 千分位符號 }).format(value);
});
// 日期格式化
Vue.filter('dateFormat', function (value, myFormat) {
return moment(value).format(myFormat);
});
載入 BootstrapVue 套件,提供多種美化功能
Vue.use(BootstrapVue)
建立 vue app
const app = new Vue({
el: '#app', // 綁定 html element
data() { // 定義屬性及預設值,需要先定義才能使用 v-model
return {
plaintext: '123',
htmltext: '<i>123</i>',
trimMsg: null,
loading: false, // 控制顯示忙碌中圖案
}
},
methods: { // 定義函數
取得參數字串() {
return this.參數字串;
},
下單() {
this.$bvToast.toast('已下單', {variant: 'success',solid: true, noCloseButton:true}); // 顯示訊息視窗,variant 決定顏色,sold:true 表示不要透明處理,noCloseButton:true 搭配不指定 title 才不會顯示 title bar
},
getdata() {
let $vue = this;
axios.post('./get', { 參數: '@Model' }) // 呼叫後端
.then(response => {
this.resultdata = response.data;
}).catch(function (error) { // 请求失败处理
console.log(error);
$vue.$bvToast.toast(error.response.data, { variant: 'danger', solid: true, noCloseButton: true }); // catch 中的 this 是window,需要在之前先用變數儲存 vue 物件
});
},
並行呼叫() {
axios.all([axios.post('./get', { 參數: '@Model' }), axios.post('./testpost')]) // 同時呼叫多個後端,全部完成後才進行下一個動作時使用此方法
.then(axios.spread((response1, response2) => {
this.resultdata1 = response1.data;
this.resultdata2 = response2.data;
}));
},
},
computed: { // 計算型屬性,html使用時不需要加括號
金額() {
return this.unitprice * this.number;
},
},
watch: { // 監控屬性變化
trimMsg(val, oldValue) { // 當trimMsg更新時觸發
console.log(`新的 msg: ${val}`);
console.log(`舊的 msg: ${oldValue}`);
}
},
created: function () { // app 建立後觸發
let $vue = this; // 預先儲存 app 以供函數使用
axios.interceptors.request.use( // 呼叫後端前觸發
function (config) {
$vue.loading = true; // 搭配b-spinner顯示忙碌中圖案,且透過 v-bind:disabled 避免重複執行click
return config;
},
function (error) {
$vue.loading = false; // 呼叫失敗時隱藏忙碌中圖案
return Promise.reject(error);
}
);
axios.interceptors.response.use(function (response) { // 呼叫後端完成後觸發
$vue.loading = false; // 呼叫完成後隱藏忙碌中圖案
return response;
}, function (error) {
$vue.loading = false; // 呼叫完成但失敗時隱藏忙碌中圖案
return Promise.reject(error);
});
},
mounted: function () {
this.$nextTick(function () {
// 放置頁面載入後要執行的初始動作,類似 jquery $(document).ready(function() {})
// 若要立刻呼叫 axios.post 必須先等候一下,否則 b-overlay 無法正確顯示
// ex. setTimeout(() => this.查詢訂單(), 100);
})
},
});
避免中文字出現亂碼
1. <head></head> 加入 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
2. 檔案編碼必須為"具有BOM 的 UTF-8",若無則用記事本另存,編碼選擇 具有BOM 的 UTF-8 (visual studio create view 預設此編碼)
混入 (可放共用函數)
import { commonMixin } from '@Url.Content("~/scripts/commonVue.js")'
Vue.mixin(commonMixin); // 放在 Vue.filter 之後避免 filter 失效
commonVue.js :
export const commonMixin = {
methods: {
onerror: function (error) {
console.error(error);
if (error.response.status == 401) {
alert('登入逾時');
location.reload();
}
else
this.$bvToast.toast(error.response.data, { variant: 'danger', solid: true, noAutoHide: true });
},
}
}
※若要動態新增物件屬性,必須在綁定到 vue 之前完成,否則會喪失DOM雙向綁定機制
const rows = [{value:1},{value:2},];
rows.forEach(a => {
a.text = '...';
});
this.rows = rows;
相關連結