Vue3 Composition Api check for empty slot - vuejs3

First project with Vue3, trying to determine if a named slot has content supplied on a given page.
In my template I have this:
<div
:class="{ 'py-20': hasTopContent }"
>
<slot name="top-content" />
</div>
In my code I have the following:
setup (_, { slots }) {
const hasTopContent = computed((slots) => {
console.log(slots.topContent);
return slots.topContent && slots.topContent().length;
});
return {
hasTopContent
}
}
The above console.log is returning TypeError: Cannot read properties of undefined (reading 'topContent'). What have I missed? Thanks!

Michal Levý is right
var Main = {
components: {
'my-component': MyComponent,
},
data() {
return {
}
},
methods: {
}
};
const app = Vue.createApp(Main);
app.mount("#app")
<html>
<head>
<style>
.my-component {
background-color: #fafafa;
padding: 5px 20px 20px 20px;
}
</style>
</head>
<body>
<div id="app">
<h3>With top slot</h3>
<my-component class='my-component'>
<template v-slot:top>
<h4>Top Slot</h4>
</template>
</my-component>
<h3>Without top slot</h3>
<my-component class='my-component'>
</my-component>
<hr style='padding: 20px 20px 20px 20px;' />
</div>
<script src="//unpkg.com/vue#next"></script>
<script type="text/x-template" id="my-component">
<div
:class="{ 'py-20': hasTopContent }">
<slot name="top" />
hasTopContent: {{hasTopContent}}
</div>
</script>
<script type="text/javascript">
var MyComponent = {
template: '#my-component',
setup(_, { slots }) {
const hasTopContent = Vue.computed(() => {
return slots.top && slots.top().length > 0;
});
return { hasTopContent }
}
}
</script>
</body>
</html>

Related

How to use <i18n-t> in Web component?

I'm creating a Vue web component using i18n
And I wanna put a span tag with color in
here is my code demo.
I wanna know how to import
<!-- custom-element.ce.vue -->
<script setup>
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const locale = ref('en')
defineProps({
locale: String,
})
</script>
<template>
<div classs="custom-ele-wrap">
<i18n-t keypath="title" tag="span">
<template #text>
<span :class="['locale-text', locale']"> {{ localeText }} </span>
</template>
</i18n-t>
</div>
</template>
<style scoped>
.locale-text.en {
color: blue;
}
.local-text.zh-TW {
color: red;
}
</style>
// <!-- i18n json -->
{
"en": {
"title": "{text} language",
},
"zh-TW": {
"title": "這是{text}語言",
}
}
but it shows
enter image description here

Vue adding dynamic class doesn't change current class

I have wrapper div with padding and I am dynamically adding items inside of it.
I don't want any padding on wrapper div when there is no item in it.
I have created computed method isEmpty to check if there are items or not and used it to add optional class :class={ className: isEmpty } but it doesn't work.
Here is the fiddle link: https://jsfiddle.net/2u9rtdmh/3/
You should wrap an expression for :class into ":
:class="{ className: isEmpty }"
You should read the console errors when trying to diagnose problems, i.e. your jsfiddle doesn't even have an #app element.
The correct syntax for your scenario would be :class="{ 'padding0' : isEmpty }"
Binding HTML Classes
Vue.config.productionTip = false;
Vue.config.devtools = false;
new Vue({
el: "#app",
data: {
},
computed: {
isEmpty() {
return true;
}
}
})
body {
background-color: black;
}
.my-wrapper {
padding: 32px;
background-color: white;
}
.padding0 {
padding: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div :class="{ 'padding0' : isEmpty }" class="my-wrapper">
<div>
<div>
</div>
</div>
</div>
</div>

change element style in method callback

This code is trying to add a class to an element. the class definition is located in meteor_app_root/stylesheets/style.css .wrongInput { color: red; }
This method returns fine but the text inside the input element is not changing to red as I am expecting.
edited
I get browser console print "server returned" but the addClass line is not doing its work.
edited
changing the style from color: Red; to border-color: Red; makes the boarder colour red.
What am I doing wrong? Thanks
Template.footer.events({
'click button': function () {
var doc = {};
$('input').each(function () {
this.value && (doc[this.name]=this.value)
});
Meteor.call('processInputs', doc, function (err, res) {
if (res) {
console.log("res " + res);
$('[name="plate"]').addClass("wrongInput");
}
});
}
});
//server.js
Meteor.methods({
processInputs: function (doc) {
return "server acted";
}
});
<template name="content">
<div class="container">
<div class="row">
<section class="col-xs-12">
<form>
<ul class="list-group">
{{#each this.items}}
<li>
<input class="list-group-item basic-vertical-spacing col-xs-12" type="text"
name={{name}} placeholder={{placeholder}}>
</li>
{{/each}}
</ul>
</form>
</section>
</div>
</div>
</template>
I see what it is, you didn't have the if(err):
Meteor.call('myFunction', function(err, data) {
if (err)
{
$('[name="plate"]').addClass("wrongInput");
}
});

ionic conditional text color

I want to show different color for the name of a person if he is Present or Absent.
working in ion view
<ion-view view-title="{{employee.firstName }}">
<ion-content has-header="true" padding="true">
<div ng-style="{{employee.tStatus}} === 'Present' ? { color:'green' } : { color:'red'}"> {{employee.name }}</div>
</ion-content>
</ion-view>
And its not working in any way
Any recommendation please
HTML
<ion-view view-title="{{employee.firstName }}">
<ion-content has-header="true" padding="true">
<div ng-class="{'green':employee.tStatus == 'Present','color: red':employee.tStatus == 'Absent'}">{{employee.name }}
</div>
</ion-content>
</ion-view>
SO Demo
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.employee = {
tStatus: 'Present',
name: 'Sameed'
}
});
.green {
color: green;
}
.red {
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<div ng-class="{'green':employee.tStatus == 'Present','color: red':employee.tStatus == 'Absent'}">{{employee.name }}
</div>
</div>
You could use a function which gives the right color:
var app = angular.module('app', []);
app.controller('employeeCtrl', function($scope) {
$scope.employee = {
tStatus: 'Absent',
name: 'Foo'
};
$scope.getColorClass = function(employee)
{
switch(employee.tStatus)
{
case 'Present':
return "green";
case 'Absent':
default:
return "red";
}
};
});
it becomes in handy to pass the emploee in to it. if you want to add more classes, you can just modify your function inside your controller.
you can also add multiple classes. separate them with a space while returning.
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<div ng-app="app" ng-controller="employeeCtrl">
<div ng-class="getColorClass(employee)">
{{employee.name}}
</div>
</div>
and in your css define the classes
.red {
color: red;
}
.green {
color: green;
}
var app = angular.module('app', []);
app.controller('employeeCtrl', function($scope) {
$scope.employee = {};
$scope.employee.tStatus = 'Absent';
$scope.employee.name = "Foo";
$scope.getColorClass = function(employee) {
switch (employee.tStatus) {
case 'Present':
return "green";
case 'Absent':
default:
return "red";
}
};
});
.red {
color: red;
}
.green {
color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<div ng-app="app" ng-controller="employeeCtrl">
<div ng-class="getColorClass(employee)">
{{employee.name}}
</div>
</div>

Polymer 1.x: How to reverse order of records returned by <firebase-collection>

How do I reverse the order of records returned by <firebase-collection> as follows:
<firebase-collection id="foo" order-by-child="bar">
?
Can I do it declaratively? Or do I need to call an imperative method like maybe...
this.$.foo = this.$.foo.reverse();
https://elements.polymer-project.org/elements/firebase-element?active=firebase-collection
Note: I'm using <iron-list> and not <template is="dom-repeat">.
Simplest is just to use a <dom-repeat> with an inverse sort I believe.
sort. Specifies a comparison function following the standard Array sort API.
Per https://www.polymer-project.org/1.0/docs/devguide/templates.html#filtering-and-sorting-lists
The best solution is to use <iron-list> then sort that according to this answer.
http://jsbin.com/vizexodoyi/1/edit?html,output
<html>
<head>
<title>My Element</title>
<script data-require="polymer#*" data-semver="1.0.0" src="http://www.polymer-project.org/1.0/samples/components/webcomponentsjs/webcomponents-lite.js"></script>
<script data-require="polymer#*" data-semver="1.0.0" src="http://www.polymer-project.org/1.0/samples/components/polymer/polymer.html"></script>
<base href="http://element-party.xyz/" />
<link rel="import" href="all-elements.html" />
</head>
<body>
<dom-module id="my-element">
<template>
<style>
h3 {
margin-bottom: 0px;
}
iron-list {
padding-bottom: 16px;
height: 100%;
}
.item {
#apply(--layout-horizontal);
margin: 16px 16px 0 16px;
padding: 20px;
border-radius: 8px;
background-color: white;
border: 1px solid #ddd;
}
</style>
<firebase-collection location="https://dinosaur-facts.firebaseio.com/dinosaurs" data="{{items}}">
</firebase-collection>
<h3>Controls</h3>
<paper-dropdown-menu label="Sort by">
<paper-menu class="dropdown-content" selected="{{sortVal}}" attr-for-selected="data-sortby">
<paper-item data-sortby="order">Order</paper-item>
<paper-item data-sortby="height">Height</paper-item>
</paper-menu>
</paper-dropdown-menu>
<br>
<paper-toggle-button checked="{{reverse}}">Reverse</paper-toggle-button>
<br /><br />
<br><h3>Monitor Control Values</h3>
<div>Sort by: [[sortVal]]</div>
<div>Reverse: [[reverse]]</div>
<br><h3>Iron-List Output</h3>
<iron-list id="list" items="[[items]]" as="item">
<template>
<div class="item">
Name: [[item.__firebaseKey__]]<br />
Order: [[item.order]]<br />
Height: [[item.height]]
</div>
</template>
</iron-list>
</template>
<script>
(function() {
Polymer({
is: "my-element",
properties: {
items: {
type: Array,
},
sortVal: {
type: String,
value: 'order'
},
sortOrder: {
type: Number,
value: -1, // High to low
computed: '_computeSortOrder(reverse)'
}
},
observers: [
'sortChanged(sortVal, sortOrder)'
],
_computeSortOrder: function(bool) {
return bool ? 1 : -1;
},
sortChanged(val, ord) {
if (! this.items || this.items.length == 0) {
return;
}
var temp = Array.prototype.slice.call(this.items);
temp.sort(this._computeSort(val, ord));
this.items = temp;
//console.log('ord: ' + ord);
//console.log('val: ' + val);
//console.log('items: ' + this.items);
},
_computeSort: function(val, ord) {
return function(a, b) {
if (a[val] === b[val]) {
return 0;
}
return (ord * (a[val] > b[val] ? 1 : -1));
};
}
});
})();
</script>
</dom-module>
<my-element></my-element>
</body>
</html>

Resources