国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

node.js|vue.js|jquery|angularjs|React|json|js教程|

服務(wù)器之家 - 編程語言 - JavaScript - 實用的 vue tags 創(chuàng)建緩存導(dǎo)航的過程實現(xiàn)

實用的 vue tags 創(chuàng)建緩存導(dǎo)航的過程實現(xiàn)

2021-12-02 16:10Leo_噠噠 JavaScript

這篇文章主要介紹了實用的 vue tags 創(chuàng)建緩存導(dǎo)航的過程實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

需求

是要做一個tag,當(dāng)切換頁面的時候保留狀態(tài)。

效果圖:

實用的 vue tags 創(chuàng)建緩存導(dǎo)航的過程實現(xiàn)

思路

既然涉及了router跳轉(zhuǎn),那我們就去查api 發(fā)現(xiàn)keep-alive,巧了就用它吧。這里我們用到了include屬性,該屬性接受一個數(shù)組,當(dāng)組件的name名稱包含在inclue里的時候就會觸發(fā)keep-alive。

import { Vue, Component, Watch, Mixins } from "vue-property-decorator";

// 此處省略n行代碼

// 這是個計算屬性。(至于為什么這么寫 這里就不介紹了。)
get cachedViews():string[] {
 return this.$store.state.tagsView.cachedViews;
}

// 此處省略n行代碼

<keep-alive :include="cachedViews">
 <router-view :key="key"></router-view>
</keep-alive>

那我們接下來就處理cachedViews變量就好了。

vuex實現(xiàn)

import { Route } from "vue-router"; // 檢測規(guī)則

interface TagsState{
 visitedViews: Route[];
 cachedViews: string[];
}

const state = (): TagsState => ({
 visitedViews: [], // 展示的菜單
 cachedViews: [], // 緩存菜單 用來activeed
});

const mutations = {
 ADD_VISITED_VIEW: (state: TagsState, view: Route) => {
 if (state.visitedViews.some((v: any) => v.path === view.path)) { return; }
 state.visitedViews.push(
  Object.assign({}, view, {
  title: view.meta.title || "no-name",
  }),
 );
 },
 ADD_CACHED_VIEW: (state: TagsState, view: Route) => {
 if (state.cachedViews.includes(view.meta.name)) { return; }
 if (!view.meta.noCache) {
  state.cachedViews.push(view.meta.name);
 }
 },

 DEL_VISITED_VIEW: (state: TagsState, view: Route) => {
 for (const [i, v] of state.visitedViews.entries()) {
  if (v.path === view.path) {
  state.visitedViews.splice(i, 1);
  break;
  }
 }
 },
 DEL_CACHED_VIEW: (state: TagsState, view: Route) => {
 const index = state.cachedViews.indexOf(view.meta.name);
 index > -1 && state.cachedViews.splice(index, 1);
 },

 DEL_OTHERS_VISITED_VIEWS: (state: TagsState, view: Route) => {
 state.visitedViews = state.visitedViews.filter((v: any) => {
  return v.meta.affix || v.path === view.path;
 });
 },
 DEL_OTHERS_CACHED_VIEWS: (state: TagsState, view: Route) => {
 const index = state.cachedViews.indexOf(view.meta.name);
 if (index > -1) {
  state.cachedViews = state.cachedViews.slice(index, index + 1);
 } else {
  // if index = -1, there is no cached tags
  state.cachedViews = [];
 }
 },

 DEL_ALL_VISITED_VIEWS: (state: TagsState) => {
 // keep affix tags
 const affixTags = state.visitedViews.filter((tag: any) => tag.meta.affix);
 state.visitedViews = affixTags;
 },
 DEL_ALL_CACHED_VIEWS: (state: TagsState) => {
 state.cachedViews = [];
 },

 UPDATE_VISITED_VIEW: (state: TagsState, view: Route) => {
 for (let v of state.visitedViews) {
  if (v.path === view.path) {
  v = Object.assign(v, view);
  break;
  }
 }
 },
};

const actions = {
 addView({ dispatch }: any, view: Route) {
 dispatch("addVisitedView", view);
 dispatch("addCachedView", view);
 },
 addVisitedView({ commit }: any, view: Route) {
 commit("ADD_VISITED_VIEW", view);
 },
 addCachedView({ commit }: any, view: Route) {
 commit("ADD_CACHED_VIEW", view);
 },

 delView({ dispatch, state }: any, view: Route) {
 return new Promise((resolve) => {
  dispatch("delVisitedView", view);
  dispatch("delCachedView", view);
  resolve({
  visitedViews: [...state.visitedViews],
  cachedViews: [...state.cachedViews],
  });
 });
 },
 delVisitedView({ commit, state }: any, view: Route) {
 return new Promise((resolve) => {
  commit("DEL_VISITED_VIEW", view);
  resolve([...state.visitedViews]);
 });
 },
 delCachedView({ commit, state }: any, view: Route) {
 return new Promise((resolve) => {
  commit("DEL_CACHED_VIEW", view);
  resolve([...state.cachedViews]);
 });
 },

 delOthersViews({ dispatch, state }: any, view: Route) {
 return new Promise((resolve) => {
  dispatch("delOthersVisitedViews", view);
  dispatch("delOthersCachedViews", view);
  resolve({
  visitedViews: [...state.visitedViews],
  cachedViews: [...state.cachedViews],
  });
 });
 },
 delOthersVisitedViews({ commit, state }: any, view: Route) {
 return new Promise((resolve) => {
  commit("DEL_OTHERS_VISITED_VIEWS", view);
  resolve([...state.visitedViews]);
 });
 },
 delOthersCachedViews({ commit, state }: any, view: Route) {
 return new Promise((resolve) => {
  commit("DEL_OTHERS_CACHED_VIEWS", view);
  resolve([...state.cachedViews]);
 });
 },

 delAllViews({ dispatch, state }: any, view: Route) {
 return new Promise((resolve) => {
  dispatch("delAllVisitedViews", view);
  dispatch("delAllCachedViews", view);
  resolve({
  visitedViews: [...state.visitedViews],
  cachedViews: [...state.cachedViews],
  });
 });
 },
 delAllVisitedViews({ commit, state }: any) {
 return new Promise((resolve) => {
  commit("DEL_ALL_VISITED_VIEWS");
  resolve([...state.visitedViews]);
 });
 },
 delAllCachedViews({ commit, state }: any) {
 return new Promise((resolve) => {
  commit("DEL_ALL_CACHED_VIEWS");
  resolve([...state.cachedViews]);
 });
 },

 updateVisitedView({ commit }: any, view: Route) {
 commit("UPDATE_VISITED_VIEW", view);
 },
};

export default {
 namespaced: true,
 state,
 mutations,
 actions,
};

上面代碼,我們定義了一系列的對標(biāo)簽的操作。

組件實現(xiàn)

組件解構(gòu)如圖

實用的 vue tags 創(chuàng)建緩存導(dǎo)航的過程實現(xiàn)

TheTagsView.vue

<script lang="ts">
/**
 * @author leo
 * @description #15638 【test_tabs 組件】tab組件
 */
import { Component, Vue, Prop, Watch, Mixins } from "vue-property-decorator";
import ScrollPane from "./ScrollPane.vue";
import path from "path";

@Component({
 components: {
 ScrollPane,
 },
})
export default class TheTagsView extends Vue {
 get visitedViews() {
 return this.$store.state.tagsView.visitedViews; // 點開過的視圖
 }
 get routes() {
 return this.$store.state.permission.routes;
 }

 public visible: boolean = false; // 標(biāo)簽右鍵列表顯示隱藏
 public top: number = 0; // transform定位
 public left: number = 0; // transform定位
 public selectedTag: any = {}; // 當(dāng)前活躍的標(biāo)簽
 public affixTags: any[] = []; // 所有標(biāo)簽

 @Watch("$route")
 public watchRoute() {
 this.addTags(); // 新增當(dāng)前標(biāo)簽
 this.moveToCurrentTag(); // 刪除原活動標(biāo)簽
 }

 @Watch("visible")
 public watchVisible(value: any) {
 if (value) {
  document.body.addEventListener("click", this.closeMenu);
  } else {
  document.body.removeEventListener("click", this.closeMenu);
  }
 }

 public isActive(route: any) { // 是否當(dāng)前活動
 return route.path === this.$route.path;
 }

 public isAffix(tag: any) { // 是否固定
 return tag.meta && tag.meta.affix;
 }

 // 過濾當(dāng)前標(biāo)簽于路由
 public filterAffixTags(routes: any, basePath = "/") {
 let tags: any = [];
 routes.forEach((route: any) => {
  if (route.meta && route.meta.affix) {
  const tagPath = path.resolve(basePath, route.path);
  tags.push({
   fullPath: tagPath,
   path: tagPath,
   name: route.name,
   meta: { ...route.meta },
  });
  }
  if (route.children) {
  const tempTags = this.filterAffixTags(route.children, route.path);
  if (tempTags.length >= 1) {
   tags = [...tags, ...tempTags];
  }
  }
 });
 return tags;
 }

 public addTags() {
 const { name } = this.$route;
 if (name) {
  this.$store.dispatch("tagsView/addView", this.$route);
 }
 return false;
 }

 public moveToCurrentTag() {
 const tags: any = this.$refs.tag;
 this.$nextTick(() => {
  if (tags) {
  for (const tag of tags) {
   if (tag.to.path === this.$route.path) {
   (this.$refs.scrollPane as any).moveToTarget(tag);
   // when query is different then update
   if (tag.to.fullPath !== this.$route.fullPath) {
    this.$store.dispatch("tagsView/updateVisitedView", this.$route);
   }
   break;
   }
  }
  }
 });
 }
 public refreshSelectedTag(view: any) {
 this.$store.dispatch("tagsView/delCachedView", view).then(() => {
  const { fullPath } = view;
  this.$nextTick(() => {
  this.$router.replace({
   path: "/redirect" + fullPath,
  });
  });
  });
 }

 public closeSelectedTag(view: any) {
 this.$store.dispatch("tagsView/delView", view).then(({ visitedViews }) => {
  if (this.isActive(view)) {
  this.toLastView(visitedViews, view);
  }
 });
 }

 public closeOthersTags() {
 this.$router.push(this.selectedTag);
 this.$store.dispatch("tagsView/delOthersViews", this.selectedTag).then(() => {
  this.moveToCurrentTag();
 });
 }

 public closeAllTags(view: any) {
 this.$store.dispatch("tagsView/delAllViews").then(({ visitedViews }) => {
  if (this.affixTags.some((tag) => tag.path === view.path)) {
  return;
  }
  this.toLastView(visitedViews, view);
 });
 }

 public toLastView(visitedViews: any , view: any) {
 const latestView = visitedViews.slice(-1)[0];
 if (latestView) {
  this.$router.push(latestView.fullPath);
 } else {
  // now the default is to redirect to the home page if there is no tags-view,
  // you can adjust it according to your needs.
  if (view.name === "Dashboard") {
  // to reload home page
  this.$router.replace({ path: "/redirect" + view.fullPath });
  } else {
  this.$router.push("/");
  }
 }
 }
 public openMenu(tag: any , e: any) {
 const menuMinWidth = 105;
 const offsetLeft = this.$el.getBoundingClientRect().left; // container margin left
 const offsetWidth = this.$el.offsetWidth; // container width
 const maxLeft = offsetWidth - menuMinWidth; // left boundary
 const left = e.clientX - offsetLeft + 15 + 160; // 15: margin right

 if (left > maxLeft) {
  this.left = maxLeft;
 } else {
  this.left = left;
 }

 this.top = e.clientY;
 this.visible = true;
 this.selectedTag = tag;
 }

 public closeMenu() {
 this.visible = false;
 }

 public mounted() {
 this.initTags();
 this.addTags(); // 添加當(dāng)前頁面tag
 }
}
</script>

<template>
 <div id="tags-view-container" class="tags-view-container">
 <scroll-pane ref="scrollPane" class="tags-view-wrapper">
  <router-link
  v-for="(tag, index) in visitedViews"
  ref="tag"
  :key="tag.path"
  :class="isActive(tag)?"active":"""
  :to="{ path: tag.path, query: tag.query, fullPath: tag.fullPath }"
  tag="span"
  class="tags-view-item"
  @click.middle.native="!isAffix(tag)?closeSelectedTag(tag):"""
  @contextmenu.prevent.native="openMenu(tag,$event)"
  >
  {{ tag.title }}
  <!-- <span v-if="!isAffix(tag)" class="el-icon-close" @click.prevent.stop="closeSelectedTag(tag)" /> -->
  <span class="tab-border" v-if="index!==visitedViews.length-1"></span>
  </router-link>
 </scroll-pane>
 <ul v-show="visible" :style="{left:left+"px",top:top+"px"}" class="contextmenu">
  <li @click="refreshSelectedTag(selectedTag)">刷新</li>
  <li v-if="!isAffix(selectedTag)" @click="closeSelectedTag(selectedTag)">關(guān)閉當(dāng)前標(biāo)簽</li>
  <li @click="closeOthersTags">關(guān)閉其他標(biāo)簽</li>
  <li @click="closeAllTags(selectedTag)">關(guān)閉所有</li>
 </ul>
 </div>
</template>

<style lang="less" scoped>
.tags-view-container {
 height: 46px;
 width: 100%;
 background: #fff;
 .tags-view-wrapper {
 position: relative;
 .tags-view-item {
  display: inline-block;
  position: relative;
  cursor: pointer;
  height: 46px;
  line-height: 46px;
  // border: 1px solid #d8dce5;
  color: #495060;
  background: #fff;
  padding: 0 4px;
  font-size: 14px;
  .tab-border {
  display: inline-block;
  height: 10px;
  width: 1px;
  background: #f1f1f1;
  margin-left: 4px;
  }
  &:hover {
  border-bottom: 2px solid #666;
  }
  &.active {
  // background-color: #1F1A16;
  border-bottom: 2px solid #1F1A16;
  color: #333;
  // border-color: #1F1A16;
  // &::before {
  // content: "";
  // background: #fff;
  // display: inline-block;
  // width: 8px;
  // height: 8px;
  // border-radius: 50%;
  // position: relative;
  // margin-right: 2px;
  // }
  }
 }
 }
 .contextmenu {
 margin: 0;
 background: #fff;
 z-index: 3000;
 position: absolute;
 list-style-type: none;
 padding: 5px 0;
 border-radius: 4px;
 font-size: 12px;
 font-weight: 400;
 color: #333;
 box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, .3);
 li {
  margin: 0;
  padding: 7px 16px;
  cursor: pointer;
  &:hover {
  background: #eee;
  }
 }
 }
}
</style>

<style lang="less">
//reset element css of el-icon-close
.tags-view-wrapper {
 .tags-view-item {
 .el-icon-close {
  width: 16px;
  height: 16px;
  vertical-align: 3px;
  border-radius: 50%;
  text-align: center;
  transition: all .3s cubic-bezier(.645, .045, .355, 1);
  transform-origin: 100% 50%;
  &:before {
  transform: scale(.6);
  display: inline-block;
  vertical-align: -3px;
  }
  &:hover {
  background-color: #b4bccc;
  color: #fff;
  }
 }
 }
 .el-scrollbar__bar{
 pointer-events: none;
 opacity: 0;
 }
}
</style>

ScrollPane.vue

<script lang="ts">
/**
 * @author leo
 * @description #15638 【test_tabs 組件】tab組件
 */
import { Component, Vue, Prop, Watch, Mixins } from "vue-property-decorator";

const tagAndTagSpacing = 4; // tagAndTagSpacing

@Component({
 components: {
 ScrollPane,
 },
})
export default class ScrollPane extends Vue {
 get scrollWrapper() {
 return (this.$refs.scrollContainer as any).$refs.wrap;
 }

 public left: number = 0;

 public handleScroll(e: any) {
 const eventDelta = e.wheelDelta || -e.deltaY * 40;
 const $scrollWrapper = this.scrollWrapper;
 $scrollWrapper.scrollLeft = $scrollWrapper.scrollLeft + eventDelta / 4;
 }

 public moveToTarget(currentTag: any) {
 const $container = (this.$refs.scrollContainer as any).$el;
 const $containerWidth = $container.offsetWidth;
 const $scrollWrapper = this.scrollWrapper;
 const tagList: any = this.$parent.$refs.tag;

 let firstTag = null;
 let lastTag = null;

 // find first tag and last tag
 if (tagList.length > 0) {
  firstTag = tagList[0];
  lastTag = tagList[tagList.length - 1];
 }

 if (firstTag === currentTag) {
  $scrollWrapper.scrollLeft = 0;
 } else if (lastTag === currentTag) {
  $scrollWrapper.scrollLeft = $scrollWrapper.scrollWidth - $containerWidth;
 } else {
  // find preTag and nextTag
  const currentIndex = tagList.findIndex((item: any) => item === currentTag);
  const prevTag = tagList[currentIndex - 1];
  const nextTag = tagList[currentIndex + 1];

  // the tag"s offsetLeft after of nextTag
  const afterNextTagOffsetLeft = nextTag.$el.offsetLeft + nextTag.$el.offsetWidth + tagAndTagSpacing;

  // the tag"s offsetLeft before of prevTag
  const beforePrevTagOffsetLeft = prevTag.$el.offsetLeft - tagAndTagSpacing;

  if (afterNextTagOffsetLeft > $scrollWrapper.scrollLeft + $containerWidth) {
  $scrollWrapper.scrollLeft = afterNextTagOffsetLeft - $containerWidth;
  } else if (beforePrevTagOffsetLeft < $scrollWrapper.scrollLeft) {
  $scrollWrapper.scrollLeft = beforePrevTagOffsetLeft;
  }
 }
 }
}
</script>

<template>
 <el-scrollbar ref="scrollContainer" :vertical="false" class="scroll-container" @wheel.native.prevent="handleScroll">
 <slot />
 </el-scrollbar>
</template>

<style lang="less" scoped>
.scroll-container {
 white-space: nowrap;
 position: relative;
 overflow: hidden;
 width: 100%;
 .el-scrollbar__bar {
 bottom: 0px;
 }
 .el-scrollbar__wrap {
 height: 49px;
 }
}
</style>

index.ts

import TheTagsView from "./TheTagsView.vue";
export default TheTagsView;

這樣我們的組件就寫完啦,有哪里有問題的小伙伴可以留言哦。

組件調(diào)用

因為是全局的,所以放在全局下直接調(diào)用就好了

總結(jié)

這樣我們一個簡單的能實現(xiàn)alive 頁面的tag功能就實現(xiàn)了。大家趕緊嘗試一下吧~

兄臺,請留步。這里有幾點要注意一下哦~

問題1: 開發(fā)環(huán)境緩存住了,線上環(huán)境不好用了

我們是根據(jù)組件name值是否是include里包含的來判斷的。但是你會發(fā)現(xiàn)生產(chǎn)的的時候 class后面的名在線上被打包后變了。 什么?!這豈不是緩存不住了???是的。 所以解決辦法如圖。一般人我不告訴他0.o

實用的 vue tags 創(chuàng)建緩存導(dǎo)航的過程實現(xiàn)

問題2: tags的顯示名字我在哪定義呢

tags顯示的名字我怎么定義呢,好問題。小兄弟肯定沒有仔細(xì)讀代碼

ADD_VISITED_VIEW: (state: TagsState, view: Route) => {
 if (state.visitedViews.some((v: any) => v.path === view.path)) { return; }
 state.visitedViews.push(
  Object.assign({}, view, {
  title: view.meta.title || "no-name", /// 我在這里!!!!!
  }),
 );
 },

由上圖我們可知,我是在路由的配置里mate標(biāo)簽里的tile里配置的。至于你,隨你哦~

{
 	path: "index", // 入口
 name: "common-home-index-index",
 component: () => import(/* webpackChunkName: "auth" */ "@/views/home/index.vue"),
 meta: {
  title: "首頁", // 看見了么,我就是你要顯示的名字
  name: "CommonHome", // 記住,我要跟你的上面name頁面組件名字一樣
 },
}

問題3:我有的頁面,跳路由后想刷新了怎么辦

那我們頁面緩存住了,我怎么讓頁面刷新呢,比如我新增頁面,新增完了需要關(guān)閉當(dāng)前頁面跳回列表頁面的,我們的思路就是,關(guān)閉標(biāo)簽,url參數(shù)添加refresh參數(shù)

this.$store
   .dispatch("tagsView/delView", this.$route)
   .then(({ visitedViews }) => {
    EventBus.$emit("gotoOwnerDeliveryOrderIndex", {
    refresh: true,
    });
   });	

然后在activated鉤子里判斷下是否有這個參數(shù),

this.$route.query.refresh && this.fetchData();

記得處理完結(jié)果后吧refresh刪了,不然每次進來都刷新了,我們是在拉去數(shù)據(jù)的混合里刪的

if ( this.$route.query.refresh ) {
 this.$route.query.refresh = "";
}

問題4:有沒有彩蛋啊

有的,請看圖。 實用的 vue tags 創(chuàng)建緩存導(dǎo)航的過程實現(xiàn) 我的哥乖乖,怎么實現(xiàn)的呢。這個留給你們研究吧。上面代碼已經(jīng)實現(xiàn)了。只不過你需要在加一個頁面,跟路由。其實就是跳轉(zhuǎn)到一個新空頁面路由。重新跳回來一下~

redirect/index.vue

<script lang="ts">
import { Component, Vue, Prop, Watch, Mixins } from "vue-property-decorator";

@Component
export default class Redirect extends Vue {
 public created() {
 const { params, query } = this.$route;
 const { path } = params;
 // debugger;
 this.$router.replace({ path: "/" + path, query });
 }
}
</script>
<template>
</template>
/**
 * 刷新跳轉(zhuǎn)路由
 */
export const redirectRouter: any = {
 path: "/redirect",
 name: "redirect",
 component: RouterView,
 children: [
 {
  path: "/redirect/:path*",
  component: () => import(/* webpackChunkName: "redirect" */ "@/views/redirect/index.vue"),
  meta: {
  title: "title",
  },
 },
 ],
};

參考

https://github.com/PanJiaChen/vue-element-admin

到此這篇關(guān)于實用的 vue tags 創(chuàng)建緩存導(dǎo)航的過程的文章就介紹到這了,更多相關(guān)實用的 vue tags 創(chuàng)建緩存導(dǎo)航的過程內(nèi)容請搜索服務(wù)器之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持服務(wù)器之家!

原文鏈接:https://juejin.cn/post/6901576100531404813

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 黄毛片网站 | 久久精品国产清自在天天线 | 日韩欧美一区二区三区 | 成人综合网站 | 国产成人精品一区二区三区网站观看 | 午夜网| 日韩电影一区二区三区 | 成人在线不卡 | 国产黄色电影 | 久久精品影片 | 久久精品xx老女人老配少 | 一级爱 | 欧美精品久久久 | 中文字幕成人在线 | 成人午夜影院 | 亚洲专区欧美 | 99精品久久| 淫语视频 | 日韩精品一区二区在线观看 | 成人在线一级片 | av中文字幕在线观看 | 做a视频免费观看 | 国产午夜一区二区三区 | 视频一区中文字幕 | 久久亚洲一区二区 | 国产精品69久久久久水密桃 | 综合伊人| 中文字幕一区二区三区在线视频 | 亚洲九区 | 91精品国产乱码久久久久久 | 99久色 | 在线播放亚洲 | 精品国产一二三区 | 99久久婷婷国产综合精品电影 | 日韩高清中文字幕 | 一区二区三区久久 | 日韩视频一区二区 | 国产欧美日韩综合精品一区二区 | 四虎免费紧急入口观看 | 91精品国产乱码久久久久久久久 | 亚洲午夜网 |