-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Vue #21
Labels
Comments
vscode 插件
|
Vue技术内幕,源码解析 |
VUE 事件鼠标移入移出事件,类CSS hover 事件 <label for="main-link" class="link" @mouseenter="showSub" @mouseleave="hideSub">集团信息</label> |
Vue 判断浏览器
import Vue from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';
import './registerServiceWorker';
Vue.config.productionTip = false;
console.log('navigator.userAgent;--',navigator.userAgent)
let na=navigator.userAgent
Vue.prototype.$na=na
new Vue({
router,
store,
render: (h) => h(App),
}).$mount('#app');
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
@Component
export default class HelloWorld extends Vue {
@Prop() private msg!: string;
created(){
console.log('na--',this.$na)
}
}
</script>
Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1 https://github.com/greedying/vue-visitor 探测当前设备 |
页面上下效果
<template>
<div id="app">
<!-- <div id="nav">-->
<!-- <router-link to="/">Home</router-link> |-->
<!-- <router-link to="/about">About</router-link>-->
<!-- </div>-->
<transition :name="slideType">
<router-view/>
</transition>
<audio loop :src="musicSrc" preload class="audio" ref="audio"/>
</div>
</template>
<script lang="ts">
import {Component, Vue} from 'vue-property-decorator';
@Component({
components: {}
})
export default class App extends Vue {
audioRef
musicSrc = ''
slideType:string=''
mounted() {
this.preventWechatTouch()
this.listenMusic()
this.listenNavgation()
this.slideType='transition'
}
play() {
this.audioRef.play()
}
pause() {
this.audioRef.pause()
}
preventWechatTouch() {
document.addEventListener('touchmove', function (event) {
event.preventDefault();
});
}
listenMusic() {
this.audioRef = this.$refs.audio
this.$bus.on('play', this.play)
this.$bus.on('pause', this.pause)
}
listenNavgation() {
this.$bus.on('slideUp', this.slideToUp)
this.$bus.on('slideDown', this.slideToDown)
}
slideToUp() {
this.slideType = 'transition'
}
slideToDown() {
this.slideType = 'down'
}
}
</script>
<style lang="less">
@font-face {
font-family: "kuaile";
src: url("./assets/kuaile.ttf")
}
@font-face {
font-family: "SourceHanSans";
src: url("./assets/SourceHanSansCN-Normal.otf")
}
#app {
font-family: SourceHanSans, 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
body {
margin: 0;
}
body:before {
width: 100%;
height: 100%;
content: ' ';
position: fixed;
z-index: -1;
top: 0;
left: 0;
background: #fff;
}
.transition-enter-active {
transform: translateY(0vh);
transition: all .5s ease;
//transition: all 0.5s cubic-bezier(1.0, 0.5, 0.8, 1.0);
}
.transition-leave-active {
transition: all .5s ease;
//transition: all 0.5s cubic-bezier(1.0, 0.5, 0.8, 1.0);
}
.transition-enter {
transform: translateY(100vh);
}
.transition-leave-to
/* .slide-fade-leave-active for below version 2.1.8 */ {
transform: translateY(-100vh);
// opacity: 0;
}
.down-enter-active {
transform: translateY(0vh);
transition: all .5s ease;
//transition: all 0.5s cubic-bezier(1.0, 0.5, 0.8, 1.0);
}
.down-leave-active {
transition: all .5s ease;
//transition: all 0.5s cubic-bezier(1.0, 0.5, 0.8, 1.0);
}
.down-enter {
transform: translateY(-100vh);
}
.down-leave-to
/* .slide-fade-leave-active for below version 2.1.8 */ {
transform: translateY(100vh);
// opacity: 0;
}
& > .touche::before {
content: '';
position: absolute;
top: -10px;
right: -10px;
bottom: -10px;
left: -10px;
}
& > .audio {
position: absolute;
top: 1000vw;
left: 1000vh;
opacity: 0;
z-index: 0;
}
</style>
|
Vue 指令 directive
export default {
install(Vue, options) {
Vue.directive('drag', {
bind(el, binding, vnode, oldVnode) {
let startX
let startY
let translateX = 0
let translateY = 0
let translateXLast = 0
let translateYLast = 0
let distance = 0
function touchStart(event) {
event.preventDefault()
if (!event.touches.length) return;
el.classList.add('dragable')
el.classList.add('ease')
let touch = event.touches[0]
startX = touch.pageX;
startY = touch.pageY;
}
function touchMove(event) {
event.preventDefault();
if (!event.touches.length) return;
let touch = event.touches[0]
let x = touch.pageX - startX
let y = touch.pageY - startY;
translateX = x
translateY = y
el.style.transform = `translate(${translateXLast + x}px, ${translateYLast + y}px)`
}
function touchEnd(event) {
translateXLast += translateX
translateYLast += translateY
endAnimation()
}
function endAnimation() {
el.style.transform = `translate(${translateXLast}px, ${translateYLast - distance}px`
el.style.opacity = 0
setTimeout(() => {
reset()
}, 500)
}
function reset() {
translateX = 0
translateY = 0
translateXLast = 0
translateYLast = 0
el.classList.remove('ease')
el.classList.add('dragable')
el.style.transform = `translate(${0}px, ${0}px`
el.style.opacity = 1
}
function init() {
distance = binding.value
el.addEventListener('touchstart', touchStart, false)
el.addEventListener('touchmove', touchMove, false)
el.addEventListener('touchend', touchEnd, false)
}
init()
}
})
}
}
.dragable {
z-index: 2;
display: flex;
}
.dragable.fix {
z-index: 1;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.ease {
transition: all 0.3s linear;
}
import Drag from './directive/drag'
Vue.use(Drag)
<template>
<div class="content-inner" v-drag="goods.distance">
</div>
</template> |
Vue 插件编写dem01
import ShareModal from "./ShareModal.vue";
let $vm;
const optionsDefaults = {};
export default {
install(Vue, opts) {
console.log("share");
const options = { ...optionsDefaults, ...opts };
if (!$vm) {
let ShareModalComponent = Vue.extend(ShareModal);
$vm = new ShareModalComponent({
el: document.createElement("div")
});
document.body.appendChild($vm.$el);
Vue.prototype.$shareModal = $vm;
}
return $vm;
}
};
<template>
<div class="share_modal-container" :class="{show :isShowShareTip}" @click="hide">
<img :src="shareImage" alt="分享提示" class="share-tip" />
</div>
</template>
<script lang="ts">
import { Component, Prop, Vue } from "vue-property-decorator";
@Component({
filters: {}
})
export default class ShareModal extends Vue {
@Prop() private category?: string; //
private isShowShareTip: boolean = true;
private shareImage: string = require("./shareTip.png");
async mounted() {}
show() {
this.isShowShareTip = true;
}
hide() {
this.isShowShareTip = false;
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="less">
.share_modal-container {
opacity: 0;
position: fixed;
top: 0;
left: 0;
display: flex;
align-items: center;
justify-content: center;
width: 100vw;
height: 100vh;
background-color: rgba(0, 0, 0, 0.73);
&>.share-tip{
position: absolute;
display: flex;
top:0;
right:0;
width: 50vw;
}
}
.share_modal-container.show {
opacity: 1;
}
</style>
import Vue from "vue";
import App from "./App.vue";
import "./registerServiceWorker";
import router from "./router";
import store from "./store";
//plugins
import ShareModal from './plugins/ShareModal'
Vue.use(ShareModal)
Vue.config.productionTip = false;
new Vue({
router,
store,
render: h => h(App)
}).$mount("#app"); demo2
<template>
<div class="exchange_currency-container" :class="{show :isShow}">
<div class="wrapper">
<div class="current-currency-wrapper">
抢到
<span class="current-currency">{{currentCurrency}}</span>个折扣兑换币
</div>
<div class="total-currency-wrapper">
当前共获得:
<span class="total-currency">{{totalCurrency}}</span>个
<span class="redeem" @click="goDiscountShop">去兑换>></span>
</div>
<img :src="redEnvelopeImage" alt="红包" class="celebrate" />
<div class="tip-wrapper">
<span class="tip">*折扣兑换币可在折扣商城兑换</span>
<span class="tip-important">超低折扣商品</span>
</div>
<img :src="grabImage" alt="继续摇" class="grab" @click="handleContinueShake" />
<img :src="closeImage" alt="关闭" class="close" @click="handleCloseModal" />
</div>
</div>
</template>
<script lang="ts">
import { Component, Prop, Vue } from "vue-property-decorator";
import Store from "../../store";
const store = new Store();
import { options } from "./type";
@Component({
filters: {
numberToTimeString(number: number) {
if (number < 0) {
return "00";
}
if (number > 0 && number < 10) {
return `0${number}`;
}
return number;
}
}
})
export default class ExchangeCurrency extends Vue {
private isShow: boolean = false;
private closeImage: string = require("../../assets/modal/close.png");
private redEnvelopeImage: string = require("../../assets/modal/redEnvelope.png");
private grabImage: string = require("../../assets/modal/grab.png");
private currentCurrency: number = 0; // 本次摇一摇获得的兑换币
private totalCurrency: number = 0;
async mounted() {}
show(options: options) {
const { currentCurrency, totalCurrency } = options;
this.currentCurrency = currentCurrency;
this.totalCurrency = totalCurrency;
console.log("options", options);
this.isShow = true;
}
goDiscountShop() {
this.isShow = false;
this.$emit("goExchange", 222);
}
handleContinueShake(){
this.$emit("continueShake", 111);
this.isShow = false;
}
handleCloseModal() {
this.isShow = false;
this.$emit('hide')
}
onExchange() {}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="less">
.exchange_currency-container {
position: fixed;
top: 0;
left: 0;
z-index: -1;
opacity: 0;
display: flex;
align-items: center;
justify-content: center;
width: 100vw;
height: 100vh;
background-color: rgba(0, 0, 0, 0.73);
transition: all 0.2s ease-in-out;
& > .wrapper {
display: flex;
flex-direction: column;
align-items: center;
& > .current-currency-wrapper {
display: flex;
flex-direction: row;
align-items: baseline;
font-size: 0.2rem;
color: #fff;
font-family: "思源黑体 CN";
font-weight: bold;
margin-bottom: 0.06rem;
& > .current-currency {
display: table-cell;
vertical-align: bottom;
font-size: 0.31rem;
color: #f6cb8a;
font-family: "思源黑体 CN";
font-weight: heavy;
margin-left: 0.07rem;
margin-right: 0.07rem;
}
}
& > .total-currency-wrapper {
display: flex;
align-items: baseline;
font-size: 0.17rem;
color: #fff;
font-family: "思源黑体 CN";
font-weight: regular;
margin-bottom: 0.25rem;
& > .total-currency {
font-size: 0.22rem;
color: #f6cb8a;
font-family: "思源黑体 CN";
font-weight: regular;
margin-left: 0.03rem;
margin-right: 0.03rem;
}
& > .redeem {
font-size: 0.17rem;
color: #f89c65;
font-family: "思源黑体 CN";
font-weight: regular;
margin-left: 0.17rem;
text-decoration: underline;
}
}
& > .celebrate {
display: flex;
width: 2.585rem;
height: 1.69rem;
margin-bottom: 0.21rem;
}
& > .tip-wrapper {
display: flex;
flex-direction: row;
align-items: center;
font-size: 0.13rem;
color: #fff;
font-family: "思源黑体 CN";
font-weight: regular;
margin-bottom: 0.18rem;
& > .tip {
}
& > .tip-important {
color: #f9532d;
font-weight: bold;
}
}
& > .grab {
display: flex;
width: 1.975rem;
height: 0.39rem;
margin-bottom: 0.32rem;
}
& > .close {
display: flex;
width: 0.34rem;
height: 0.34rem;
}
}
}
.exchange_currency-container.show {
z-index: 1;
opacity: 1;
transition: all 0.2s ease-in-out;
}
</style>
import ExchangeCurrency from "./ExchangeCurrency.vue";
import { options } from "./type";
let $vm;
const optionsDefaults = {};
type opts = {
options: options;
};
export default {
install(Vue, opts?: opts) {
const options = { ...optionsDefaults, ...opts };
if (!$vm) {
let ExchangeCurrencyComponent = Vue.extend(ExchangeCurrency);
$vm = new ExchangeCurrencyComponent({
data: options,
el: document.createElement("div")
});
document.body.appendChild($vm.$el);
Vue.$exchangeCurrency = Vue.prototype.$exchangeCurrency = $vm;
}
return $vm;
}
};
export interface options {
currentCurrency: number; // 本次摇一摇获得的兑换币
totalCurrency: number; // 累计获得的兑换币
} 全局引用import ExchangeCurrency from "./plugins/ExchangeCurrency";
Vue.use(ExchangeCurrency); 使用// 显示
this.$exchangeCurrency.show({
currentCurrency: 6, //摇到的兑换币数量
totalCurrency: 20 // 总兑换币数量
});
// 隐藏 [或点击弹窗隐藏自身]
this.$exchangeCurrency.hide();
// 监听 去兑换事件
this.$exchangeCurrency.$on("goExchange", e => {
console.log("回调", e);
this.$router.replace({
path: `/discountShop/${store.userInfo.openid || "default"}`
});
});
// 监听 继续摇 事件
this.$exchangeCurrency.$on("continueShake", e => {
console.log("回调2", e);
});
// 监听 兑换币窗口关闭
this.$exchangeCurrency.$on("hide", () => {
console.log("关闭兑换币");
}); |
Open
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
安装,升级,卸载
在声明组件时,使用基于类(class-based)的 API,则可以使用官方维护的 vue-class-component 装饰器:
Vue
vue 组件
The text was updated successfully, but these errors were encountered: