How to implement ag-grid into nuxt.js - vue.js

How to integrate ag-grid to work with nuxt.js via the nuxt.config file?
The error I'm getting:
commons.app.js:16278 Uncaught TypeError: Cannot read property '_init' of null
at AgGridVue (commons.app.js:16278)
at Function.Vue.use (commons.app.js:16233)
at Module../plugins/ag-grid.client.js (app.js:5186)
at webpack_require (runtime.js:791)
at fn (runtime.js:151)
at Module../.nuxt/index.js (app.js:1997)
at webpack_require (runtime.js:791)
at fn (runtime.js:151)
at Module. (app.js:236)
at Module../.nuxt/client.js (app.js:1308)
ag-grid.client.js:
import Vue from "vue";
import { AgGridVue } from "ag-grid-vue";
Vue.use(AgGridVue);
nuxt.config.js:
plugins: [
"#/plugins/element-ui",
"#/plugins/tooltip",
"#/plugins/calendar",
"#/plugins/ag-grid.client.js"
],
The file to load table into:
<template>
<div class="flex h-full">
<no-ssr>
<ag-grid-vue style="width: 500px; height: 500px;"
class="ag-theme-balham"
:columnDefs="columnDefs"
:rowData="rowData">
</ag-grid-vue>
</no-ssr>
</div>
</template>
<script>
export default {
components: {},
data() {
return {
columnDefs: null,
rowData: null
};
},
beforeMount() {
this.columnDefs = [
{ headerName: "Make", field: "make" },
{ headerName: "Model", field: "model" },
{ headerName: "Price", field: "price" }
];
this.rowData = [
{ make: "Toyota", model: "Celica", price: 35000 },
{ make: "Ford", model: "Mondeo", price: 32000 },
{ make: "Porsche", model: "Boxter", price: 72000 }
];
}
};
</script>

In the file "ag-grid.client.js", you can't add a component with Vue.use, you need to use Vue.component and it'll register it globally:
import Vue from 'vue'
import { AgGridVue } from 'ag-grid-vue'
Vue.component('ag-grid-vue', AgGridVue)
And then you don't need to set the tag "".

Related

How to dynamically insert text in Ckeditor5 for Vue 2

My application provides many selectable standard paragraphs which users can insert at any point. In a previous version insertion was simple: CKEDITOR.instances[editorId].insertHTML(text).
I'm trying to use v5 api with model.insertContent(text) but get error:
"vue.runtime.esm.js:3020 TypeError: t2.is is not a function
at bl.rp (converters.js:771:21)
at bl.fire (emittermixin.js:199:30)
at <computed> (observablemixin.js:262:16)
at VueComponent.testInsert (Test.vue:29:1)"
Here's the composition file. I have tried accessing the insertContent method from this.editor and from the apiReference returned from the #ready event;
<template>
<div>
<button #click="testInsert('abracadabra')">Insert literal content</button>
<ckeditor tag-name="textarea" :editor="editor" v-model="doc.HTML" #ready="editorReady" :config="editorConfig"></ckeditor>
</div>
</template>
<script>
import ClassicEditor from '#ckeditor/ckeditor5-build-classic';
export default {
name: 'testEditorInsert',
mounted() {
},
data() {
return {
doc: {ID: 0, HTML: "This is a sample text. Insert here? This is the remainder of the sample text"},
editor: ClassicEditor,
editorData: 'loading',
editorConfig: {
toolbar: [ 'bold', 'italic', 'link', 'bulletedList', 'numberedList', 'blockQuote' ],
},
editorApi:null ,
}
},
methods: {
testInsert: function(text) {
console.log(this.editorApi, text);
//this.editor.model.insertContent(text);
this.editorApi.model.insertContent(text);
},
editorReady: function(editor) {
this.editorApi = editor;
}
},
}
</script>

ECharts failed in rendering the candlesticks in quasar app

I use echarts for vue library from here and getting both sample setup and data from here.
So my codes are like these:
app.js
import { Quasar } from 'quasar'
import { markRaw } from 'vue'
import RootComponent from 'app/src/App.vue'
import createStore from 'app/src/stores/index'
import createRouter from 'app/src/router/index'
import ECharts from 'vue-echarts'
import { use } from "echarts/core"
import { CanvasRenderer } from 'echarts/renderers'
import { CandlestickChart } from 'echarts/charts'
import {
GridComponent,
TooltipComponent,
TitleComponent,
LegendComponent,
DataZoomComponent,
} from 'echarts/components'
use([
CanvasRenderer,
CandlestickChart,
GridComponent,
TooltipComponent,
TitleComponent,
LegendComponent,
DataZoomComponent,
])
... more ..
MyChart.vue
<template>
<q-item>
<div style="width: 100%; margin: 0;" class="bg-white">
<table style="width: 100%; height: 360px">
<tr>
<td style="width: 45%">Info</td>
<td style="width: 55%">
<chart class="candle-chart" :option="option"></chart>
</td>
</tr>
</table>
</div>
</q-item>
</template>
<script>
/* eslint-disable */
import { defineComponent, ref } from "vue";
export default defineComponent({
name: "MyChart",
props: {
id: Number,
event: Object,
prices: Array
},
setup(props) {
const priceData = splitData(props.prices);
const optionObj = ref({
title: {
text: props.event.pair,
left: 0
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross'
}
},
legend: {
data: ['日K']
},
grid: {
left: '10%',
right: '5%',
bottom: '15%'
},
xAxis: {
type: 'category',
data: priceData.categoryData,
boundaryGap: false,
axisLine: { onZero: false },
splitLine: { show: false },
min: 'dataMin',
max: 'dataMax'
},
yAxis: {
scale: true,
splitArea: {
show: true
}
},
series: [
{
name: '日K',
type: 'candlestick',
data: priceData.values,
itemStyle: {
color: '#FD1050',
color0: '#0CF49B',
borderColor: '#FD1050',
borderColor0: '#0CF49B'
},
}
]
});
function splitData(rawData) {
const categoryData = [];
const values = [];
for (var i = 0; i < rawData.length; i++) {
categoryData.push(rawData[i].splice(0, 1)[0]);
values.push(rawData[i]);
}
return {
categoryData: categoryData,
values: values
};
}
return {
option: optionObj
}
}
});
</script>
<style scoped>
.candle-chart {
width: 100%;
border: 1px;
border-style: solid;
border-radius: 4px;
border-color: #b0a9a9;
}
</style>
I load data from json file, but to be simple.. the structure of the data is like below:
"prices": [
[ "2013/1/24", 2320.26, 2320.26, 2287.3, 2362.94 ],
[ "2013/1/25", 2300, 2291.3, 2288.26, 2308.38 ],
... more data ... ]
There is no error after running it, I can see the chart area and all the lines, the legends, the grid, the tooltip and so on... but not a single candle rendered (see below screemshot)
Can anybody from ECharts or Vue-echarts or anybody who ever work on this tell me what is wrong with my code?

bootstrap-vue modal not displaying

environment
dotnet core 2.1.0
"bootstrap-vue": "^2.0.0-rc.11",
"nuxt": "^1.4.1",
"vue": "^2.5.16",
"vue-axios": "^2.1.1",
"vue-router": "^3.0.1",
"vue-server-renderer": "^2.1.8",
"vue-template-compiler": "^2.5.16",
"vue-toasted": "^1.1.24",
"vuex": "^3.0.1",
"vuex-router-sync": "^4.0.1"
I can't figure out how to get a simple bootstrap-vue modal working. The modal-sample component renders, with the button visible, but when the button is clicked nothing happens (modal doesn't "show").
However, in the vue dev tools, I can see the show event was emitted. Also, if I copy and paste the code in the bootstrap-vue playground it works, so it has to be my set up. Not sure if it matters but it's also running in a dotnet core environment.
webpack.config
const VueLoaderPlugin = require('vue-loader/lib/plugin');
...
resolve: {
extensions: ['.js', '.vue'],
alias: {
'vue$': 'vue/dist/vue',
...
}
...
,
module: {
rules: [
{ test: /\.vue$/, include: /ClientApp/, use: 'vue-loader' },
{ test: /\.js$/,
include: [/ClientApp/,
require.resolve("bootstrap-vue")],
use: 'babel-loader' },
{ test: /\.css$/,
use: isDevBuild ? ['vue-style-loader', 'style-loader', 'css-loader'] : ExtractTextPlugin.extract({ use: 'css-loader' }) },
{ test: /\.(png|jpg|jpeg|gif|svg)$/,
use: 'url-loader?limit=25000' }
]
},
plugins: [
new VueLoaderPlugin(),
new webpack.DllReferencePlugin({
context: __dirname,
manifest: require('./wwwroot/dist/vendor-manifest.json')
})
].concat(isDevBuild ? [
// Plugins that apply in development builds only
new webpack.SourceMapDevToolPlugin({
filename: '[file].map', // Remove this line if you prefer inline source maps
moduleFilenameTemplate: path.relative(bundleOutputDir, '[resourcePath]') // Point sourcemap entries to the original file locations on disk
})
] : [
// Plugins that apply in production builds only
new webpack.optimize.UglifyJsPlugin(),
new ExtractTextPlugin({use: 'site.css', fallback: 'vue-style-loader'})
])
}];
app-root.vue
import Swapshift from './modal-sample'
Vue.component('modal-sample', Swapshift);
modal-sample.vue
<template>
<div style="margin-top: 20px; padding: 10px;">
<b-button variant="primary" v-b-modal.newSwapShiftModal>New Swap Shift</b-button>
<b-modal id="newSwapShiftModal" title="New Swap Edit" >
<div class="d-block text-center">
<h3>Hello From My Modal!</h3>
</div>
</b-modal>
</div>
</template>
<script>
import { mapActions, mapState } from 'vuex'
import bModal from 'bootstrap-vue/es/components/modal/modal'
import bModalDirective from 'bootstrap-vue/es/directives/modal/modal'
export default {
components: { bModal },
directives: { bModalDirective },
data() {
return {
swapshift: {
id: 1,
status: {
id: 1,
description: 'Requested'
}
}
}
},
computed: {
},
methods: {
},
async created() {
console.log('...in modal-sample1');
}
}
</script>
HTML attributes all get translated to lowercase. This includes parts of the directive attribute on your button. So what is happening is that when the v-b-modal directive receives the modifiers (ie. .newSwapShiftModal), it receives newswapshiftsodal from the browser (all attributes are always lowercased by the browser).
So you need to set the id on the modal to also be lowercase (as attribute values inside quotes retain their case).
<template>
<div style="margin-top: 20px; padding: 10px;">
<b-button variant="primary" v-b-modal.new-swap-shift-modal>New Swap Shift</b-button>
<b-modal id="new-swap-shift-modal" title="New Swap Edit" >
<div class="d-block text-center">
<h3>Hello From My Modal!</h3>
</div>
</b-modal>
</div>
</template>
Example fiddle showing case sensitivity issues with IDs: https://jsfiddle.net/4cnk28yw/
EDIT: also register the directive with the correct name (as mentioned by #ittus):
import { mapActions, mapState } from 'vuex'
import { BModal, VBModal } from 'bootstrap-vue'
export default {
components: { BModal },
directives: { 'b-modal': VBModal },
// ...
}
Directive name should be b-modal. You should try changing:
directives: {
'b-modal': bModalDirective
}

Vue 2.5: Passing prop to component. Prop gets bundled in variable name

I'm new to Vue.js and my first try is to make a simple line-chart using ChartJS (vue-chartjs bundle).
I've used the "HelloWorld.vue" as base material, and created a LineChart.js
The problem is that in HelloWorld, i got my variable called datacollection, this name gets passed into my LineChart.js. How do I fix so I dont get the variable name as an object
I get:
datacollection:
{
labels: {...},
datasets: {...}
}
I want:
{
labels: {...},
datasets: {...}
}
Thus, in my LineChart.js I need to do .datacollection. This will make my LineChart.js less reusable, since I always have to remember to name all my variables calling LineChart 'datacollection'.
LineChart.js:
import { Line } from 'vue-chartjs'
export default {
extends: Line,
props: ['data', 'options'],
watch: {
'data': function (value) {
// I get the update from backend, but I have to use .datacollection (the variable name from the calling page)
console.log('Ändrat: ', value)
this.renderChart(value.datacollection, this.options)
}
},
data () {
return {
gradient: null,
gradient2: null
}
},
mounted () {
console.log('data in component', this.data)
/*
this.data contains datacollection: {
labels: {
...
},
datasets: {
....
}
}
This wont render any graph since I dont do .datacollection
*/
this.renderChart(this.data, this.options)
}
}
My Graph.vue page:
<template>
<div class='hello'>
<h1>{{ msg }}</h1>
<h2>Graph</h2>
<!-- this.datacollection is printed as expected, {labels: {}, datasets: {}} -->
<p>{{ this.datacollection }}</p>
<section>
<line-chart
:data='{datacollection}'
:options='{chartOptions}'
:width="400"
:height="200"
>
</line-chart>
</section>
<section>
<reactive-example></reactive-example>
</section>
</div>
</template>
<script>
export default {
name: 'Graph',
mounted: function () {
this.axios.get('graph/').then(response => {
console.log(response.data)
this.datacollection = response.data
})
},
data: function () {
return {
msg: 'Welcome to Your Vue.js App',
datacollection: {
labels: ['January', 'February'],
datasets: [
{
label: 'First',
backgroundColor: '#f87979',
data: [40, 20]
},
{
label: 'Second',
backgroundColor: '#aa7979',
data: [20, 30]
}
]
}
}
}
}
</script>
<!-- Add 'scoped' attribute to limit CSS to this component only -->
<style scoped>
h1, h2 {
font-weight: normal;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
My dependenicies (versions)
"dependencies": {
"axios": "^0.17.1",
"chart.js": "^2.7.1",
"vue": "^2.5.2",
"vue-axios": "^2.0.2",
"vue-chartjs": "^3.0.2",
"vue-router": "^3.0.1"
}
What do I miss?
In your template, you have the following:
<line-chart
:data='{datacollection}'
:options='{chartOptions}'
:width="400"
:height="200"
>
</line-chart>
In ES2015, {datacollection} is shorthand (see New notations in ECMAScript 2015) for creating a new object with a datacollection property with the value of datacollection as its value. In Vue, everything in the quotes of a binding is treated as a javascript expression, so in most modern browsers what that syntax does is create a new object with a datacollection property and pass that object to the component.
Instead, just remove the braces.
<line-chart
:data='datacollection'
:options='chartOptions'
:width="400"
:height="200"
>
</line-chart>

create a component inside a component, getting error: "Failed to mount component: template or render function not defined."

trying to make a component (tag: simple-div-container) that on a button press will create 2 (tag: simple-div) components, inside each new simple-div there will be a simple-div-container.
so I can create "endless" components inside each other.
I have simple-div-container and when I press the button I get 2 simple-div
but I don't get inside them the NEW simple-div-container.
I get an error:
Failed to mount component: template or render function not defined.
code for tag: simple-div-container
<template>
<div>
<button #click="insert2Div" class="div-controler">insert 2 div</button>
<div v-if="divs" class="horizontal-align">
<simplediv v-if="divs" :style="{height: simpleDivHeight + 'px',width: simpleDivWidthPrecent/2 + '%', border: 1 + 'px solid' }"
:height="simpleDivHeight" :widthPrecent="simpleDivWidthPrecent" :isRender="true"></simplediv>
<simplediv v-if="divs" :style="{height: simpleDivHeight + 'px',width: simpleDivWidthPrecent/2 + '%', border: 1 + 'px solid' }"
:height="simpleDivHeight" :widthPrecent="simpleDivWidthPrecent" :isRender="true"></simplediv>
</div>
</div>
</template>
<script>
import SimpleDiv from '../simple-div/simpleDiv.vue';
export default {
props: {
simpleDivHeight: {
require: true,
type: Number
},
simpleDivWidthPrecent: {
require: true,
type: Number
}
},
data() {
return {
divs: false,
}
},
methods: {
insert2Div() {
console.log('insert 2 div')
this.divs = true;
},
},
components: {
simplediv: SimpleDiv
},
}
</script>
<style scoped>
.horizontal-align {
display: flex;
flex-direction: row;
}
</style>
code for tag: simple-div
<template>
<div>
<simple-div-container v-if="isRender" :simpleDivHeight="height" :simpleDivWidthPrecent="widthPrecent/2"></simple-div-container>
</div>
</template>
<script>
import simpleDivContainer from '../simple-div-container/simpleDivContainer.vue';
export default {
props: {
height: {
require: true,
type: Number
},
widthPrecent: {
require: true,
type: Number
},
isRender:{
require: true,
type: Boolean
}
},
data() {
return {
isDivContainer: false
}
},
components: {
'simple-div-container': simpleDivContainer
}
}
</script>
<style scoped>
.div-controler {
position: fixed;
transform: translate(-10%, -320%);
}
</style>
an interesting point: if i add to simple-div data some property(while webpack listens to changes) than it will automatically rerender and the new simpe-div-container will show
You have a circular reference problem. You should check if registering the simple-div component in the beforeCreate lifecycle hook helps. In the simple-div-container:
In the simple-div-container:
beforeCreate () {
this.$options.components.simple-div = require('../simple-div/simpleDiv.vue')
}