vue项目中使用代码编辑器,视频播放器插件

1、Vue-代码编辑器插件

1)安装

npm install monaco-editor --save
npm install monaco-editor-webpack-plugin --save-dev # webpack 4.x 以上版本不需要,可以试一下

2) vue.config.js中添加

const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin')

// webpack 配置
chainWebpack(config) {
	config.plugin('monaco').use(new MonacoWebpackPlugin()) // monaco-editor
}

在这里插入图片描述在这里插入图片描述

3)使用

(1)封装组件MonacoEditor目录下,index.vue
<template>
  <div>
    <div id="code-editor" :style=" 'width: '+width+'px; height:' +height+'px; border:1px solid grey;'"></div>
  </div>
</template>

<script>
import * as monaco from 'monaco-editor'
import { getJsonPath } from '@/api/jsonpath'
export default {
  name: 'index',
  model: {
    prop: 'content',
    event: 'change'
  },
  props: {
    'content': null,
    'language': {
      default: 'javascript'
    },
    'readOnly': {
      default: false
    },
    'theme': {
      default: 'vs-dark'
    },
    'fontSize': {
      default: 20
    },
    'width': {
      default: 1000
    },
    'height': {
      default: 500
    }
  },
  data: function () {
    return {
      editor: null,
      jsonPath: null,
      // languages: ['abap', 'apex', 'azcli', 'bat', 'cameligo', 'clojure', 'coffee', 'cpp', 'csharp', 'csp', 'css', 'dockerfile', 'fsharp', 'go', 'graphql', 'handlebars', 'html', 'ini', 'java', 'javascript', 'json', 'kotlin', 'less', 'lua', 'markdown', 'mips', 'msdax', 'mysql', 'objective-c', 'pascal', 'pascaligo', 'perl', 'pgsql', 'php', 'postiats', 'powerquery', 'powershell', 'pug', 'python', 'r', 'razor', 'redis', 'redshift', 'restructuredtext', 'ruby', 'rust', 'sb', 'scheme', 'scss', 'shell', 'solidity', 'sophia', 'sql', 'st', 'swift', 'tcl', 'twig', 'typescript', 'vb', 'xml', 'yaml'],
      option: {
        value: this.content, // 编辑器初始显⽰⽂字
        language: this.language, // 语⾔⽀持⾃⾏查阅demo
        readOnly: this.readOnly, // 是否为只读模式
        fontSize: this.fontSize,
        acceptSuggestionOnCommitCharacter: true, // 接受关于提交字符的建议
        acceptSuggestionOnEnter: 'on', // 接受输入建议 "on" | "off" | "smart"
        accessibilityPageSize: 10, // 辅助功能页面大小 Number 说明:控制编辑器中可由屏幕阅读器读出的行数。警告:这对大于默认值的数字具有性能含义。
        accessibilitySupport: 'on', // 辅助功能支持 控制编辑器是否应在为屏幕阅读器优化的模式下运行。
        autoClosingBrackets: 'always', // 是否自动添加结束括号(包括中括号) "always" | "languageDefined" | "beforeWhitespace" | "never"
        autoClosingDelete: 'always', // 是否自动删除结束括号(包括中括号) "always" | "never" | "auto"
        autoClosingOvertype: 'always', // 是否关闭改写 即使用insert模式时是覆盖后面的文字还是不覆盖后面的文字 "always" | "never" | "auto"
        autoClosingQuotes: 'always', // 是否自动添加结束的单引号 双引号 "always" | "languageDefined" | "beforeWhitespace" | "never"
        autoIndent: 'always', // 控制编辑器在用户键入、粘贴、移动或缩进行时是否应自动调整缩进
        automaticLayout: true, // 自动布局
        codeLens: true, // 是否显示codeLens 通过 CodeLens,你可以在专注于工作的同时了解代码所发生的情况 – 而无需离开编辑器。 可以查找代码引用、代码更改、关联的 Bug、工作项、代码评审和单元测试。
        codeLensFontFamily: '', // codeLens的字体样式
        codeLensFontSize: 20, // codeLens的字体大小
        colorDecorators: true, // 呈现内联色彩装饰器和颜色选择器
        foldingStrategy: 'indentation', // 代码可分⼩段折叠
        comments: {
          ignoreEmptyLines: true, // 插入行注释时忽略空行。默认为真。
          insertSpace: true // 在行注释标记之后和块注释标记内插入一个空格。默认为真。
        }, // 注释配置
        contextmenu: true, // 启用上下文菜单
        columnSelection: true, // 启用列编辑 按下shift键位然后按↑↓键位可以实现列选择 然后实现列编辑
        autoSurround: 'never', // 是否应自动环绕选择
        copyWithSyntaxHighlighting: true, // 是否应将语法突出显示复制到剪贴板中 即 当你复制到word中是否保持文字高亮颜色
        cursorBlinking: 'Solid', // 光标动画样式
        cursorSmoothCaretAnimation: true, // 是否启用光标平滑插入动画  当你在快速输入文字的时候 光标是直接平滑的移动还是直接"闪现"到当前文字所处位置
        cursorStyle: 'UnderlineThin', // "Block"|"BlockOutline"|"Line"|"LineThin"|"Underline"|"UnderlineThin" 光标样式
        cursorSurroundingLines: 0, // 光标环绕行数 当文字输入超过屏幕时 可以看见右侧滚动条中光标所处位置是在滚动条中间还是顶部还是底部 即光标环绕行数 环绕行数越大 光标在滚动条中位置越居中
        cursorSurroundingLinesStyle: 'all', // "default" | "all" 光标环绕样式
        cursorWidth: 2, // <=25 光标宽度
        minimap: {
          enabled: true // 是否启用预览图
        }, // 预览图设置
        folding: true, // 是否启用代码折叠
        links: true, // 是否点击链接
        overviewRulerBorder: true, // 是否应围绕概览标尺绘制边框
        renderLineHighlight: 'line', // 当前行突出显示方式
        roundedSelection: true, // 选区是否有圆角
        scrollBeyondLastLine: true, // 设置编辑器是否可以滚动到最后一行之后
        theme: this.theme// vs, hc-black, or vs-dark
      }
    }
  },
  watch: {
    content: function (newValue) {
      console.debug('Code editor: content change')
      if (this.editor) {
        if (newValue !== this.editor.getValue()) {
          monaco.editor.setModelLanguage(this.editor.getModel(), this.language)
          this.editor.setValue(newValue)
          this.editor.trigger(this.editor.getValue(), 'editor.action.formatDocument')
        }
      }
    }
  },
  mounted: function () {
    const copyToClipboard = this.copyToClipboard
    this.editor = monaco.editor.create(
      this.$el.querySelector('#code-editor'), this.option
      // {
      //   value: this.content,
      //   language: this.language,
      //   theme: 'vs',
      //   readOnly: this.readOnly,
      //   automaticLayout: true
      // }
    )
    this.editor.addAction({
      id: 'json-path',
      label: 'Copy JsonPath',
      keybindings: [
        monaco.KeyMod.chord(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KEY_J)
      ],
      precondition: "editorLangId == 'json'",
      keybindingContext: "editorLangId == 'json'",
      contextMenuGroupId: '9_cutcopypaste',
      contextMenuOrder: 2,
      run: copyToClipboard
    })
    this.editor.onDidChangeModelContent(event => {
      const value = this.editor.getValue()
      if (this.value !== value) {
        this.$emit('change', value, event)
      }
    })
    this.editor.onDidChangeCursorPosition(event => {
      const value = this.editor.getValue()
      const offSet = this.editor.getModel().getOffsetAt(event.position)
      const language = this.language
      if (this.value !== value && language === 'json') {
        this.$emit('on-cursor-change', { offSet: offSet })
      }
      if (language === 'json' && offSet !== 0) {
        this.jsonPath = getJsonPath(value, offSet)
        this.$emit('on-jsonpath-change', { jsonPath: this.jsonPath })
      }
    })
  },
  methods: {
    copyToClipboard () {
      const notification = this.$Notice
      if (this.jsonPath) {
        navigator.clipboard.writeText(this.jsonPath)
          .then(function () { }, function () {
            notification.error({
              title: 'jsonpath copy failed.'
            })
          }
          )
      } else {
        notification.warning({
          title: 'There is no jsonpath that can be copied.'
        })
      }
    }
  }
}
</script>
(2)使用组件
<template>
  <div style="margin: 0 auto">
    <el-row>
      <el-col :span="2">
        <el-select v-model="code.language" @change="setLanguage" filterable placeholder="请选择语言" style="width: 100%">
          <el-option
            v-for="item in languages"
            :key="item.name"
            :label="item.name"
            :value="item">
          </el-option>
        </el-select>
      </el-col>
      <el-col :span="2">
        <el-tooltip class="item" effect="dark" content="温馨提示:该编译器暂不支持数据动态输入" placement="right">
          <el-button @click="run" type="success" icon="el-icon-caret-right">运行</el-button>
        </el-tooltip>
      </el-col>
      <el-col :span="1" style="margin-left: -25px">
        <el-button @click="dialogFormVisible = true">输入</el-button>
      </el-col>
      <el-col style="padding-top: 10px; padding-left: 20px" :span="10" v-if="elapsedTime >= 0">
        运行时间:{{elapsedTime}} Ms
      </el-col>
    </el-row>
    <!-- 输入参数区 -->
    <el-dialog
      title="参数输入"
      :visible.sync="dialogFormVisible"
      width="30%"
      center>
      <div>
        <el-input
          type="textarea"
          :rows="2"
          placeholder="请输入参数"
          v-model="code.params">
        </el-input>
      </div>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">取 消</el-button>
        <el-button type="primary" @click="dialogFormVisible = false">确 定</el-button>
      </div>
    </el-dialog>
    <div>
      <!-- 代码编辑框 -->
      <div style="float: left">
        <monaco-editor
          v-model="code.content"
          :language="language"
          width='700'
          height='500'
          :readOnly="false">
        </monaco-editor>
      </div>
      <!-- 结果展示框-->
      <div style="float: left; margin-left: -1px">
        <monaco-editor
          v-model="result"
          :language="language"
          width='500'
          height='500'
          readOnly="true">
        </monaco-editor>
      </div>
    </div>
  </div>
</template>

<script>
import MonacoEditor from '@/components/MonacoEditor'
import codeApi from '@/api/codeSubmit'

export default {
  components: {
    MonacoEditor
  },
  name: 'JsonEditor',
  data () {
    return {
      code: {
        content: null,
        language: 'java',
        params: ''
      },
      language: '',
      elapsedTime: -1,
      dialogFormVisible: false,
      result: null,
      languages: [
        { name: 'Java', language: 'java', value: ['java', 'java-1_8_0', 'java-11_0_11', 'java-16_0_1'] },
        { name: 'C语言', language: 'c', value: ['c', 'c-gcc7_5_0'] },
        { name: 'Python', language: 'python', value: ['py', 'py-3_6_9', 'py-2_7_17'] },
        { name: 'C++', language: 'cpp', value: ['cpp', 'cpp-gcc7_5_0'] },
        { name: 'PHP', language: 'php', value: ['php', 'php-8_0_3', 'php-7_4_16'] },
        { name: 'C#', language: 'csharp', value: ['cs', 'cs-_NET2_2_402'] },
        { name: 'Go语言', language: 'go', value: ['go', 'go-1_16_3', 'go-1_10_4'] },
        { name: 'R', language: 'r', value: ['r', 'r-4_0_1'] },
        { name: 'MySQL', language: 'mysql', value: ['mysql', 'mysql-5_7_31'] },
        { name: 'JS', language: 'javascript', value: ['js', 'js-14_16_1', 'js-10_16_0'] },
        { name: 'Ruby', language: 'ruby', value: ['ruby', 'ruby-2_5_1'] },
        // { name: 'Groovy', language: '', value: ['groovy', 'groovy-2_4_16'] },
        { name: 'Shell/Bash', language: 'shell', value: ['sh'] },
        { name: 'Lua', language: 'lua', value: ['lua', 'lua-5_3_3'] },
        { name: 'Objc', language: 'objective-c', value: ['objc', 'objc-gcc7_5_0'] },
        { name: 'F#', language: 'fsharp', value: ['fsharp', 'fsharp-_NET2_2_402'] },
        { name: 'VB.NET', language: 'vb', value: ['vb', ' vb-_NET2_2_402'] },
        { name: 'Swift', language: 'swift', value: ['swift', 'swift-5_2_4'] },
        { name: 'Dart', language: 'dart', value: ['dart', 'dart-2_8_4'] },
        { name: 'Clojure', language: 'clojure', value: ['clojure', 'clojure-1_9_0'] },
        { name: 'Kotlin', language: 'kotlin', value: ['kotlin', 'kotlin-1_3_72'] },
        { name: 'Rust', language: 'rust', value: ['rust', 'rust-1_27_1'] },
        { name: 'Pascal', language: 'pascal', value: ['pascal', 'pascal-3_0_4'] },
        { name: 'Perl', language: 'perl', value: ['perl', 'perl-5_30_3'] },
        // { name: 'Erlang', language: '', value: ['erlang', 'erlang-9_2'] },
        { name: 'Scala', language: 'scala', value: ['scala', 'scala-2_13_2'] }
        // { name: 'Haskell', language: '', value: ['haskell', 'haskell-8_0_2'] },
        // { name: 'Nim', language: '', value: ['nim', 'nim-0_17_2'] },
        // { name: 'Lisp', language: '', value: ['list', 'list-2_49_60'] },
        // { name: 'Ocaml', language: '', value: ['ocaml', 'ocaml-4_05_0'] },
        // { name: 'Racket', language: '', value: ['racket', 'racket-6_11'] },
        // { name: 'SQLite', language: '', value: ['sqlite', 'sqlite-2_8_17', 'sqlite-3_22_0'] },
        // { name: 'NASM', language: '', value: ['nasm', 'nasm-2_13_02'] },
        // { name: 'D', language: '', value: ['d', 'd-gcc8_4_0'] },
        // { name: 'Fortran', language: '', value: ['fortran', 'fortran-gfortran7_5_0'] }
      ]
    }
  },
  methods: {
    setLanguage (row) {
      console.log(this.code.language)
      this.code.language = row.value[0]
      console.log(this.code.language)
      this.language = row.language
    },
    run () {
      if (!this.code.content) {
        this.$message.warning('请输入代码在运行')
        return false
      }
      codeApi.runCode(this.code).then(re => {
        console.log(re.data.body)
        if (re.code === 1) {
          this.$message.success(re.message)
          let body = JSON.parse(re.data.body)
          let data = JSON.parse(body.data)
          this.elapsedTime = data.elapsedTime
          this.result = data.result
        } else {
          let data = JSON.parse(re.data)
          this.$message.error(re.msg)
          this.result = data.result
        }
      })
    }
  }
}
</script>

<style scoped>
  .el-col {
    margin: 2px 10px;
  }
</style>

2、Vue-视频播放插件vue-video-player的配置及简单使用

1.安装

npm install vue-video-player --save

2. 引入

全局引用 在main.js里面导入并引用

import VideoPlayer from 'vue-video-player'

// 引入方式一
import 'vue-video-player/src/custom-theme.css'
import 'video.js/dist/video-js.css'

// 引入方式二
require('video.js/dist/video-js.css')
require('vue-video-player/src/custom-theme.css')

Vue.use(VideoPlayer)

3. 使用

1)封装组件VideoPlayer目录下,index.vue
<template>
  <div class='demo' :style="'width:'+width+'%;margin: 0 auto'">
    <video-player class="video-player vjs-custom-skin"
                  ref="videoPlayer"
                  :playsinline="true"
                  :options="playerOptions"
                  @play="onPlayerPlay($event)"
                  @pause="onPlayerPause($event)"
                  @ended="onPlayerEnded($event)"
                  @waiting="onPlayerWaiting($event)"
                  @playing="onPlayerPlaying($event)"
                  @loadeddata="onPlayerLoadeddata($event)"
                  @timeupdate="onPlayerTimeupdate($event)"
                  @canplay="onPlayerCanplay($event)"
                  @canplaythrough="onPlayerCanplaythrough($event)"
                  @statechanged="playerStateChanged($event)"
                  @ready="playerReadied">
    </video-player>
  </div>
</template>

<script>
export default {
  name: 'index',
  props: {
    // 播放地址
    src: {
      type: String,
      default: ''
    },
    // 封面地址
    poster: {
      type: String,
      default: ''
    },
    // 自动播放
    autoplay: {
      type: Boolean,
      default: false
    },
    // 结束就重新开始
    loop: {
      type: Boolean,
      default: false
    },
    // 语言
    language: {
      type: String,
      default: 'zh-CN'
    },
    width: {
      type: Number,
      default: 50
    }
  },
  data () {
    return {
      playerOptions: {
        playbackRates: [0.5, 1.0, 1.5, 2.0, 2.5, 3.0], // 可选的播放速度
        autoplay: this.autoplay, // 如果为true,浏览器准备好时开始回放
        muted: false, // 默认情况下将会消除任何音频。
        loop: this.loop, // 是否视频一结束就重新开始。
        preload: 'auto', // 建议浏览器在<video>加载元素后是否应该开始下载视频数据。auto浏览器选择最佳行为,立即开始加载视频(如果浏览器支持)
        language: this.language,
        aspectRatio: '16:9', // 将播放器置于流畅模式,并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字(例如"16:9"或"4:3")
        fluid: true, // 当true时,Video.js player将拥有流体大小。换句话说,它将按比例缩放以适应其容器。
        sources: [{
          type: 'video/mp4', // 类型
          src: this.src // url地址
        }],
        poster: this.poster, // 封面地址
        notSupportedMessage: '此视频暂无法播放,请稍后再试', // 允许覆盖Video.js无法播放媒体源时显示的默认信息。
        controlBar: {
          timeDivider: true, // 当前时间和持续时间的分隔符
          durationDisplay: true, // 显示持续时间
          remainingTimeDisplay: true, // 是否显示剩余时间功能
          fullscreenToggle: true // 是否显示全屏按钮
        }
      }
    }
  },
  methods: {
    // 播放回调
    onPlayerPlay (player) {
      console.log('player play!', player)
    },

    // 暂停回调
    onPlayerPause (player) {
      console.log('player pause!', player)
    },

    // 视频播完回调
    onPlayerEnded (player) {
      console.log(player)
    },

    // DOM元素上的readyState更改导致播放停止
    onPlayerWaiting (player) {
      console.log(player)
    },

    // 已开始播放回调
    onPlayerPlaying (player) {
      console.log(player)
    },

    // 当播放器在当前播放位置下载数据时触发
    onPlayerLoadeddata (player) {
      console.log(player)
    },

    // 当前播放位置发生变化时触发
    onPlayerTimeupdate (player) {
      console.log(player)
    },

    // 媒体的readyState为HAVE_FUTURE_DATA或更高
    onPlayerCanplay (player) {
      // console.log('player Canplay!', player)
    },

    // 媒体的readyState为HAVE_ENOUGH_DATA或更高。这意味着可以在不缓冲的情况下播放整个媒体文件
    onPlayerCanplaythrough (player) {
      // console.log('player Canplaythrough!', player)
    },

    // 播放状态改变回调
    playerStateChanged (playerCurrentState) {
      console.log('player current update state', playerCurrentState)
    },

    // 将侦听器绑定到组件的就绪状态。与事件监听器的不同之处在于,如果ready事件已经发生,它将立即触发该函数
    playerReadied (player) {
      console.log('example player 1 readied', player);
    }
  }
}
</script>

<style scoped>
  .video-js .vjs-icon-placeholder {
    width: 100%;
    height: 100%;
    display: block;
  }

</style>
2)使用组件
<template>
    <VideoPlayer :src="src"></VideoPlayer>
</template>

<script>
// 引入组件
import VideoPlayer from '@/components/VideoPlayer'
export default {
  // 添加组件
  components: { VideoPlayer },
  name: 'video',
  data(){
      return{
          src: ''
      }
  }
}
</script>

<style scoped>

</style>

3、Avue的使用

1、安装和引入

安装:

npm i @smallwei/avue -S

引入:

// 引入
import Avue from '@smallwei/avue';
import '@smallwei/avue/lib/index.css';
Vue.use(Avue);

2、简单使用

1)表格导出xlsx表格

引入

<!-- 导入需要的包 (一定要放到index.html中的head标签里)-->
<script src="https://cdn.staticfile.org/FileSaver.js/2014-11-29/FileSaver.min.js"></script>
<script src="https://cdn.staticfile.org/xlsx/0.18.2/xlsx.full.min.js"></script>

使用:
将option中的属性excelBtn设置为true即可开启导出功能

<avue-crud :option="option" :data="data"></avue-crud>
<script>
export default {
  data(){
    return {
       data:[{
          text1:'内容1-1',
          text2:'内容1-2',
          deep:{
             text3:'内容1-3',
          }
       },{
          text1:'内容2-1',
          text2:'内容2-2',
          deep:{
             text3:'内容2-3',
          }
       }],
       option:{
          excelBtn:true,
          column: [{
            label: '列内容1',
            prop: 'text1',
          }, {
            label: '列内容2',
            prop: 'text2',
          }, {
            label: '列内容3',
            prop: 'text3',
            bind:'deep.text3'
          }]
       }
    }
  }
}
</script>

大问题

在这里插入图片描述解决办法:
在安装内容的命令后面加上

--legacy-peer-deps
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

向山海出发

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值