Vue 之 Vue Cli 创建 Three js 工程( 网页 3D )的简单整理(一些注意事项)
Vue 开发的一些知识整理,方便后期遇到类似的问题,能够及时查阅使用。本节介绍,Vue 前端开发中使用 Vue cli + three 结合开发网页 3D 场景,如果有不足之处,欢迎指出,或者你有更好的方法,欢迎留言。操作环境:win 10node 16.14.2 版本npm 8.5.0 版本@vue/cli 5.0.4three 0.139.1
Vue 之 Vue Cli 创建 Three js 工程( 网页 3D )的简单整理(一些注意事项)
目录
Vue 之 Vue Cli 创建 Three js 工程( 网页 3D )的简单整理(一些注意事项)
在 Vue 工程 中安装 three 相关,并实现简单 3D 场景预览
1、npm(cnpm) 安装中 -S 、 -D 参数的简单说明
2、Vue Cli 项目目录结构的简单说明(版本不同可能会略有差别):
3、 vue-cli项目中页面相关的主要文件简单说明(版本设置会有所区别)
一、简单介绍
Vue 开发的一些知识整理,方便后期遇到类似的问题,能够及时查阅使用。
本节介绍,Vue 前端开发中使用 Vue cli + three 结合开发网页 3D 场景,如果有不足之处,欢迎指出,或者你有更好的方法,欢迎留言。
操作环境:
- win 10
- node 16.14.2 版本
- npm 8.5.0 版本
- @vue/cli 5.0.4
- three 0.139.1
二、实现原理
1、vue create 项目名称,使用 vue 创建项目
2、vue install three-相关包
3、打开项目,根据需要在 App.vue 对应添加 three 相关代码
4、npm run serve 运行工程,部署成功,输入网址,浏览器浏览即可
三、注意事项
1、这里的操作前提是npm(nodejs) 和 vue 基本环境已经搭建完成
( ---没有搭建基本环境,可参见博文:
2、可能需要注意一些插件的安装顺序,特别是需要依赖 three 的其他包,需要安装 three 后,才好
3、在vue环境中渲染页面时明显比直接引入three.js方式卡,所以注意(可见后面代码)
scene 和camera 等不要放在data里面,要在 mounted 时初始化,beforeMount 时定时器清空
4、一般 vue cli 工程推到 Git 上的不会把 node_module 等的相关代码上传,所以初次从网上下载或者克隆的 vue 工程,可能需要切换目标目录,在cmd(window)中输入 npm install 加载 packgae.json 中的依赖包, npm run serve 才可能正常运行工程
5、安装 three 成功后,在项目中 import three from 'three';
,之后运行程序。
发现控制台报错 default export is not declared in imported module
说明 three.js没有默认的导出对象
- 应该写成
import * as THREE from 'three';
- 或者可以这样:
import { Scene, WebGLRenderer, PerspectiveCamera, BoxGeometry, MeshBasicMaterial, Mesh} from 'three';
- 或者使用CommonJS的形式引入
var three = require ('three'); (作说明使用,暂未尝试该法)
四、实现步骤
Vue Cli 创建 Vue 工程
1、新建需要创建 Vue Cli 工程文件夹(方便工程管理而已)
2、打开 cmd 切换到之前建立好的文件夹,然后使用 vue create 项目名称,创建工程,可以默认创建工程,也可手动创建,这里测试选择默认创建 vue 3 工程
命令:
- e: 切换盘
- cd xx\xx 切换到目标文件夹
- vue create xx_xx-xx 创建 vue 工程
3、之后系统就会自动进行工程文件和包的下载,一般等待即可
4、工程创建好后,即可根据名提示,切换到创建的工程文件夹,运行服务(一般目的是检测工程创建是否OK)
命令:
- cd xx_xxx-xx 切换到创建的工程文件夹
- npm run serve 运行服务
5、输入对应网址,没问题,即可看到下图效果
在 Vue 工程 中安装 three 相关,并实现简单 3D 场景预览
1、 在 cmd 中,使用命令安装 three
命令:cnpm install three -S ( -S 的目的是把 three 依赖添加到 packgae.json 文件夹中)
2、安装轨道控制插件 three-orbit-controls (不需要好似也可以不安装,待确认)
( 注意:该插件引入之前确认three.js 库已经引入, OrbitControls = require('three-orbit-controls')(THREE)
,使用方法: controls = new OrbitControls(camera);)
命令:cnpm install -S three-orbit-controls
3、安装 obj 下载包
(注意:该插件引入之前必须确认three.js库已经引入,该插件包括加载.obj和.mtl 文件的加载器
import {MTLLoader,OBJLoader} from 'three-obj-mtl-loader';
使用方法:mtlLoader = new MTLLoader(); objLoader = new OBJLoader();
特别要注意,单独使用three-mtl-loader
和 three-obj-loader
两个插件时,可能会发生错误。)
命令:npm i -S three-bj-mtl-loader
4、安装 CSS2DRenderer 包
(注意:插件引入之前必须确认htree.js库已经引入import {CSS2DRenderer,CSS2DObject} from 'three-css2drenderer';
使用方法: labelRenderer = new CSS2DRenderer(); label = new CSS2DObject( text );
)
命令:npm install -S three-css2drenderer
5、安装好 three 相关包后,可以在工程文件夹 package.json 文件中,查看 three 依赖已经添加进来了
6、打开工程,这里是使用 WebStorm 打开的工程,然后再 App 中添加测试的 THREE 相关代码
7、这里测试的相关代码,主要功能是在场景中显示一个Box ,然后鼠标可以操作观察 Box
8、回到 cmd ,运行服务器 (如果之前的没有关闭,可以直接进行浏览器预览)
命令:npm run serve
9、浏览器预览效果如下
五、相关代码
1、App.vue 的相关修改和添加的代码
<template>
<div id="container"></div>
</template>
<script>
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import Stats from 'three/examples/jsm/libs/stats.module.js';
export default {
name: 'ThreeTest',
components: {
},
data(){
return{}
},
mounted() {
// three 一些参数定义(这样可以必要的避免卡顿)
this.scene;
this.camera;
this.renderer;
this.stats;
this.box;
this.init();
},
methods:{
init() {
// scene
this.initScene();
// camera
this.initCamera();
// light
this.initLight();
// renderer
this.initRenderer();
// OrbitControls
this.initOrbitControls();
// onWindowResize
this.onWindowResize();
this.axiesHelper();
this.iniStats();
this.addBox();
this.animate();
},
initScene() {
this.scene = new THREE.Scene();
},
initCamera() {
this.camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 200);
this.camera.position.set(-15, 7, 15);
this.camera.lookAt(this.scene.position);
},
onWindowResize() {
this.camera.aspect = window.innerWidth / window.innerHeight;
this.camera.updateProjectionMatrix();
this.renderer.setSize(window.innerWidth, window.innerHeight);
window.addEventListener('resize', this.onWindowResize);
},
initLight() {
const ambientLight = new THREE.AmbientLight(0xcccccc, 0.4);
this.scene.add(ambientLight);
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.6);
directionalLight.position.set(-1, 1, 1);
this.scene.add(directionalLight);
},
initRenderer() {
this.renderer = new THREE.WebGLRenderer({antialias: true});
this.renderer.setSize(window.innerWidth, window.innerHeight);
this.renderer.setPixelRatio(window.devicePixelRatio);
this.renderer.setClearColor(0xcccccc);
document.body.appendChild(this.renderer.domElement);
},
initOrbitControls() {
const controls = new OrbitControls(this.camera, this.renderer.domElement);
controls.minDistance = 5;
controls.maxDistance = 50;
},
iniStats() {
this.stats = new Stats();
document.body.appendChild(this.stats.dom);
},
addBox() {
var boxGeo = new THREE.BoxGeometry(10,10,)
this.box = new THREE.Mesh(boxGeo,new THREE.MeshPhongMaterial())
this.scene.add(this.box);
},
moveBox(){
this.box.position.set(10,0,10);
},
animate() {
requestAnimationFrame(this.animate);
this.stats.update();
this.render();
},
axiesHelper() {
var helper = new THREE.AxesHelper(20);
this.scene.add(helper);
},
render() {
this.renderer.render(this.scene, this.camera);
}
},
// beforeDestroy 废弃,使用 beforeUnmount
beforeUnmount() {
// 相关参数置空
this.scene = null;
this.camera = null;
this.renderer = null;
this.stats = null;
this.box = null;
}
}
</script>
<style>
#app {
text-align: center;
height: 100%;
}
</style>
六、其他说明
1、npm(cnpm) 安装中 -S 、 -D 参数的简单说明
2、Vue Cli 项目目录结构的简单说明(版本不同可能会略有差别):
1)项目目录结构的简单说明
2)build文件夹下相关文件及目录简单说明:
3)config文件夹下目录和文件:
3、 vue-cli项目中页面相关的主要文件简单说明(版本设置会有所区别)
1)index.html:
说明:一般只定义一个空的根节点,在main.js里面定义的实例将挂载在#app节点下,内容通过vue组件填充。
2)App.vue文件:
说明:app.vue是项目的主组件,所有页面都是在app.vue下切换的。一个标准的vue文件,分为三部分。
第一装写html代码在<template></template>中,一般在此下面只能定义一个根节点;
第二<script></script>标签;
第三<style scoped></style>用来写样式,其中scoped表示。该style作用于只在当前组件的节点及其子节点,但是不包含子组件呦。
<router-view></router-view>是子路由视图,后面的路由页面都显示在此处,相当于一个指示标,指引显示哪个页面。
3)main.js:
说明:入口文件来着,主要作用是初始化vue实例并使用需要的插件。比如下面引用了4个插件,但只用了app(components里面是引用的插件)。
4)router下面的index.js文件:路由配置文件。
说明:定义了三个路由,分别是路径为/,路径为/msg,路径为/detail。后续会详细说明,因为我也是才学好多东西不懂,囧。
5)package.json 文件
{
"name": "{{ name }}",// 项目名称
"version": "1.0.0",// 版本
"description": "{{ description }}",// 描述
"author": "{{ author }}",// 作者
"private": true,//是否私人项目
"scripts": {
"dev": "node build/dev-server.js",// npm run dev 的 dev,使用node执行 build/dev-server.js
"start": "node build/dev-server.js",// npm run start 跑的是同样的命令
"build": "node build/build.js"{{#unit}},// npm run build 跑的是 node build/build.js
// 以下脚本为单元测试用到的脚本
"unit": "cross-env BABEL_ENV=test karma start test/unit/karma.conf.js --single-run"{{/unit}}{{#e2e}},
"e2e": "node test/e2e/runner.js"{{/e2e}}{{#if_or unit e2e}},
"test": "{{#unit}}npm run unit{{/unit}}{{#unit}}{{#e2e}} && {{/e2e}}{{/unit}}{{#e2e}}npm run e2e{{/e2e}}"{{/if_or}}{{#lint}},
"lint": "eslint --ext .js,.vue src{{#unit}} test/unit/specs{{/unit}}{{#e2e}} test/e2e/specs{{/e2e}}"{{/lint}}
},
// dependencies 设定的是项目里使用的依赖,
//dependencies 项目的依赖,类似于后端的pom.xml,在此处的依赖,选择 "build": "vue-cli-service build --mode prod", 时会打包进去,一般添加插件,选择装入此处即可
"dependencies": {
"vue": "^2.2.6"{{#router}},// 项目依赖vue.js
"vue-router": "^2.3.1"{{/router}}// 项目依赖vue-router
},
// devDependencies设定的是开发使用的依赖
//devDependencies项目的依赖,在build 时。不会被打包,类似于pom.xml 中的scope作用域
"devDependencies": {
"autoprefixer": "^6.7.2",// 是用于给css3属性自动加属性前缀的
// babel相关的都是用于处理es6语法的
"babel-core": "^6.22.1",
{{#lint}}
"babel-eslint": "^7.1.1",
{{/lint}}
"babel-loader": "^6.2.10",
"babel-plugin-transform-runtime": "^6.22.0",
"babel-preset-env": "^1.3.2",
"babel-preset-stage-2": "^6.22.0",
"babel-register": "^6.22.0",
//
"chalk": "^1.1.3",// chalk适用于格式化输出命令行信息的,比如run dev以后的start...
"connect-history-api-fallback": "^1.3.0",//
"copy-webpack-plugin": "^4.0.1",//
"css-loader": "^0.28.0",// 所有的*-loader都是 webpack的扩展,webpack是把各种资源理解为一个模块,css-loader就是读取css模块的加载器
{{#lint}}
// eslint 是代码格式化检查工具,开启以后要严格遵照它规定的格式进行开发
"eslint": "^3.19.0",
"eslint-friendly-formatter": "^2.0.7",
"eslint-loader": "^1.7.1",
"eslint-plugin-html": "^2.0.0",
{{#if_eq lintConfig "standard"}}
"eslint-config-standard": "^6.2.1",
"eslint-plugin-promise": "^3.4.0",
"eslint-plugin-standard": "^2.0.1",
{{/if_eq}}
{{#if_eq lintConfig "airbnb"}}
"eslint-config-airbnb-base": "^11.1.3",
"eslint-import-resolver-webpack": "^0.8.1",
"eslint-plugin-import": "^2.2.0",
{{/if_eq}}
{{/lint}}
"eventsource-polyfill": "^0.9.6",
"express": "^4.14.1",// express 用于启动 node http server的服务
"extract-text-webpack-plugin": "^2.0.0",
"file-loader": "^0.11.1",
"friendly-errors-webpack-plugin": "^1.1.3",
"html-webpack-plugin": "^2.28.0",// webpack 里载入和处理html的插件
"http-proxy-middleware": "^0.17.3",// node server 的中间件工具
"webpack-bundle-analyzer": "^2.2.1",
{{#unit}}
"cross-env": "^4.0.0",// 设定环境变量的工具,NODE_ENV变量跟它有关
// karma相关的都是单元测试工具
"karma": "^1.4.1",
"karma-coverage": "^1.1.1",
"karma-mocha": "^1.3.0",
"karma-phantomjs-launcher": "^1.0.2",
"karma-phantomjs-shim": "^1.4.0",
"karma-sinon-chai": "^1.3.1",
"karma-sourcemap-loader": "^0.3.7",
"karma-spec-reporter": "0.0.30",
"karma-webpack": "^2.0.2",
"lolex": "^1.5.2",
"mocha": "^3.2.0",
"chai": "^3.5.0",
"sinon": "^2.1.0",
"sinon-chai": "^2.8.0",
"inject-loader": "^3.0.0",
"babel-plugin-istanbul": "^4.1.1",
"phantomjs-prebuilt": "^2.1.14",
{{/unit}}
{{#e2e}}
"chromedriver": "^2.27.2",
"cross-spawn": "^5.0.1",
"nightwatch": "^0.9.12",
"selenium-server": "^3.0.1",
{{/e2e}}
"semver": "^5.3.0",// 一个版本检查工具
"shelljs": "^0.7.6",// selljs是在node里跑shell命令的工具,比如‘rm -rf’
"opn": "^4.0.2",// 跨平台的开启文件或者网页的工具
"optimize-css-assets-webpack-plugin": "^1.3.0",
"ora": "^1.2.0",// 命令行里自动运行的信息提示
"rimraf": "^2.6.0",// 跑shell命令 rm-rf 的工具
"url-loader": "^0.5.8", // 配合webpack的加载器
"vue-loader": "^11.3.4", // 配合webpack的加载器
"vue-style-loader": "^2.0.5", // 配合webpack的加载器
"vue-template-compiler": "^2.2.6", // vue-template-compiler,可能是配合离线版vue
// webpack相关的用于,把图片,*.vue, *.js, 这些组合成最终的项目,webpack-dev用于跑测试服务器
"webpack": "^2.3.3",
"webpack-dev-middleware": "^1.10.0",
"webpack-hot-middleware": "^2.18.0",
"webpack-merge": "^4.1.0"
},
// 项目依赖的引擎版本
"engines": {
"node": ">= 4.0.0",
"npm": ">= 3.0.0"
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
]
}
更多推荐
所有评论(0)