ace-builds在nuxtjs项目中使用最全攻略,自用,建议收藏用到的时候直接使用。

1,624 阅读4分钟

在nuxtjs中需要用到编辑器,nuxtjs会在node环境运行,导致插件总会报window或document的错,在尝试了多个编辑器之后,最终选择了ace,也是各种查找,现总结一下,方便之后自己再用。如果只是单纯的vue或react项目,推荐使用的微软开发的monaco-editor

安装

npm install ace-duilds

建议拆封成全局组件,在组要用到的地方直接引入使用

  • 在components文件夹中创建 GlobalAce.vue文件
<template>
  <div class="ace-container">
    <!-- 编辑器容器 -->
    <div
      ref="ace"
      :value="value"
      class="ace-editor"/>
    <!-- 右下角选项 -->
    <div
      v-show="toggle"
      class="config-panel">
      <div>
        <!-- 目前支持7种语言 -->
        <div class="item">
          <label class="title">语言</label>
          <el-select
            v-model="modePath"
            class="value"
            size="mini"
            value-key="name"
            @change="handleModelPathChange">
            <el-option
              v-for="mode in modeArray"
              :key="mode.name"
              :label="mode.name"
              :value="mode.path"/>
          </el-select>
        </div>
        <!-- 控制是否换行 -->
        <div class="item">
          <label class="title">换行</label>
          <el-select
            v-model="wrap"
            class="value"
            size="mini"
            value-key="name"
            @change="handleWrapChange">
            <el-option
              v-for="wrap in wrapArray"
              :key="wrap.name"
              :label="wrap.name"
              :value="wrap.value"/>
          </el-select>
        </div>
        <!-- 界面主题切换, 经过本人实验, 样式没有什么太重复的 -->
        <div class="item">
          <label class="title">主题</label>
          <el-select
            v-model="theme"
            class="value"
            size="mini"
            value-key="name"
            @change="handleThemeChange">
            <el-option
              v-for="theme in themeArray"
              :key="theme.name"
              :label="theme.name"
              :value="theme.path"/>
          </el-select>
        </div>
      </div>
    </div>
    <!-- 选项蒙版 -->
    <div
      class="bookmarklet"
      @click="toggleConfigPanel"/>
  </div>

</template>

<script>
/* 引入ace语言主题等 */
import ace from 'ace-builds';
import 'ace-builds/src-noconflict/snippets/javascript';
import 'ace-builds/src-noconflict/snippets/html';
import 'ace-builds/src-noconflict/snippets/css';
import 'ace-builds/src-noconflict/snippets/scss';
import 'ace-builds/src-noconflict/snippets/json';
import 'ace-builds/src-noconflict/snippets/java';
import 'ace-builds/src-noconflict/snippets/text';
import 'ace-builds/webpack-resolver';
import 'ace-builds/src-noconflict/ext-language_tools';
import 'ace-builds/src-noconflict/theme-monokai';
import 'ace-builds/src-noconflict/mode-javascript';
/* 测试过没重复的主题 */
const themeArray = [{
  name: 'chaos',
  path: 'ace/theme/chaos',
}, {
  name: 'chrome',
  path: 'ace/theme/chrome',
}, {
  name: 'cobalt',
  path: 'ace/theme/cobalt',
}, {
  name: 'dracula',
  path: 'ace/theme/dracula',
}, {
  name: 'gob',
  path: 'ace/theme/gob',
}, {
  name: 'kuroir',
  path: 'ace/theme/kuroir',
}, {
  name: 'monokai',
  path: 'ace/theme/monokai',
}, {
  name: 'nord_dark',
  path: 'ace/theme/nord_dark',
}, {
  name: 'solarized_dark',
  path: 'ace/theme/solarized_dark',
}];
/* 是否开启换行 */
const wrapArray = [{
  name: '开启',
  value: true,
}, {
  name: '关闭',
  value: false,
}];
/* 目前可选的7种语言 */
const modeArray = [{
  name: 'JavaScript',
  path: 'ace/mode/javascript',
}, {
  name: 'HTML',
  path: 'ace/mode/html',
}, {
  name: 'CSS',
  path: 'ace/mode/css',
}, {
  name: 'SCSS',
  path: 'ace/mode/scss',
}, {
  name: 'Json',
  path: 'ace/mode/json',
}, {
  name: 'Java',
  path: 'ace/mode/java',
}, {
  name: 'Text',
  path: 'ace/mode/text',
}];

export default {
  /* 接受组件中传来的value */
  props: {
    value: {
      type: String,
      default: '',
    },
  },
  data() {
    return {
      aceEditor: null,
      toggle: false,
      wrap: true,
      theme: 'ace/theme/monokai',
      themePath: 'ace/theme/monokai',
      modePath: 'ace/mode/javascript',
      modeArray,
      wrapArray,
      themeArray,
    };
  },
  /* 检测传来的value, 渲染在编辑器上 */
  watch: {
    value(v) {
      console.log('vvvvvvvvvvv', v);
      this.aceEditor.getSession().setValue(v);
    },
  },
  mounted() {
    /* 初始化 编辑器 */
    this.aceEditor = ace.edit(this.$refs.ace, {
      maxLines: 25, // 最大行数,超过会自动出现滚动条
      minLines: 25, // 最小行数,还未到最大行数时,编辑器会自动伸缩大小
      fontSize: 14, // 编辑器内字体大小
      value: this.value ? this.value : '',
      theme: this.themePath, // 默认设置的主题
      mode: this.modePath, // 默认设置的语言模式
      wrap: this.wrap,
      tabSize: 4, // 制表符设置为 4 个空格大小
    });
    // 激活自动提示
    this.aceEditor.setOptions({
      enableSnippets: true,
      enableLiveAutocompletion: true,
      enableBasicAutocompletion: true,
    });
    /* 未知 */
    this.aceEditor.$blockScrolling = Infinity;
    /* 检测编辑器内容发生变化 */
    this.aceEditor.getSession().on('change', this.change);
  },
  methods: {
    /* 选项蒙版展示 / 隐藏 */
    toggleConfigPanel() {
      this.toggle = !this.toggle;
    },
    /*  */
    change() {
      /* nuxt自带的触发时间, 在用到的地方可以接受到value */
      this.$nuxt.$emit('inputChange', this.aceEditor.getSession().getValue());
    },
    /* 语言变化 */
    handleModelPathChange(modelPath) {
      this.aceEditor.getSession().setMode(modelPath);
    },
    /* 换行变化 */
    handleWrapChange(wrap) {
      this.aceEditor.getSession().setUseWrapMode(wrap);
    },
    /* 主题变化 */
    handleThemeChange(theme) {
      this.aceEditor.setTheme(theme);
    },
  },
};
</script>

<style lang='less' scoped>
// 样式, 使用的是less, 可以更改做的更好看
.ace-container {
  position: relative;

  .bookmarklet {
    position: absolute;
    right: 0;
    bottom: 0;
    width: 10px;
    height: 10px;
    z-index: 2;
    cursor: pointer;
    border-width: 9px;
    border-style: solid;
    border-color: lightblue gray gray rgb(206, 173, 230);
    border-image: initial;
  }

  .config-panel {
    position: absolute;
    right: 0;
    bottom: 0;
    width: 50%;
    height: 100%;
    overflow: scroll;
    box-shadow: grey -5px 2px 3px;
    background-color: rgba(255, 255, 255, 0.5);
    z-index: 1;

    .item {
      margin: 10px auto;
      text-align: center;

      .title {
        color: white;
        margin: 0 10px;
        font-size: 14px;
      }
    }
  }
}
</style>
  • 在components文件夹中创建install_ace.js文件
import Ace from './GlobalAve.vue'; // 注意引入路径

export default {
  install(Vue, options) {
    Vue.component('Ace', Ace);
  },
};
  • 在nuxt的plugins文件夹中创建ace-builds.js文件
import Vue from 'vue';
import ace from 'ace-builds';
import AceComponent from 'component/install_ace'; 
// 注意自己的路径,是否配置了绝对路径

Vue.use(ace);
Vue.use(AceComponent);
  • 在nuxt.config.js中引入
plugins: [
    '@/plugins/element-ui', // 引入的其他plugin
    { src: '@/plugins/ace-builds', ssr: false }, // 引入ace,注意ssr要设置为false,表示在服务器是不加载,否则会报错
],

现在,全局ace组件就可以使用的,只要在需要的地方直接添加 <Ace>就可以使用了

  • 在组件中使用
<Ace v-model="aceContent"/>

data() {
    return {
        aceContent: '初始化编辑器中的内容',
        saveData: '',
    }
},
mounted() {
    this.refresh();
    /* 接收编辑器改变的内容 */
    this.$nuxt.$on('inputChange', (data) => {
      // console.log(data);
      this.saveData = data;
    });
},
methods: {
    /* 组件中方法,检测相关事件,如果有变化,给aceContent重新赋值,编辑器中内容会实时发生变化 */
    handleNodeClick(data) {
      if (data.fileContext) {
        this.aceContent = data.fileContext;
      }
    },
}

至此,ace-builds在nuxt中就能够在任何组件中使用了,也是在网上查找了许多内容,加上自己的改动,让他能在nuxt上直接使用 有兴趣的可以去观看他人写的 blog.csdn.net/YoshinoNanj… www.cnblogs.com/chengxu9311…

如有侵权,请私信我删除内容